{"id":13794917,"url":"https://github.com/fedorovvvv/svelte-floating-ui","last_synced_at":"2025-05-15T16:02:37.050Z","repository":{"id":41545502,"uuid":"510141741","full_name":"fedorovvvv/svelte-floating-ui","owner":"fedorovvvv","description":"Svelte✨ Floating UI 🎈","archived":false,"fork":false,"pushed_at":"2025-03-28T02:03:01.000Z","size":315,"stargazers_count":160,"open_issues_count":0,"forks_count":9,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-11T21:12:24.871Z","etag":null,"topics":["floating","floating-ui","svelte","sveltejs","ui"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fedorovvvv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-03T21:44:00.000Z","updated_at":"2025-04-07T12:07:06.000Z","dependencies_parsed_at":"2024-09-27T01:20:57.615Z","dependency_job_id":"b9cbd542-27d9-47e0-9d67-d7e17845897e","html_url":"https://github.com/fedorovvvv/svelte-floating-ui","commit_stats":{"total_commits":79,"total_committers":5,"mean_commits":15.8,"dds":0.430379746835443,"last_synced_commit":"80140b8d661cf38fe51417665482cb2f6ff9b2f2"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fedorovvvv%2Fsvelte-floating-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fedorovvvv%2Fsvelte-floating-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fedorovvvv%2Fsvelte-floating-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fedorovvvv%2Fsvelte-floating-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fedorovvvv","download_url":"https://codeload.github.com/fedorovvvv/svelte-floating-ui/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480428,"owners_count":21110937,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["floating","floating-ui","svelte","sveltejs","ui"],"created_at":"2024-08-03T23:00:50.064Z","updated_at":"2025-04-11T21:12:30.258Z","avatar_url":"https://github.com/fedorovvvv.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/fedorovvvv/svelte-floating-ui/blob/main/svelte-floating-ui.png\" alt=\"Svelte Floating UI\"\u003e\n\u003cp\u003e\n\n# 🎈Svelte Floating UI\n\n[![npm version](http://img.shields.io/npm/v/svelte-floating-ui.svg)](https://www.npmjs.com/package/svelte-floating-ui)\n[![npm downloads](https://img.shields.io/npm/dm/svelte-floating-ui.svg)](https://www.npmjs.com/package/svelte-floating-ui)\n![license](https://img.shields.io/npm/l/svelte-floating-ui)\n\n[Floating UI](https://github.com/floating-ui/floating-ui/) for Svelte with [actions](https://svelte.dev/docs#use_action). No wrapper components or component bindings required!\n\n```bash\nnpm install svelte-floating-ui\n```\n```bash\npnpm install svelte-floating-ui\n```\n```bash\nyarn add svelte-floating-ui\n```\n\n\n## Usage\n\n`createFloatingActions` takes an optional [options object](https://floating-ui.com/docs/computePosition#options) for configuring the content placement. The content action also takes an optional [options object](https://floating-ui.com/docs/computePosition#options) for updating the options of the content placement.\n\n`createFloatingActions` also returns an `update` method as it's third value which can be used to [manually update](https://floating-ui.com/docs/computePosition#updating) the content position.\n\n### Example\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { offset, flip, shift } from \"svelte-floating-ui/dom\";\n  import { createFloatingActions } from \"svelte-floating-ui\";\n\n  const [ floatingRef, floatingContent ] = createFloatingActions({\n    strategy: \"absolute\",\n    placement: \"top\",\n    middleware: [\n      offset(6),\n      flip(),\n      shift(),\n    ]\n  });\n\n  let showTooltip = $state(false);\n\u003c/script\u003e\n\n\u003cbutton\n  onmouseenter={() =\u003e showTooltip = true}\n  onmouseleave={() =\u003e showTooltip = false}\n  use:floatingRef\n\u003eHover me\u003c/button\u003e\n\n{#if showTooltip}\n  \u003cdiv style=\"position:absolute\" use:floatingContent\u003e\n    Tooltip\n  \u003c/div\u003e\n{/if}\n```\n\n## API\n\n### Setting Floating UI options\n\nFloating UI options can be set statically when creating the actions, or dynamically on the content action.\n\nIf both are set, then the dynamic options will be merged with the initial options.\n\n```svelte\n\u003cscript\u003e\n  // set once and no longer updated\n  const [ floatingRef, floatingContent ] = createFloatingActions(initOptions);\n\u003c/script\u003e\n\n\u003c!-- will be merged with initOptions --\u003e\n\u003cdiv use:floatingContent={ dynamicOptions }/\u003e\n```\n\n### Updating the Floating UI position\n\nThe content element's position can be manually updated by using the third value returned by `createFloatingActions`. This method takes an optional options object which will be merged with the initial options.\n\n```svelte\n\u003cscript\u003e\n  // Get update method\n  const [ floatingRef, floatingContent, update] = createFloatingActions(initOptions);\n\n  update(updateOptions)\n\u003c/script\u003e\n```\n\n### [Floating UI autoUpdate](https://floating-ui.com/docs/autoUpdate)\n\nYou can use [autoUpdate options](https://floating-ui.com/docs/autoUpdate#options) directly in initOptions for [createFloatingActions or floatingContent](https://github.com/fedorovvvv/svelte-floating-ui#example), but not in [update](https://github.com/fedorovvvv/svelte-floating-ui#updating-the-floating-ui-position)\n\n```svelte\n\u003cscript\u003e\n  import { offset, flip, shift } from \"svelte-floating-ui/dom\";\n  import { createFloatingActions } from \"svelte-floating-ui\";\n\n  const [ floatingRef, floatingContent ] = createFloatingActions({\n    strategy: \"absolute\",\n    placement: \"top\",\n    middleware: [\n      offset(6),\n      flip(),\n      shift(),\n    ],\n    autoUpdate: { // or false to disable everything\n      ancestorResize: false,\n      elementResize: false\n    }\n  });\n\u003c/script\u003e\n```\n\nWhat values can autoUpdate have?\n\nPartial\u003c[Options](https://floating-ui.com/docs/autoUpdate#options)\u003e\n\n```ts\n/**\n* false: Don't initialize autoUpdate;\n* true: Standard autoUpdate values from the documentation;\n* object: All as in the autoUpdate documentation. Your parameters are added to the default ones;\n* @default true\n*/\nautoUpdate?: boolean | Partial\u003cOptions\u003e\n```\n\n### [Virtual Elements](https://floating-ui.com/docs/virtual-elements)\n\n**Svelte Floating UI** allows you to use the `floatingRef` (reference node) like [VirtualElement](https://floating-ui.com/docs/virtual-elements)\n\nThis is an example of creating a tooltip that runs behind the mouse cursor:\n\n```svelte\n\u003cscript lang='ts'\u003e\n  import type { ClientRectObject } from 'svelte-floating-ui/dom'\n  import { createFloatingActions, createVirtualElement, type CreateVirtualElementOptions } from 'svelte-floating-ui'\n  \n  const [floatingRef, floatingContent] = createFloatingActions({\n    strategy: 'fixed', //or absolute\n  })\n\n  let x = $state(0)\n  let y = $state(0)\n\n  const handleMouseMove = (ev: MouseEvent) =\u003e {\n    x = ev.clientX\n    y = ev.clientY\n  }\n\n  const getBoundingClientRect: ClientRectObject = $derived({\n    x,\n    y,\n    top: y,\n    left: x,\n    bottom: y,\n    right: x,\n    width: 0,\n    height: 0\n  });\n\n const virtualElement = createVirtualElement({ getBoundingClientRect });\n\n $effect(() =\u003e {\n  virtualElement.update({ getBoundingClientRect });\n });\n\n  floatingRef(virtualElement)\n\u003c/script\u003e\n\n\u003csvelte:window onmousemove={handleMouseMove}/\u003e\n\n\u003cmain\u003e\n  \u003ch2 use:floatingContent\u003eMagic\u003c/h2\u003e\n\u003c/main\u003e\n```\n\n### Applying custom styles on compute\n\nTo apply styles manually, you can pass the `onComputed` option to `createFloatingActions`. This is a function that recieves a [`ComputePositionReturn`](https://floating-ui.com/docs/computeposition#return-value). This function is called every time the tooltip's position is computed.\n\nSee [Arrow Middleware](#arrow-middleware) for an example on it's usage.\n\n## Arrow Middleware\n\nFor convenience, a custom [Arrow middleware](https://floating-ui.com/docs/arrow) is provided. Rather than accepting an `HTMLElement`, this takes a `Writable\u003cHTMLElement\u003e` (`createArrowRef`). Otherwise, this middleware works exactly as the regular Floating UI one, including needing to manually set the arrow styles.\n\nTo set the styles, you can pass the [`onComputed`](#applying-custom-styles-on-compute) option. The below implementation is copied from the [Floating UI Tutorial](https://floating-ui.com/docs/tutorial#arrow-middleware).\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n import { arrow, createArrowRef, createFloatingActions } from 'svelte-floating-ui';\n const arrowRef = createArrowRef();\n let showTooltip = $state(true);\n\n const [floatingRef, floatingContent] = createFloatingActions({\n  strategy: 'absolute',\n  placement: 'bottom',\n  middleware: [arrow({ element: arrowRef })],\n  onComputed({ placement, middlewareData }) {\n   if ($arrowRef) {\n    const { x, y } = middlewareData.arrow || {};\n    const staticSide =\n     {\n      top: 'bottom',\n      right: 'left',\n      bottom: 'top',\n      left: 'right'\n     }[placement.split('-')[0]] ?? 'top';\n\n    Object.assign($arrowRef.style, {\n     left: x != null ? `${x}px` : '',\n     top: y != null ? `${y}px` : '',\n     [staticSide]: '-4px'\n    });\n   }\n  }\n });\n\u003c/script\u003e\n\n\u003cmain\u003e\n \u003cbutton\n  onmouseenter={() =\u003e (showTooltip = true)}\n  onmouseleave={() =\u003e (showTooltip = false)}\n  use:floatingRef\u003eHover me\u003c/button\n \u003e\n\n {#if showTooltip}\n  \u003cdiv class=\"tooltip\" use:floatingContent\u003e\n   Tooltip this is some longer text than the button\n   \u003cdiv class=\"arrow\" style=\"position: absolute;\" bind:this={$arrowRef}\u003e^\u003c/div\u003e\n  \u003c/div\u003e\n {/if}\n\u003c/main\u003e\n\n```\n\n_Thanks to [TehNut/svelte-floating-ui](https://github.com/TehNut/svelte-floating-ui) for the foundation for this package_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffedorovvvv%2Fsvelte-floating-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffedorovvvv%2Fsvelte-floating-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffedorovvvv%2Fsvelte-floating-ui/lists"}