@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.
- package/LICENSE +21 -0
- package/README.md +44 -1
- package/dist/components/accordion/accordion.css +109 -0
- package/dist/components/accordion/accordion.d.ts +41 -0
- package/dist/components/drawer/drawer.css +117 -0
- package/dist/components/drawer/drawer.d.ts +29 -0
- package/dist/components/menu/menu.css +106 -0
- package/dist/components/menu/menu.d.ts +71 -0
- package/dist/components/modal/modal.css +122 -0
- package/dist/components/modal/modal.d.ts +27 -0
- package/dist/components/popover/popover.css +115 -0
- package/dist/components/popover/popover.d.ts +36 -0
- package/dist/components/tooltip/tooltip.css +60 -0
- package/dist/components/tooltip/tooltip.d.ts +19 -0
- package/dist/index.css +13 -0
- package/dist/index.js +1089 -0
- package/dist/lib/after-transition.d.ts +18 -0
- package/dist/lib/described-by.d.ts +23 -0
- package/dist/lib/dialog-focus.d.ts +48 -0
- package/dist/lib/inert.d.ts +56 -0
- package/dist/lib/styles-check.d.ts +12 -0
- package/dist/overlays.d.ts +7 -0
- package/package.json +43 -3
|
@@ -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": "
|
|
4
|
-
"description": "
|
|
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
|
}
|