{"id":50863492,"url":"https://github.com/jmjuanes/alure","last_synced_at":"2026-06-14T23:05:02.598Z","repository":{"id":354405157,"uuid":"1222365290","full_name":"jmjuanes/alure","owner":"jmjuanes","description":"A primitive for building and managing floating elements in React","archived":false,"fork":false,"pushed_at":"2026-04-28T11:29:13.000Z","size":32,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-28T13:29:52.832Z","etag":null,"topics":["floating","react","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/jmjuanes.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-27T09:44:02.000Z","updated_at":"2026-04-28T11:29:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jmjuanes/alure","commit_stats":null,"previous_names":["jmjuanes/alure"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jmjuanes/alure","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmjuanes%2Falure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmjuanes%2Falure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmjuanes%2Falure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmjuanes%2Falure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmjuanes","download_url":"https://codeload.github.com/jmjuanes/alure/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmjuanes%2Falure/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34340817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","react","ui"],"created_at":"2026-06-14T23:04:58.660Z","updated_at":"2026-06-14T23:05:02.593Z","avatar_url":"https://github.com/jmjuanes.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# alure\n\n\u003e A primitive for building and managing floating elements in React, powered by composable middlewares.\n\n![npm version](https://badgen.net/npm/v/alure?labelColor=1d2734\u0026color=21bf81)\n![license](https://badgen.net/github/license/jmjuanes/alure?labelColor=1d2734\u0026color=21bf81)\n\nAlure provides a simple and flexible system to display floating elements: dialogs, context menus, command palettes, tooltips, or any UI element that appears on top of your application. Instead of managing visibility state and positioning logic scattered across your components, alure centralises everything in a single provider and lets you compose behaviour through middleware.\n\n## Installation\n\nAdd to your project using **yarn** or **npm**:\n\n```bash\n## install using yarn\n$ yarn add alure\n\n## install using npm\n$ npm install alure\n```\n\n## Basic usage\n\nWrap your application with `AlureProvider` and place `AlureOutlet` where floating elements should be rendered (typically at the root level, just before the closing tag of your app).\n\n```tsx\nimport { AlureProvider, AlureOutlet } from \"alure\";\n\nconst App = () =\u003e (\n    \u003cAlureProvider\u003e\n        \u003cYourApp /\u003e\n        \u003cAlureOutlet /\u003e\n    \u003c/AlureProvider\u003e\n);\n```\n\nThen use the `useAlure` hook anywhere in your component tree to open and close floating elements:\n\n```tsx\nimport { useAlure, withOverlay, withDismiss } from \"alure\";\nimport { MyDialog } from \"./MyDialog\";\n\nconst OpenDialogButton = () =\u003e {\n    const { open } = useAlure();\n\n    return (\n        \u003cbutton onClick={() =\u003e open(\"my-dialog\", {\n            component: MyDialog,\n            middlewares: [\n                withOverlay({\n                    closeOnClick: true,\n                }),\n                withDismiss(),\n            ],\n            context: {\n                title: \"Hello from alure\",\n            },\n        })}\u003e\n            Open dialog\n        \u003c/button\u003e\n    );\n};\n```\n\nInside `MyDialog`, use `useAlure` to access the element context and close itself:\n\n```tsx\nimport { useAlure } from \"alure\";\n\nconst MyDialog = () =\u003e {\n    const { close, getContext } = useAlure();\n    const { title } = getContext();\n\n    return (\n        \u003cdiv className=\"dialog\"\u003e\n            \u003ch2\u003e{title}\u003c/h2\u003e\n            \u003cbutton onClick={() =\u003e close()}\u003eClose\u003c/button\u003e\n        \u003c/div\u003e\n    );\n};\n```\n\n## API\n\n### `AlureProvider`\n\nThe root provider. Wrap your application with it to enable alure.\n\n```tsx\n\u003cAlureProvider\u003e\n    {children}\n\u003c/AlureProvider\u003e\n```\n\n### `AlureOutlet`\n\nRenders all active floating elements. Place it at the root of your application, outside your main content.\n\n```tsx\n\u003cAlureOutlet /\u003e\n```\n\n### `useAlure`\n\nHook to interact with the alure manager. Returns the following methods:\n\n#### `open(id, element)`\n\nOpens a floating element.\n\n| Parameter | Type | Description |\n|---|---|---|\n| `id` | `string` | Unique identifier for the element. |\n| `element.component` | `ElementType` | The React component to render. Required. |\n| `element.middlewares` | `AlureMiddleware[]` | Optional array of middleware to compose behaviour. |\n| `element.context` | `any` | Optional data passed to the element, accessible via `getContext()`. |\n| `element.onMount` | `function` | Callback to be executed when the floating element is mounted. |\n| `element.onUnmount` | `function` | Callback to be executed when the floating element is removed. |\n\n#### `close(id?)`\n\nCloses a floating element. When called without an `id` from inside a floating element, it closes itself. When called from outside a floating element, an `id` is required.\n\n#### `closeAll()`\n\nCloses all active floating elements.\n\n#### `getContext()`\n\nReturns the context object passed when the element was opened. Only available inside a floating element.\n\n### Middleware\n\nMiddleware are composable units that wrap a floating element to add positioning, behaviour, or visual decoration. They are applied in order, outermost first.\n\n#### `withFixedPosition(options)`\n\nPositions the element at a fixed coordinate on the screen.\n\n| Option | Type | Description |\n|---|---|---|\n| `top` | `number \\| string` | Distance from the top of the viewport. |\n| `left` | `number \\| string` | Distance from the left of the viewport. |\n| `className` | `string` | Optional CSS class for the container. |\n| `style` | `CSSProperties` | Optional additional inline styles for the container. |\n\n#### `withOverlay(options?)`\n\nRenders a full-screen overlay behind the floating element.\n\n| Option | Type | Description |\n|---|---|---|\n| `closeOnClick` | `boolean` | If `true`, closes the element when the overlay is clicked. |\n| `className` | `string` | Optional CSS class for the overlay. |\n| `style` | `CSSProperties` | Optional additional inline styles. |\n\n#### `withDismiss()`\n\nCloses the floating element when the user presses the `Escape` key.\n\n#### `withPortal(options?)`\n\nRenders the floating element inside a React portal, detaching it from the current DOM tree.\n\n| Option | Type | Description |\n|---|---|---|\n| `target` | `HTMLElement` | Target DOM node. Defaults to `document.body`. |\n| `key` | `string` | Optional React key for the portal. |\n\n## Examples\n\n### Context menu\n\n```tsx\nimport { useCallback } from \"react\";\nimport { useAlure, withFixedPosition, withDismiss } from \"alure\";\nimport { ContextMenu } from \"./ContextMenu\";\n\nconst Canvas = () =\u003e {\n    const { open } = useAlure();\n\n    const handleContextMenu = useCallback((event: React.MouseEvent) =\u003e {\n        event.preventDefault();\n        open(\"context-menu\", {\n            component: ContextMenu,\n            middlewares: [\n                withFixedPosition({\n                    top: event.clientY,\n                    left: event.clientX,\n                }),\n                withDismiss(),\n            ],\n            context: {\n                position: {\n                    top: event.clientY,\n                    left: event.clientX,\n                },\n            },\n        });\n    }, [open]);\n\n    return (\n        \u003cdiv onContextMenu={handleContextMenu}\u003eRight-click me\u003c/div\u003e\n    );\n};\n```\n\n### Dialog with overlay\n\n```tsx\nimport { useAlure, withOverlay, withDismiss } from \"alure\";\nimport { ExportDialog } from \"./ExportDialog\";\n\nconst ExportButton = () =\u003e {\n    const { open } = useAlure();\n\n    return (\n        \u003cbutton onClick={() =\u003e open(\"export-dialog\", {\n            component: ExportDialog,\n            middlewares: [\n                withOverlay({ closeOnClick: true }),\n                withDismiss(),\n            ],\n        })}\u003e\n            Export\n        \u003c/button\u003e\n    );\n};\n```\n\n### Command palette\n\n```tsx\nimport { useAlure, withDismiss } from \"alure\";\nimport { CommandsPalette } from \"./CommandsPalette\";\n\nconst useCommandsPalette = () =\u003e {\n    const { open, close } = useAlure();\n\n    return {\n        openPalette: () =\u003e open(\"commands-palette\", {\n            component: CommandsPalette,\n            middlewares: [\n                withDismiss(),\n            ],\n        }),\n        closePalette: () =\u003e close(\"commands-palette\"),\n    };\n};\n```\n\n### Custom middleware\n\nYou can build your own middleware by returning an object with a `wrapper` component:\n\n```tsx\nimport type { AlureMiddleware } from \"alure\";\nimport type { PropsWithChildren } from \"react\";\n\nconst withFadeIn = (): AlureMiddleware =\u003e ({\n    wrapper: ({ children }: PropsWithChildren) =\u003e (\n        \u003cdiv style={{ animation: \"fadeIn 150ms ease-out\" }}\u003e\n            {children}\n        \u003c/div\u003e\n    ),\n});\n```\n\n## License\n\nAlure is release under the [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmjuanes%2Falure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmjuanes%2Falure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmjuanes%2Falure/lists"}