@corndev/ui-overlays 0.0.0-reserved.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Runs `done` once `el`'s own transition ends — or after `fallbackMs`, whichever
3
+ * comes first — and returns a function that cancels it.
4
+ *
5
+ * A dialog's teardown used to wait on a one-time `transitionend` alone. With no
6
+ * transition to end (reduced motion, the stylesheet not loaded) or a `destroy()`
7
+ * that removed the element first, it never came: the backdrop stayed and the
8
+ * page stayed scroll-locked. And a dialog reopened during its fade-out kept the
9
+ * old listener, which then tore down the newly open one. The fallback covers
10
+ * the first; cancelling on reopen covers the second. Only the element's own
11
+ * event counts, not one bubbling up from a child's hover transition.
12
+ *
13
+ * @param {HTMLElement} el
14
+ * @param {() => void} done
15
+ * @param {number} [fallbackMs=500] Longer than any transition the theme defines.
16
+ * @returns {() => void} Cancel.
17
+ */
18
+ export function afterTransition(el: HTMLElement, done: () => void, fallbackMs?: number): () => void;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Space-separated ids from every argument, de-duplicated in order; undefined
3
+ * when there are none, so React omits the attribute.
4
+ *
5
+ * @param {...(string | null | undefined)} lists
6
+ * @returns {string | undefined}
7
+ */
8
+ export function mergeIds(...lists: (string | null | undefined)[]): string | undefined;
9
+ /**
10
+ * Add ids to an element's aria-describedby, keeping the ones already there.
11
+ *
12
+ * @param {Element} el
13
+ * @param {...string} ids
14
+ */
15
+ export function addDescribedBy(el: Element, ...ids: string[]): void;
16
+ /**
17
+ * Remove ids from an element's aria-describedby, and the attribute itself only
18
+ * when nothing is left.
19
+ *
20
+ * @param {Element} el
21
+ * @param {...string} ids
22
+ */
23
+ export function removeDescribedBy(el: Element, ...ids: string[]): void;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Focusable elements inside `root`, in document order — skipping anything in a
3
+ * `hidden` or `inert` subtree, such as a closed accordion panel, which the
4
+ * browser would refuse to focus anyway.
5
+ *
6
+ * @param {Element} root
7
+ * @returns {HTMLElement[]}
8
+ */
9
+ export function focusableIn(root: Element): HTMLElement[];
10
+ /**
11
+ * The element a dialog should focus when it opens, in order of who asked:
12
+ *
13
+ * 1. `[data-autofocus]` — the author named it. Mantine's convention too, so a
14
+ * migrating app needs no change. On a wrapper it means the first control
15
+ * inside.
16
+ * 2. Whatever React's `autoFocus` already focused. React does not render an
17
+ * `autofocus` attribute; it calls `focus()` during commit, before any effect
18
+ * runs, so the only trace it leaves is `document.activeElement`.
19
+ * 3. `[autofocus]` — the same request, written in plain HTML.
20
+ * 4. The first focusable element that is not the close control.
21
+ * 5. The close control, and failing that the dialog itself — which is why the
22
+ * dialog carries `tabindex="-1"`.
23
+ *
24
+ * @param {HTMLElement} root The element with `role="dialog"`.
25
+ * @returns {HTMLElement}
26
+ */
27
+ export function chooseInitialFocus(root: HTMLElement): HTMLElement;
28
+ /**
29
+ * Whether `el` is only a last resort — the close control or the dialog itself —
30
+ * meaning nothing in the content asked for focus. A lazily loaded body can still
31
+ * arrive and ask, so this is when it is worth looking again.
32
+ *
33
+ * @param {HTMLElement} root
34
+ * @param {Element | null} el
35
+ * @returns {boolean}
36
+ */
37
+ export function isFallbackFocus(root: HTMLElement, el: Element | null): boolean;
38
+ /**
39
+ * Keeps Tab inside `root`: wraps from the last control to the first and back,
40
+ * and pulls focus in if it has somehow ended up outside.
41
+ *
42
+ * @param {KeyboardEvent} event
43
+ * @param {HTMLElement} root
44
+ * @returns {void}
45
+ */
46
+ export function wrapTab(event: KeyboardEvent, root: HTMLElement): void;
47
+ /** Marks a dialog's own close control, so it is the last resort rather than the default. */
48
+ export const CLOSE_ATTR: "data-dialog-close";
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Re-applies `inert` around the topmost open layer.
3
+ *
4
+ * Called after any layer opens or closes: it clears what it set last time, finds
5
+ * the layer that is now on top, and inerts that layer's siblings — which is how
6
+ * a lower dialog becomes inert while a higher one is open, since both are
7
+ * children of the same portal root.
8
+ *
9
+ * @param {Document} [doc=document] Document to update.
10
+ * @returns {void}
11
+ */
12
+ export function refreshInert(doc?: Document): void;
13
+ /**
14
+ * Opens a dialog layer: everything beside it, including any dialog already open,
15
+ * becomes inert.
16
+ *
17
+ * @param {HTMLElement} el The dialog's outermost element (the backdrop).
18
+ * @returns {void}
19
+ */
20
+ export function openLayer(el: HTMLElement): void;
21
+ /**
22
+ * Closes a dialog layer and hands the page back — to the dialog below it if
23
+ * there is one, otherwise to the page.
24
+ *
25
+ * Safe to call on an element that was never opened, and on one already detached
26
+ * from the document, which is what unmounting a React portal leaves behind.
27
+ *
28
+ * @param {HTMLElement} el The element passed to {@link openLayer}.
29
+ * @returns {void}
30
+ */
31
+ export function closeLayer(el: HTMLElement): void;
32
+ /**
33
+ * Whether `el` is the topmost open dialog layer.
34
+ *
35
+ * Keyboard shortcuts belong to the dialog on top and to nothing beneath it.
36
+ * Every open dialog listens for keys on the document, because focus can sit on
37
+ * the backdrop or on `<body>` after a click, so without this check one Escape
38
+ * reached every listener and closed a whole stack at once — the confirm *and* the
39
+ * form it was confirming, with the form's unsaved work.
40
+ *
41
+ * Read from the DOM for the same reason as the rest of this module: each
42
+ * component's copy of this helper sees the same layers.
43
+ *
44
+ * @param {HTMLElement} el The element passed to {@link openLayer}.
45
+ * @returns {boolean}
46
+ */
47
+ export function isTopLayer(el: HTMLElement): boolean;
48
+ /**
49
+ * Whether any open layer matches `selector` — so a dialog closing on top of
50
+ * another of its kind leaves the page's scroll lock in place for the one below.
51
+ *
52
+ * @param {Document} doc
53
+ * @param {string} selector A selector the layer element must also match.
54
+ * @returns {boolean}
55
+ */
56
+ export function hasOpenLayer(doc: Document, selector: string): boolean;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Warns, once per package, if the package's stylesheet is not on the page.
3
+ *
4
+ * The record of what has been checked lives on `globalThis`, not in this module:
5
+ * the React build inlines helpers like this into each component's module, so a
6
+ * module-level set would warn once per component instead of once per package.
7
+ *
8
+ * @param {keyof PACKAGES} pkg The package the component ships in.
9
+ * @param {string} component Its name, for the message.
10
+ * @returns {void}
11
+ */
12
+ export function checkStylesLoaded(pkg: "@corndev/ui-overlays" | "@corndev/ui-notifications" | "@corndev/ui-markdown" | "@corndev/ui-icons", component: string): void;
@@ -0,0 +1,7 @@
1
+ export { createModal } from "./components/modal/modal.js";
2
+ export { createDrawer } from "./components/drawer/drawer.js";
3
+ export { createAccordion } from "./components/accordion/accordion.js";
4
+ export { createTooltip } from "./components/tooltip/tooltip.js";
5
+ export { createPopover } from "./components/popover/popover.js";
6
+ export { createMenu } from "./components/menu/menu.js";
7
+ export const version: "1.0.0-beta.1";
package/package.json CHANGED
@@ -1,12 +1,52 @@
1
1
  {
2
2
  "name": "@corndev/ui-overlays",
3
- "version": "0.0.0-reserved.0",
4
- "description": "Reserved for Corn UI. Install @corndev/ui-overlays@latest for the real package.",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Corn UI — Overlay components: Modal, Drawer, Accordion, Tooltip, Popover",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/overlays.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/overlays.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./styles": "./dist/index.css"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "node ../../scripts/build-ui-overlays.js",
21
+ "prepack": "node ../../scripts/copy-license.js",
22
+ "clean": "rm -rf dist"
23
+ },
24
+ "keywords": [
25
+ "corn-ui",
26
+ "corndog",
27
+ "ui",
28
+ "modal",
29
+ "drawer",
30
+ "accordion",
31
+ "tooltip",
32
+ "popover",
33
+ "overlay"
34
+ ],
35
+ "author": "Corndog Development LLC",
5
36
  "license": "MIT",
6
37
  "repository": {
7
38
  "type": "git",
8
39
  "url": "git+https://gitlab.com/corn-dev/corn-ui.git",
9
40
  "directory": "packages/ui-overlays"
10
41
  },
11
- "homepage": "https://cornui.com"
42
+ "homepage": "https://cornui.com",
43
+ "bugs": {
44
+ "url": "https://gitlab.com/corn-dev/corn-ui/-/issues"
45
+ },
46
+ "dependencies": {
47
+ "@corndev/ui": "1.0.0-beta.1"
48
+ },
49
+ "sideEffects": [
50
+ "**/*.css"
51
+ ]
12
52
  }