@allxsmith/bestax-bulma 5.51.0 → 5.53.0
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/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/Command.js +637 -0
- package/dist/esm/components/Command.js.map +1 -0
- package/dist/esm/components/Modal.js +2 -1
- package/dist/esm/components/Modal.js.map +1 -1
- package/dist/esm/components/Sidebar.js +3 -1
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/components/Toast.js +8 -5
- package/dist/esm/components/Toast.js.map +1 -1
- package/dist/esm/elements/Notification.js +4 -2
- package/dist/esm/elements/Notification.js.map +1 -1
- package/dist/esm/form/Autocomplete.js +5 -4
- package/dist/esm/form/Autocomplete.js.map +1 -1
- package/dist/esm/form/Checkbox.js +3 -2
- package/dist/esm/form/Checkbox.js.map +1 -1
- package/dist/esm/form/CheckboxCard.js +119 -0
- package/dist/esm/form/CheckboxCard.js.map +1 -0
- package/dist/esm/form/Checkboxes.js +14 -3
- package/dist/esm/form/Checkboxes.js.map +1 -1
- package/dist/esm/form/Combobox.js +3 -2
- package/dist/esm/form/Combobox.js.map +1 -1
- package/dist/esm/form/DateInputBase.js +15 -6
- package/dist/esm/form/DateInputBase.js.map +1 -1
- package/dist/esm/form/DateRangeInputBase.js +15 -5
- package/dist/esm/form/DateRangeInputBase.js.map +1 -1
- package/dist/esm/form/DateTimeInputBase.js +15 -6
- package/dist/esm/form/DateTimeInputBase.js.map +1 -1
- package/dist/esm/form/Fieldset.js +64 -0
- package/dist/esm/form/Fieldset.js.map +1 -0
- package/dist/esm/form/FormContext.js +17 -1
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/InputBase.js +3 -2
- package/dist/esm/form/InputBase.js.map +1 -1
- package/dist/esm/form/Numberinput.js +3 -2
- package/dist/esm/form/Numberinput.js.map +1 -1
- package/dist/esm/form/PinInput.js +3 -2
- package/dist/esm/form/PinInput.js.map +1 -1
- package/dist/esm/form/Radio.js +3 -2
- package/dist/esm/form/Radio.js.map +1 -1
- package/dist/esm/form/RadioCard.js +86 -0
- package/dist/esm/form/RadioCard.js.map +1 -0
- package/dist/esm/form/Radios.js +14 -3
- package/dist/esm/form/Radios.js.map +1 -1
- package/dist/esm/form/Rate.js +3 -2
- package/dist/esm/form/Rate.js.map +1 -1
- package/dist/esm/form/SelectBase.js +3 -2
- package/dist/esm/form/SelectBase.js.map +1 -1
- package/dist/esm/form/Slider.js +3 -2
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/Switch.js +3 -1
- package/dist/esm/form/Switch.js.map +1 -1
- package/dist/esm/form/Taginput.js +3 -2
- package/dist/esm/form/Taginput.js.map +1 -1
- package/dist/esm/form/TextAreaBase.js +3 -2
- package/dist/esm/form/TextAreaBase.js.map +1 -1
- package/dist/esm/form/TimeInputBase.js +13 -6
- package/dist/esm/form/TimeInputBase.js.map +1 -1
- package/dist/esm/form/_pickerInternals/PickerPopover.js +4 -2
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useLocaleDefaults.js +80 -0
- package/dist/esm/form/_pickerInternals/useLocaleDefaults.js.map +1 -0
- package/dist/esm/form/groupFieldset.js +38 -0
- package/dist/esm/form/groupFieldset.js.map +1 -0
- package/dist/esm/form/useAutoLabelId.js +1 -1
- package/dist/esm/helpers/LocaleProvider.js +153 -0
- package/dist/esm/helpers/LocaleProvider.js.map +1 -0
- package/dist/esm/helpers/localeInfo.js +109 -0
- package/dist/esm/helpers/localeInfo.js.map +1 -0
- package/dist/esm/helpers/portal.js +14 -1
- package/dist/esm/helpers/portal.js.map +1 -1
- package/dist/esm/helpers/useComboboxEngine.js +3 -3
- package/dist/esm/helpers/useFocusTrap.js +2 -2
- package/dist/esm/helpers/useFocusTrap.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +4905 -3584
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +5 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Command.d.ts +318 -0
- package/dist/types/form/CheckboxCard.d.ts +94 -0
- package/dist/types/form/Checkboxes.d.ts +13 -0
- package/dist/types/form/DateInputBase.d.ts +25 -3
- package/dist/types/form/DateRangeInputBase.d.ts +25 -3
- package/dist/types/form/DateTimeInputBase.d.ts +25 -3
- package/dist/types/form/Fieldset.d.ts +86 -0
- package/dist/types/form/FormContext.d.ts +12 -0
- package/dist/types/form/RadioCard.d.ts +81 -0
- package/dist/types/form/Radios.d.ts +13 -0
- package/dist/types/form/TimeInputBase.d.ts +5 -1
- package/dist/types/form/_pickerInternals/PickerPopover.d.ts +6 -0
- package/dist/types/form/_pickerInternals/useLocaleDefaults.d.ts +49 -0
- package/dist/types/form/groupFieldset.d.ts +32 -0
- package/dist/types/helpers/LocaleProvider.d.ts +128 -0
- package/dist/types/helpers/localeInfo.d.ts +23 -0
- package/dist/types/helpers/portal.d.ts +11 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types-cjs/components/Command.d.ts +318 -0
- package/dist/types-cjs/form/CheckboxCard.d.ts +94 -0
- package/dist/types-cjs/form/Checkboxes.d.ts +13 -0
- package/dist/types-cjs/form/DateInputBase.d.ts +25 -3
- package/dist/types-cjs/form/DateRangeInputBase.d.ts +25 -3
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +25 -3
- package/dist/types-cjs/form/Fieldset.d.ts +86 -0
- package/dist/types-cjs/form/FormContext.d.ts +12 -0
- package/dist/types-cjs/form/RadioCard.d.ts +81 -0
- package/dist/types-cjs/form/Radios.d.ts +13 -0
- package/dist/types-cjs/form/TimeInputBase.d.ts +5 -1
- package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +6 -0
- package/dist/types-cjs/form/_pickerInternals/useLocaleDefaults.d.ts +49 -0
- package/dist/types-cjs/form/groupFieldset.d.ts +32 -0
- package/dist/types-cjs/helpers/LocaleProvider.d.ts +128 -0
- package/dist/types-cjs/helpers/localeInfo.d.ts +23 -0
- package/dist/types-cjs/helpers/portal.d.ts +11 -0
- package/dist/types-cjs/index.d.ts +6 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/components/_command.scss +259 -0
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/form/_checkbox.scss +44 -0
- package/src/scss/form/_checkboxcard.scss +355 -0
- package/src/scss/form/_fieldset.scss +108 -0
- package/src/scss/form/_index.scss +3 -0
- package/src/scss/form/_radio.scss +44 -0
- package/src/scss/form/_radiocard.scss +291 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { createContext, forwardRef, useContext, useMemo, useRef, useCallback, useState } from 'react';
|
|
4
|
+
import { classNames } from './classNames.js';
|
|
5
|
+
import { useBulmaClasses } from './useBulmaClasses.js';
|
|
6
|
+
import { warnOnce } from './devWarnings.js';
|
|
7
|
+
import { localeDirection, canonicalLocale } from './localeInfo.js';
|
|
8
|
+
|
|
9
|
+
const LocaleContext = createContext(null);
|
|
10
|
+
/** The nearest provider's wrapper element, for `LocalePortalScope` to test targets against. */
|
|
11
|
+
const LocaleElementContext = createContext(null);
|
|
12
|
+
/** A tag in canonical form, or `undefined`, warning about one `Intl` refuses. */
|
|
13
|
+
function validLocale(tag) {
|
|
14
|
+
try {
|
|
15
|
+
return canonicalLocale(tag);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
warnOnce(`locale-provider-invalid:${tag}`, `[bestax-bulma] <LocaleProvider locale="${tag}">: not a language ` +
|
|
19
|
+
'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +
|
|
20
|
+
'"en-US", with a hyphen rather than an underscore.');
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Sets the language and writing direction for the part of the app inside it, on a wrapper `<div>` and on what the library portals out of it.
|
|
26
|
+
*
|
|
27
|
+
* The wrapper carries `dir` and `lang`, so CSS and the components that read
|
|
28
|
+
* the computed direction follow it, as they follow `<html dir>`. A `locale`
|
|
29
|
+
* alone sets the direction of its script, and a `dir` sets the direction
|
|
30
|
+
* whatever the locale. A nested provider keeps whatever it leaves unset.
|
|
31
|
+
*
|
|
32
|
+
* Inside it, the date and time pickers take its `locale` unless given their
|
|
33
|
+
* own, and their week starts on the first day of the locale they use unless
|
|
34
|
+
* `firstDayOfWeek` is set, and a picker with a `locale` of its own is read
|
|
35
|
+
* like a nested provider. The library's portaled content, such as a
|
|
36
|
+
* `Popover` panel, a `Modal` with `portal`, a `Toast` or a `Portal`'s
|
|
37
|
+
* children, keeps the same `dir` and `lang` though it renders outside the
|
|
38
|
+
* wrapper: in a container outside the wrapper, it sits in a
|
|
39
|
+
* `display: contents` element that carries them. Without a provider none of
|
|
40
|
+
* this changes.
|
|
41
|
+
*
|
|
42
|
+
* @function
|
|
43
|
+
* @param {LocaleProviderProps} props - Props for the LocaleProvider.
|
|
44
|
+
* @returns {JSX.Element} The wrapper, inside the context.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* <LocaleProvider locale="ar-EG">
|
|
48
|
+
* <App />
|
|
49
|
+
* </LocaleProvider>
|
|
50
|
+
*/
|
|
51
|
+
const LocaleProvider = forwardRef(({ locale: localeProp, dir: dirProp, className, children, ...props }, ref) => {
|
|
52
|
+
const outer = useContext(LocaleContext);
|
|
53
|
+
const ownLocale = useMemo(() => validLocale(localeProp), [localeProp]);
|
|
54
|
+
const ownLocaleDir = useMemo(() => (ownLocale ? localeDirection(ownLocale) : undefined), [ownLocale]);
|
|
55
|
+
const locale = ownLocale || outer?.locale;
|
|
56
|
+
const dir = dirProp || ownLocaleDir || outer?.dir;
|
|
57
|
+
const value = useMemo(() => ({ locale, dir }), [locale, dir]);
|
|
58
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
59
|
+
// The wrapper, for portaled content to tell whether its target is inside
|
|
60
|
+
// it, and the caller's ref. A callback ref's cleanup is held and run on
|
|
61
|
+
// detach, as Toast and Modal do, since React 18 discards the return value.
|
|
62
|
+
const elementRef = useRef(null);
|
|
63
|
+
const consumerCleanupRef = useRef(null);
|
|
64
|
+
const setElement = useCallback((node) => {
|
|
65
|
+
elementRef.current = node;
|
|
66
|
+
if (typeof ref === 'function') {
|
|
67
|
+
if (node === null) {
|
|
68
|
+
const consumerCleanup = consumerCleanupRef.current;
|
|
69
|
+
consumerCleanupRef.current = null;
|
|
70
|
+
if (consumerCleanup)
|
|
71
|
+
consumerCleanup();
|
|
72
|
+
else
|
|
73
|
+
ref(null);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const cleanup = ref(node);
|
|
77
|
+
consumerCleanupRef.current =
|
|
78
|
+
typeof cleanup === 'function' ? cleanup : null;
|
|
79
|
+
}
|
|
80
|
+
else if (ref) {
|
|
81
|
+
ref.current = node;
|
|
82
|
+
}
|
|
83
|
+
}, [ref]);
|
|
84
|
+
return (jsx(LocaleContext.Provider, { value: value, children: jsx(LocaleElementContext.Provider, { value: elementRef, children: jsx("div", { ref: setElement, className: classNames(bulmaHelperClasses, className) || undefined, ...rest, dir: dir, lang: locale, children: children }) }) }));
|
|
85
|
+
});
|
|
86
|
+
LocaleProvider.displayName = 'LocaleProvider';
|
|
87
|
+
/** What `useLocale` returns outside a provider, the same object each time. */
|
|
88
|
+
const noLocale = {};
|
|
89
|
+
/**
|
|
90
|
+
* The locale and direction the nearest `LocaleProvider` sets, for an app's own `Intl` calls or its own portaled content; both are `undefined` outside one.
|
|
91
|
+
*
|
|
92
|
+
* It isn't the page's direction: with no provider, or one that sets no
|
|
93
|
+
* direction, the page's `<html dir>` still decides. To act on the direction
|
|
94
|
+
* an element is laid out in, read `getComputedStyle(element).direction`, as
|
|
95
|
+
* the library's components do.
|
|
96
|
+
*
|
|
97
|
+
* @function
|
|
98
|
+
* @returns {LocaleContextValue} The nearest provider's `locale` and `dir`.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* const { locale } = useLocale();
|
|
102
|
+
* const price = new Intl.NumberFormat(locale, {
|
|
103
|
+
* style: 'currency',
|
|
104
|
+
* currency: 'EUR',
|
|
105
|
+
* }).format(12.5);
|
|
106
|
+
*/
|
|
107
|
+
function useLocale() {
|
|
108
|
+
return useContext(LocaleContext) ?? noLocale;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* INTERNAL, deliberately not exported from `src/index.ts`. The nearest
|
|
112
|
+
* provider's settings, or `null` outside any provider, so a caller can tell
|
|
113
|
+
* "no provider" from "a provider that sets nothing".
|
|
114
|
+
*/
|
|
115
|
+
function useLocaleScope() {
|
|
116
|
+
return useContext(LocaleContext);
|
|
117
|
+
}
|
|
118
|
+
const displayContents = { display: 'contents' };
|
|
119
|
+
/**
|
|
120
|
+
* INTERNAL, deliberately not exported from `src/index.ts`. Keeps the `dir`
|
|
121
|
+
* and `lang` of the nearest provider, or the `scope` given in their place,
|
|
122
|
+
* on content the library portals into `target`, which has left the
|
|
123
|
+
* provider's wrapper behind.
|
|
124
|
+
*
|
|
125
|
+
* A target inside the provider's own wrapper gets the content as it is: it
|
|
126
|
+
* inherits from the wrapper, and follows it when the provider changes.
|
|
127
|
+
* Content that must be its container's direct child, a `<tr>` portaled into
|
|
128
|
+
* a `<tbody>` there, stays one. Any other target, `document.body` included,
|
|
129
|
+
* gets the content inside a `display: contents` element carrying the
|
|
130
|
+
* values, which adds no box. So does content with a `scope` of its own, a
|
|
131
|
+
* picker's panel, since the provider's values aren't its own.
|
|
132
|
+
*
|
|
133
|
+
* Which of the two is decided once, when the content mounts, and kept while
|
|
134
|
+
* it stays: switching between them would put a different element in its
|
|
135
|
+
* place and remount everything inside, losing typed text, focus and timers.
|
|
136
|
+
* A change of locale or direction updates the wrapper's attributes instead.
|
|
137
|
+
* A target is never left bare because something else, such as `<html>`,
|
|
138
|
+
* happens to carry the same values, since that can stop being true without
|
|
139
|
+
* the content remounting. Outside a provider it renders the children alone,
|
|
140
|
+
* so nothing changes there.
|
|
141
|
+
*/
|
|
142
|
+
function LocalePortalScope({ children, target, scope, }) {
|
|
143
|
+
const provider = useContext(LocaleContext);
|
|
144
|
+
const element = useContext(LocaleElementContext);
|
|
145
|
+
const [wrap] = useState(() => scope !== undefined || !element?.current?.contains(target));
|
|
146
|
+
if (!provider || !wrap)
|
|
147
|
+
return jsx(Fragment, { children: children });
|
|
148
|
+
const values = scope ?? provider;
|
|
149
|
+
return (jsx("div", { dir: values.dir, lang: values.locale, style: displayContents, children: children }));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export { LocalePortalScope, LocaleProvider, useLocale, useLocaleScope };
|
|
153
|
+
//# sourceMappingURL=LocaleProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocaleProvider.js","sources":["../../../src/helpers/LocaleProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames } from './classNames';\nimport { useBulmaClasses, BulmaClassesProps } from './useBulmaClasses';\nimport { warnOnce } from './devWarnings';\nimport { canonicalLocale, localeDirection } from './localeInfo';\n\n/** A writing direction. */\nexport type TextDirection = 'ltr' | 'rtl';\n\n/** What the nearest `LocaleProvider` sets, both `undefined` outside one. */\nexport interface LocaleContextValue {\n /**\n * The locale, as a canonical BCP 47 tag such as `\"ar-EG\"`: the provider's\n * own, else the one an outer provider sets.\n */\n locale?: string;\n /**\n * The direction: the provider's own `dir`, else its own locale's, else the\n * one an outer provider sets.\n */\n dir?: TextDirection;\n}\n\nconst LocaleContext = createContext<LocaleContextValue | null>(null);\n\n/** The nearest provider's wrapper element, for `LocalePortalScope` to test targets against. */\nconst LocaleElementContext =\n createContext<React.RefObject<HTMLDivElement | null> | null>(null);\n\n/**\n * Props for the LocaleProvider component. The helper props, the other\n * attributes and the `ref` land on its `<div>`.\n */\nexport interface LocaleProviderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'dir' | 'lang' | 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * A BCP 47 language tag, such as `\"de\"` or `\"ar-EG\"`. It becomes the\n * wrapper's `lang`, the default `locale` of the date and time pickers\n * inside, and, with no `dir`, the direction, from the way its script is\n * written. Unset, a nested provider keeps the outer one's. A tag `Intl`\n * refuses is ignored, with a warning in development.\n */\n locale?: string;\n /**\n * The direction, whatever the locale. Unset, it follows this provider's\n * `locale`, else an outer provider's direction, else the page's.\n */\n dir?: TextDirection;\n /** The part of the app it covers. */\n children?: React.ReactNode;\n}\n\n/** A tag in canonical form, or `undefined`, warning about one `Intl` refuses. */\nfunction validLocale(tag: string | undefined): string | undefined {\n try {\n return canonicalLocale(tag);\n } catch {\n warnOnce(\n `locale-provider-invalid:${tag}`,\n `[bestax-bulma] <LocaleProvider locale=\"${tag}\">: not a language ` +\n 'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +\n '\"en-US\", with a hyphen rather than an underscore.'\n );\n return undefined;\n }\n}\n\n/**\n * Sets the language and writing direction for the part of the app inside it, on a wrapper `<div>` and on what the library portals out of it.\n *\n * The wrapper carries `dir` and `lang`, so CSS and the components that read\n * the computed direction follow it, as they follow `<html dir>`. A `locale`\n * alone sets the direction of its script, and a `dir` sets the direction\n * whatever the locale. A nested provider keeps whatever it leaves unset.\n *\n * Inside it, the date and time pickers take its `locale` unless given their\n * own, and their week starts on the first day of the locale they use unless\n * `firstDayOfWeek` is set, and a picker with a `locale` of its own is read\n * like a nested provider. The library's portaled content, such as a\n * `Popover` panel, a `Modal` with `portal`, a `Toast` or a `Portal`'s\n * children, keeps the same `dir` and `lang` though it renders outside the\n * wrapper: in a container outside the wrapper, it sits in a\n * `display: contents` element that carries them. Without a provider none of\n * this changes.\n *\n * @function\n * @param {LocaleProviderProps} props - Props for the LocaleProvider.\n * @returns {JSX.Element} The wrapper, inside the context.\n *\n * @example\n * <LocaleProvider locale=\"ar-EG\">\n * <App />\n * </LocaleProvider>\n */\nexport const LocaleProvider = forwardRef<HTMLDivElement, LocaleProviderProps>(\n (\n { locale: localeProp, dir: dirProp, className, children, ...props },\n ref\n ) => {\n const outer = useContext(LocaleContext);\n const ownLocale = useMemo(() => validLocale(localeProp), [localeProp]);\n const ownLocaleDir = useMemo(\n () => (ownLocale ? localeDirection(ownLocale) : undefined),\n [ownLocale]\n );\n const locale = ownLocale || outer?.locale;\n const dir = dirProp || ownLocaleDir || outer?.dir;\n const value = useMemo(() => ({ locale, dir }), [locale, dir]);\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n // The wrapper, for portaled content to tell whether its target is inside\n // it, and the caller's ref. A callback ref's cleanup is held and run on\n // detach, as Toast and Modal do, since React 18 discards the return value.\n const elementRef = useRef<HTMLDivElement | null>(null);\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const setElement = useCallback(\n (node: HTMLDivElement | null) => {\n elementRef.current = node;\n if (typeof ref === 'function') {\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) consumerCleanup();\n else ref(null);\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n\n return (\n <LocaleContext.Provider value={value}>\n <LocaleElementContext.Provider value={elementRef}>\n <div\n ref={setElement}\n className={classNames(bulmaHelperClasses, className) || undefined}\n {...rest}\n dir={dir}\n lang={locale}\n >\n {children}\n </div>\n </LocaleElementContext.Provider>\n </LocaleContext.Provider>\n );\n }\n);\n\nLocaleProvider.displayName = 'LocaleProvider';\n\n/** What `useLocale` returns outside a provider, the same object each time. */\nconst noLocale: LocaleContextValue = {};\n\n/**\n * The locale and direction the nearest `LocaleProvider` sets, for an app's own `Intl` calls or its own portaled content; both are `undefined` outside one.\n *\n * It isn't the page's direction: with no provider, or one that sets no\n * direction, the page's `<html dir>` still decides. To act on the direction\n * an element is laid out in, read `getComputedStyle(element).direction`, as\n * the library's components do.\n *\n * @function\n * @returns {LocaleContextValue} The nearest provider's `locale` and `dir`.\n *\n * @example\n * const { locale } = useLocale();\n * const price = new Intl.NumberFormat(locale, {\n * style: 'currency',\n * currency: 'EUR',\n * }).format(12.5);\n */\nexport function useLocale(): LocaleContextValue {\n return useContext(LocaleContext) ?? noLocale;\n}\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. The nearest\n * provider's settings, or `null` outside any provider, so a caller can tell\n * \"no provider\" from \"a provider that sets nothing\".\n */\nexport function useLocaleScope(): LocaleContextValue | null {\n return useContext(LocaleContext);\n}\n\nconst displayContents: React.CSSProperties = { display: 'contents' };\n\n/** The `dir` and `lang` portaled content carries: a provider's, or a picker's own. */\nexport interface PortalLocale {\n /** The `lang` to carry, unset for none. */\n locale?: string;\n /** The `dir` to carry, unset for none. */\n dir?: string;\n}\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. Keeps the `dir`\n * and `lang` of the nearest provider, or the `scope` given in their place,\n * on content the library portals into `target`, which has left the\n * provider's wrapper behind.\n *\n * A target inside the provider's own wrapper gets the content as it is: it\n * inherits from the wrapper, and follows it when the provider changes.\n * Content that must be its container's direct child, a `<tr>` portaled into\n * a `<tbody>` there, stays one. Any other target, `document.body` included,\n * gets the content inside a `display: contents` element carrying the\n * values, which adds no box. So does content with a `scope` of its own, a\n * picker's panel, since the provider's values aren't its own.\n *\n * Which of the two is decided once, when the content mounts, and kept while\n * it stays: switching between them would put a different element in its\n * place and remount everything inside, losing typed text, focus and timers.\n * A change of locale or direction updates the wrapper's attributes instead.\n * A target is never left bare because something else, such as `<html>`,\n * happens to carry the same values, since that can stop being true without\n * the content remounting. Outside a provider it renders the children alone,\n * so nothing changes there.\n */\nexport function LocalePortalScope({\n children,\n target,\n scope,\n}: {\n children: React.ReactNode;\n /** The element the content is portaled into. */\n target: Element;\n /** Values to carry in place of the provider's, such as a picker's own. */\n scope?: PortalLocale;\n}) {\n const provider = useContext(LocaleContext);\n const element = useContext(LocaleElementContext);\n const [wrap] = useState(\n () => scope !== undefined || !element?.current?.contains(target)\n );\n if (!provider || !wrap) return <>{children}</>;\n const values = scope ?? provider;\n return (\n <div dir={values.dir} lang={values.locale} style={displayContents}>\n {children}\n </div>\n );\n}\n"],"names":["_jsx","_Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
// INTERNAL: deliberately not exported from src/index.ts. What a locale says
|
|
3
|
+
// about its direction, read from `Intl.Locale` where the engine has the data,
|
|
4
|
+
// and about its week, read from a copy of CLDR's week data.
|
|
5
|
+
/**
|
|
6
|
+
* Scripts written right to left: every script for which ICU's text info
|
|
7
|
+
* says `rtl`, as Node reported it, and `Aran`, the Nastaliq form of Arabic
|
|
8
|
+
* that WebKit fills in for Urdu. Read only where the engine has no text info
|
|
9
|
+
* of its own, which includes Firefox before 153.
|
|
10
|
+
*/
|
|
11
|
+
const RTL_SCRIPTS = ' Adlm Arab Aran Armi Avst Chrs Cprt Elym Gara Hatr Hebr Hung Khar Lydi ' +
|
|
12
|
+
'Mand Mani Mend Merc Mero Narb Nbat Nkoo Orkh Ougr Palm Phli Phlp Phnx ' +
|
|
13
|
+
'Prti Rohg Samr Sarb Sidt Sogd Sogo Syrc Thaa Yezi ';
|
|
14
|
+
/**
|
|
15
|
+
* Widely used languages whose usual script reads right to left, for an engine
|
|
16
|
+
* that can't fill in a locale's script with `maximize()`.
|
|
17
|
+
*/
|
|
18
|
+
const RTL_LANGUAGES = ' ar ckb dv fa he iw ji ks mzn nqo pnb ps sd syr ug ur yi ';
|
|
19
|
+
/**
|
|
20
|
+
* The regions whose week doesn't start on Monday, by the day it starts on
|
|
21
|
+
* (0 = Sunday, 5 = Friday, 6 = Saturday), from CLDR 48's week data as Node
|
|
22
|
+
* reported it. The library reads this rather than `Intl.Locale`'s week info
|
|
23
|
+
* because engines disagree: Firefox before 153 has none, and WebKit's differs
|
|
24
|
+
* from Node's, Chromium's and current Firefox's for China, Algeria, Jordan and
|
|
25
|
+
* Iceland among others, so an inline calendar rendered on the server would
|
|
26
|
+
* fail to hydrate there. With one table, the server and every browser agree.
|
|
27
|
+
*/
|
|
28
|
+
const WEEK_STARTS = [
|
|
29
|
+
[
|
|
30
|
+
0,
|
|
31
|
+
' AG AS BD BR BS BT BU BW BZ CA CO DM DO ET GT GU HK HN ID IL IN IS JM JP ' +
|
|
32
|
+
'KE KH KR LA MH MM MO MT MX MZ NI NP PA PE PH PK PR PT PY RH SA SG SV TH ' +
|
|
33
|
+
'TT TW UM US VE VI WS YD YE ZA ZW ',
|
|
34
|
+
],
|
|
35
|
+
[5, ' MV '],
|
|
36
|
+
[6, ' AF BH DJ DZ EG IQ IR JO KW LY OM QA SD SY '],
|
|
37
|
+
];
|
|
38
|
+
/** Whether a space-separated list, padded with spaces, holds `code`. */
|
|
39
|
+
const listed = (list, code) => list.includes(` ${code} `);
|
|
40
|
+
/** The `-u-fw-` keyword's values, by the day they name. */
|
|
41
|
+
const FW_DAYS = {
|
|
42
|
+
sun: 0,
|
|
43
|
+
mon: 1,
|
|
44
|
+
tue: 2,
|
|
45
|
+
wed: 3,
|
|
46
|
+
thu: 4,
|
|
47
|
+
fri: 5,
|
|
48
|
+
sat: 6,
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* The canonical form of a BCP 47 tag (`"en-us"` becomes `"en-US"`), or
|
|
52
|
+
* `undefined` for an empty or missing one. Throws a `RangeError` for a tag
|
|
53
|
+
* `Intl` refuses, as `Intl.DateTimeFormat` would.
|
|
54
|
+
*/
|
|
55
|
+
function canonicalLocale(tag) {
|
|
56
|
+
if (!tag)
|
|
57
|
+
return undefined;
|
|
58
|
+
return Intl.getCanonicalLocales(tag)[0];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The direction a locale's script is written in: from `Intl.Locale`'s text
|
|
62
|
+
* info, else from the script `maximize()` fills in, else from the language.
|
|
63
|
+
*
|
|
64
|
+
* @param locale - A canonical tag, as `canonicalLocale` returns.
|
|
65
|
+
*/
|
|
66
|
+
function localeDirection(locale) {
|
|
67
|
+
const intlLocale = new Intl.Locale(locale);
|
|
68
|
+
const info = intlLocale;
|
|
69
|
+
const direction = typeof info.getTextInfo === 'function'
|
|
70
|
+
? info.getTextInfo().direction
|
|
71
|
+
: info.textInfo?.direction;
|
|
72
|
+
if (direction === 'rtl' || direction === 'ltr')
|
|
73
|
+
return direction;
|
|
74
|
+
if (typeof intlLocale.maximize === 'function') {
|
|
75
|
+
const script = intlLocale.maximize().script;
|
|
76
|
+
return script && listed(RTL_SCRIPTS, script) ? 'rtl' : 'ltr';
|
|
77
|
+
}
|
|
78
|
+
return listed(RTL_LANGUAGES, intlLocale.language) ? 'rtl' : 'ltr';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The day a locale's week starts on, 0 for Sunday, as `getWeekInfo()` reads
|
|
82
|
+
* it: the tag's `-u-fw-` keyword, else the region its `-u-rg-` keyword names,
|
|
83
|
+
* else its own region or the one `maximize()` fills in, looked up in CLDR's
|
|
84
|
+
* week data, where a region not listed starts on Monday.
|
|
85
|
+
*
|
|
86
|
+
* @param locale - A canonical tag, as `canonicalLocale` returns.
|
|
87
|
+
*/
|
|
88
|
+
function localeFirstDay(locale) {
|
|
89
|
+
const fw = /-u(?:-[a-z0-9]{2,8})*?-fw-([a-z]{3})(?=-|$)/i.exec(locale);
|
|
90
|
+
if (fw && fw[1].toLowerCase() in FW_DAYS)
|
|
91
|
+
return FW_DAYS[fw[1].toLowerCase()];
|
|
92
|
+
const rg = /-u(?:-[a-z0-9]{2,8})*?-rg-([a-z]{2})[a-z0-9]{1,4}(?=-|$)/i.exec(locale);
|
|
93
|
+
const intlLocale = new Intl.Locale(locale);
|
|
94
|
+
const region = rg
|
|
95
|
+
? rg[1].toUpperCase()
|
|
96
|
+
: typeof intlLocale.maximize === 'function'
|
|
97
|
+
? intlLocale.maximize().region
|
|
98
|
+
: intlLocale.region;
|
|
99
|
+
if (region) {
|
|
100
|
+
for (const [day, regions] of WEEK_STARTS) {
|
|
101
|
+
if (listed(regions, region))
|
|
102
|
+
return day;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export { canonicalLocale, localeDirection, localeFirstDay };
|
|
109
|
+
//# sourceMappingURL=localeInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localeInfo.js","sources":["../../../src/helpers/localeInfo.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts. What a locale says\n// about its direction, read from `Intl.Locale` where the engine has the data,\n// and about its week, read from a copy of CLDR's week data.\n\nimport type { DayOfWeek } from '../form/_pickerInternals/pickerTypes';\n\n/** The parts of `Intl.Locale` newer than the ES2020 library types. */\ninterface LocaleInfo {\n getTextInfo?: () => { direction?: string };\n textInfo?: { direction?: string };\n}\n\n/**\n * Scripts written right to left: every script for which ICU's text info\n * says `rtl`, as Node reported it, and `Aran`, the Nastaliq form of Arabic\n * that WebKit fills in for Urdu. Read only where the engine has no text info\n * of its own, which includes Firefox before 153.\n */\nconst RTL_SCRIPTS =\n ' Adlm Arab Aran Armi Avst Chrs Cprt Elym Gara Hatr Hebr Hung Khar Lydi ' +\n 'Mand Mani Mend Merc Mero Narb Nbat Nkoo Orkh Ougr Palm Phli Phlp Phnx ' +\n 'Prti Rohg Samr Sarb Sidt Sogd Sogo Syrc Thaa Yezi ';\n\n/**\n * Widely used languages whose usual script reads right to left, for an engine\n * that can't fill in a locale's script with `maximize()`.\n */\nconst RTL_LANGUAGES =\n ' ar ckb dv fa he iw ji ks mzn nqo pnb ps sd syr ug ur yi ';\n\n/**\n * The regions whose week doesn't start on Monday, by the day it starts on\n * (0 = Sunday, 5 = Friday, 6 = Saturday), from CLDR 48's week data as Node\n * reported it. The library reads this rather than `Intl.Locale`'s week info\n * because engines disagree: Firefox before 153 has none, and WebKit's differs\n * from Node's, Chromium's and current Firefox's for China, Algeria, Jordan and\n * Iceland among others, so an inline calendar rendered on the server would\n * fail to hydrate there. With one table, the server and every browser agree.\n */\nconst WEEK_STARTS: ReadonlyArray<readonly [DayOfWeek, string]> = [\n [\n 0,\n ' AG AS BD BR BS BT BU BW BZ CA CO DM DO ET GT GU HK HN ID IL IN IS JM JP ' +\n 'KE KH KR LA MH MM MO MT MX MZ NI NP PA PE PH PK PR PT PY RH SA SG SV TH ' +\n 'TT TW UM US VE VI WS YD YE ZA ZW ',\n ],\n [5, ' MV '],\n [6, ' AF BH DJ DZ EG IQ IR JO KW LY OM QA SD SY '],\n];\n\n/** Whether a space-separated list, padded with spaces, holds `code`. */\nconst listed = (list: string, code: string) => list.includes(` ${code} `);\n\n/** The `-u-fw-` keyword's values, by the day they name. */\nconst FW_DAYS: Record<string, DayOfWeek> = {\n sun: 0,\n mon: 1,\n tue: 2,\n wed: 3,\n thu: 4,\n fri: 5,\n sat: 6,\n};\n\n/**\n * The canonical form of a BCP 47 tag (`\"en-us\"` becomes `\"en-US\"`), or\n * `undefined` for an empty or missing one. Throws a `RangeError` for a tag\n * `Intl` refuses, as `Intl.DateTimeFormat` would.\n */\nexport function canonicalLocale(tag: string | undefined): string | undefined {\n if (!tag) return undefined;\n return Intl.getCanonicalLocales(tag)[0];\n}\n\n/**\n * The direction a locale's script is written in: from `Intl.Locale`'s text\n * info, else from the script `maximize()` fills in, else from the language.\n *\n * @param locale - A canonical tag, as `canonicalLocale` returns.\n */\nexport function localeDirection(locale: string): 'ltr' | 'rtl' {\n const intlLocale = new Intl.Locale(locale);\n const info = intlLocale as unknown as LocaleInfo;\n const direction =\n typeof info.getTextInfo === 'function'\n ? info.getTextInfo().direction\n : info.textInfo?.direction;\n if (direction === 'rtl' || direction === 'ltr') return direction;\n if (typeof intlLocale.maximize === 'function') {\n const script = intlLocale.maximize().script;\n return script && listed(RTL_SCRIPTS, script) ? 'rtl' : 'ltr';\n }\n return listed(RTL_LANGUAGES, intlLocale.language) ? 'rtl' : 'ltr';\n}\n\n/**\n * The day a locale's week starts on, 0 for Sunday, as `getWeekInfo()` reads\n * it: the tag's `-u-fw-` keyword, else the region its `-u-rg-` keyword names,\n * else its own region or the one `maximize()` fills in, looked up in CLDR's\n * week data, where a region not listed starts on Monday.\n *\n * @param locale - A canonical tag, as `canonicalLocale` returns.\n */\nexport function localeFirstDay(locale: string): DayOfWeek {\n const fw = /-u(?:-[a-z0-9]{2,8})*?-fw-([a-z]{3})(?=-|$)/i.exec(locale);\n if (fw && fw[1].toLowerCase() in FW_DAYS) return FW_DAYS[fw[1].toLowerCase()];\n const rg = /-u(?:-[a-z0-9]{2,8})*?-rg-([a-z]{2})[a-z0-9]{1,4}(?=-|$)/i.exec(\n locale\n );\n const intlLocale = new Intl.Locale(locale);\n const region = rg\n ? rg[1].toUpperCase()\n : typeof intlLocale.maximize === 'function'\n ? intlLocale.maximize().region\n : intlLocale.region;\n if (region) {\n for (const [day, regions] of WEEK_STARTS) {\n if (listed(regions, region)) return day;\n }\n }\n return 1;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { jsx, Fragment } from 'react/jsx-runtime';
|
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import { useIsHydrated } from './useIsHydrated.js';
|
|
5
5
|
import { useConfig } from './Config.js';
|
|
6
|
+
import { LocalePortalScope } from './LocaleProvider.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Resolves a portal target: an `HTMLElement` is used directly, a non-empty
|
|
@@ -65,6 +66,17 @@ function usePortalContainer() {
|
|
|
65
66
|
* also reaches what the library's components portal, such as Popover's
|
|
66
67
|
* `appendToBody` panel or a `Modal` with `portal`.
|
|
67
68
|
*
|
|
69
|
+
* Inside a `LocaleProvider`, the children keep its `dir` and `lang`. A
|
|
70
|
+
* container inside the provider's own wrapper takes the children as they
|
|
71
|
+
* are, and they follow the provider through the page. Any other,
|
|
72
|
+
* `document.body` included, gets them inside one `<div>` carrying the
|
|
73
|
+
* provider's values, with `display: contents` so it adds no box. It is
|
|
74
|
+
* still an element, so content that must be the container's direct child,
|
|
75
|
+
* a `<tr>` in a `<tbody>`, or that a direct-child selector styles, belongs
|
|
76
|
+
* in a container inside the provider. Which of the two is settled when the
|
|
77
|
+
* children mount, so a change of locale updates them in place rather than
|
|
78
|
+
* remounting them.
|
|
79
|
+
*
|
|
68
80
|
* Tab order and focus follow the DOM too. Content portaled from inside a
|
|
69
81
|
* focus trap is no longer inside the trapped element, so the trap neither
|
|
70
82
|
* reaches it nor holds focus there: render nested overlays inside the
|
|
@@ -94,7 +106,8 @@ function Portal({ children, container, disabled = false }) {
|
|
|
94
106
|
return jsx(Fragment, { children: children });
|
|
95
107
|
if (!hydrated)
|
|
96
108
|
return null;
|
|
97
|
-
|
|
109
|
+
const target = resolveContainer(container);
|
|
110
|
+
return createPortal(jsx(LocalePortalScope, { target: target, children: children }), target);
|
|
98
111
|
}
|
|
99
112
|
|
|
100
113
|
export { Portal, resolvePortalContainer, usePortalContainer };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sources":["../../../src/helpers/portal.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIsHydrated } from './useIsHydrated';\nimport { useConfig } from './Config';\n\n/**\n * Resolves a portal target: an `HTMLElement` is used directly, a non-empty\n * `string` is treated as a `document.querySelector` selector (falling back to\n * `document.body` when it matches nothing), and any falsy value — `undefined`\n * or the empty string — resolves to `document.body`.\n *\n * The empty string is deliberately treated as \"no target\" rather than passed\n * through: `document.querySelector('')` throws a `SyntaxError`, and callers\n * building a selector from state can easily hand us `''`.\n *\n * @function resolvePortalContainer\n * @param container - The requested portal target, if any.\n * @returns The resolved DOM node to portal into.\n */\nexport function resolvePortalContainer(\n container?: string | HTMLElement\n): HTMLElement {\n if (!container) {\n return document.body;\n }\n if (typeof container === 'string') {\n return (\n (document.querySelector(container) as HTMLElement | null) ?? document.body\n );\n }\n return container;\n}\n\n/**\n * Where a component's portal goes, as a function to call when the portal is\n * created: the target the component was given, else the `portalContainer` a\n * `ConfigProvider` sets, else `document.body`, each read as\n * `resolvePortalContainer` reads it. A component that portals resolves its\n * target through this, so the provider's default reaches it.\n *\n * The hook only reads context, so it is safe to call on the server, ahead of\n * any early return. The function it returns reads the DOM, so call it only\n * where the portal is created, which the server never reaches.\n *\n * @function usePortalContainer\n * @returns A function that takes the component's own target, if any, and\n * returns the DOM node to portal into.\n */\nexport function usePortalContainer(): (\n container?: string | HTMLElement\n) => HTMLElement {\n const { portalContainer } = useConfig();\n return container => resolvePortalContainer(container || portalContainer);\n}\n\n/**\n * Props for the Portal component.\n */\nexport interface PortalProps {\n /** Content to render into the container. */\n children?: React.ReactNode;\n /**\n * Where the content goes: an element, or a `document.querySelector`\n * selector. Omitted or empty, it goes to the `portalContainer` a\n * `ConfigProvider` sets, and to `document.body` when none is set. A\n * selector that matches nothing means `document.body` too. A selector is\n * looked up again on each render, so the\n * content follows the target when it changes. Moving to another target\n * remounts the children and resets their state, which includes a selector\n * that only starts matching after the content has shown in `document.body`.\n * Render the target first, or pass the element once you have it.\n */\n container?: string | HTMLElement;\n /**\n * Render the children in place instead, on the server as well as the\n * client. Lets a component that portals only sometimes keep a single code\n * path.\n * @defaultValue false\n */\n disabled?: boolean;\n}\n\n/**\n * Renders its children into another part of the page, `document.body` unless `container` or a `ConfigProvider` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.\n *\n * React's server renderer can't render a portal, so `Portal` renders nothing\n * on the server and during hydration, and mounts its children in the commit\n * that follows. The first client render then matches the server markup. In an app\n * without server rendering it portals on the first render.\n *\n * React context, such as `ConfigProvider`'s class prefix, reaches the\n * portaled children, and their React events bubble through the React tree.\n * CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`\n * sets its variables on a wrapper element the portaled content has left, so\n * that content sees the page-level theme, and styles scoped to a shadow root\n * don't reach `document.body` at all. To keep them, portal into an element\n * inside the themed area or the shadow root: pass it as `container`, or as\n * the `portalContainer` of a `ConfigProvider` around that area. The second\n * also reaches what the library's components portal, such as Popover's\n * `appendToBody` panel or a `Modal` with `portal`.\n *\n * Tab order and focus follow the DOM too. Content portaled from inside a\n * focus trap is no longer inside the trapped element, so the trap neither\n * reaches it nor holds focus there: render nested overlays inside the\n * trapped element, or give them a trap of their own. To trap portaled\n * content, put `useFocusTrap`'s ref on the element inside the `Portal`.\n *\n * @function\n * @param {PortalProps} props - Props for the Portal component.\n * @returns The portal, the children in place when `disabled`, or nothing\n * before hydration.\n *\n * @example\n * <Portal>\n * <div className=\"box\">Rendered at the end of document.body</div>\n * </Portal>\n *\n * @example\n * // Into a dedicated overlay root\n * <Portal container=\"#overlays\">\n * <CommandPalette />\n * </Portal>\n */\nexport function Portal({ children, container, disabled = false }: PortalProps) {\n const hydrated = useIsHydrated();\n const resolveContainer = usePortalContainer();\n if (disabled) return <>{children}</>;\n if (!hydrated) return null;\n
|
|
1
|
+
{"version":3,"file":"portal.js","sources":["../../../src/helpers/portal.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIsHydrated } from './useIsHydrated';\nimport { useConfig } from './Config';\nimport { LocalePortalScope } from './LocaleProvider';\n\n/**\n * Resolves a portal target: an `HTMLElement` is used directly, a non-empty\n * `string` is treated as a `document.querySelector` selector (falling back to\n * `document.body` when it matches nothing), and any falsy value — `undefined`\n * or the empty string — resolves to `document.body`.\n *\n * The empty string is deliberately treated as \"no target\" rather than passed\n * through: `document.querySelector('')` throws a `SyntaxError`, and callers\n * building a selector from state can easily hand us `''`.\n *\n * @function resolvePortalContainer\n * @param container - The requested portal target, if any.\n * @returns The resolved DOM node to portal into.\n */\nexport function resolvePortalContainer(\n container?: string | HTMLElement\n): HTMLElement {\n if (!container) {\n return document.body;\n }\n if (typeof container === 'string') {\n return (\n (document.querySelector(container) as HTMLElement | null) ?? document.body\n );\n }\n return container;\n}\n\n/**\n * Where a component's portal goes, as a function to call when the portal is\n * created: the target the component was given, else the `portalContainer` a\n * `ConfigProvider` sets, else `document.body`, each read as\n * `resolvePortalContainer` reads it. A component that portals resolves its\n * target through this, so the provider's default reaches it.\n *\n * The hook only reads context, so it is safe to call on the server, ahead of\n * any early return. The function it returns reads the DOM, so call it only\n * where the portal is created, which the server never reaches.\n *\n * @function usePortalContainer\n * @returns A function that takes the component's own target, if any, and\n * returns the DOM node to portal into.\n */\nexport function usePortalContainer(): (\n container?: string | HTMLElement\n) => HTMLElement {\n const { portalContainer } = useConfig();\n return container => resolvePortalContainer(container || portalContainer);\n}\n\n/**\n * Props for the Portal component.\n */\nexport interface PortalProps {\n /** Content to render into the container. */\n children?: React.ReactNode;\n /**\n * Where the content goes: an element, or a `document.querySelector`\n * selector. Omitted or empty, it goes to the `portalContainer` a\n * `ConfigProvider` sets, and to `document.body` when none is set. A\n * selector that matches nothing means `document.body` too. A selector is\n * looked up again on each render, so the\n * content follows the target when it changes. Moving to another target\n * remounts the children and resets their state, which includes a selector\n * that only starts matching after the content has shown in `document.body`.\n * Render the target first, or pass the element once you have it.\n */\n container?: string | HTMLElement;\n /**\n * Render the children in place instead, on the server as well as the\n * client. Lets a component that portals only sometimes keep a single code\n * path.\n * @defaultValue false\n */\n disabled?: boolean;\n}\n\n/**\n * Renders its children into another part of the page, `document.body` unless `container` or a `ConfigProvider` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.\n *\n * React's server renderer can't render a portal, so `Portal` renders nothing\n * on the server and during hydration, and mounts its children in the commit\n * that follows. The first client render then matches the server markup. In an app\n * without server rendering it portals on the first render.\n *\n * React context, such as `ConfigProvider`'s class prefix, reaches the\n * portaled children, and their React events bubble through the React tree.\n * CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`\n * sets its variables on a wrapper element the portaled content has left, so\n * that content sees the page-level theme, and styles scoped to a shadow root\n * don't reach `document.body` at all. To keep them, portal into an element\n * inside the themed area or the shadow root: pass it as `container`, or as\n * the `portalContainer` of a `ConfigProvider` around that area. The second\n * also reaches what the library's components portal, such as Popover's\n * `appendToBody` panel or a `Modal` with `portal`.\n *\n * Inside a `LocaleProvider`, the children keep its `dir` and `lang`. A\n * container inside the provider's own wrapper takes the children as they\n * are, and they follow the provider through the page. Any other,\n * `document.body` included, gets them inside one `<div>` carrying the\n * provider's values, with `display: contents` so it adds no box. It is\n * still an element, so content that must be the container's direct child,\n * a `<tr>` in a `<tbody>`, or that a direct-child selector styles, belongs\n * in a container inside the provider. Which of the two is settled when the\n * children mount, so a change of locale updates them in place rather than\n * remounting them.\n *\n * Tab order and focus follow the DOM too. Content portaled from inside a\n * focus trap is no longer inside the trapped element, so the trap neither\n * reaches it nor holds focus there: render nested overlays inside the\n * trapped element, or give them a trap of their own. To trap portaled\n * content, put `useFocusTrap`'s ref on the element inside the `Portal`.\n *\n * @function\n * @param {PortalProps} props - Props for the Portal component.\n * @returns The portal, the children in place when `disabled`, or nothing\n * before hydration.\n *\n * @example\n * <Portal>\n * <div className=\"box\">Rendered at the end of document.body</div>\n * </Portal>\n *\n * @example\n * // Into a dedicated overlay root\n * <Portal container=\"#overlays\">\n * <CommandPalette />\n * </Portal>\n */\nexport function Portal({ children, container, disabled = false }: PortalProps) {\n const hydrated = useIsHydrated();\n const resolveContainer = usePortalContainer();\n if (disabled) return <>{children}</>;\n if (!hydrated) return null;\n const target = resolveContainer(container);\n return createPortal(\n <LocalePortalScope target={target}>{children}</LocalePortalScope>,\n target\n );\n}\n"],"names":["_jsx","_Fragment"],"mappings":";;;;;;;AAMA;;;;;;;;;;;;;AAaG;AACG,SAAU,sBAAsB,CACpC,SAAgC,EAAA;IAEhC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,QAAQ,CAAC,IAAI;IACtB;AACA,IAAA,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;AACjC,QAAA,QACG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAwB,IAAI,QAAQ,CAAC,IAAI;IAE9E;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;;;;;;;;;;;;;;AAcG;SACa,kBAAkB,GAAA;AAGhC,IAAA,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE;IACvC,OAAO,SAAS,IAAI,sBAAsB,CAAC,SAAS,IAAI,eAAe,CAAC;AAC1E;AA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDG;AACG,SAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,EAAe,EAAA;AAC3E,IAAA,MAAM,QAAQ,GAAG,aAAa,EAAE;AAChC,IAAA,MAAM,gBAAgB,GAAG,kBAAkB,EAAE;AAC7C,IAAA,IAAI,QAAQ;QAAE,OAAOA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAI;AACpC,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,IAAI;AAC1B,IAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC;AAC1C,IAAA,OAAO,YAAY,CACjBD,GAAA,CAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAqB,EACjE,MAAM,CACP;AACH;;"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
2
|
import { useId, useCallback, useRef, useState, useReducer, useEffect } from 'react';
|
|
3
3
|
import { useClientLayoutEffect } from './useClientLayoutEffect.js';
|
|
4
|
-
import {
|
|
4
|
+
import { getActiveElementInTree, isEventInside } from './shadowDom.js';
|
|
5
5
|
|
|
6
6
|
// INTERNAL: deliberately not exported from src/index.ts.
|
|
7
7
|
/** An IME is composing, so the key belongs to it (`keyCode` 229 is Safari's word for it). */
|
|
8
|
-
const isComposing$
|
|
8
|
+
const isComposing$2 = (event) => event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229;
|
|
9
9
|
const sameValues = (a, b) => a.length === b.length && a.every((value, i) => value === b[i]);
|
|
10
10
|
/**
|
|
11
11
|
* The keys, the open state, the highlight and the ARIA of an editable
|
|
@@ -179,7 +179,7 @@ function useComboboxEngine({ open: controlledOpen, defaultOpen, onOpenChange, on
|
|
|
179
179
|
const onKeyDown = (event) => {
|
|
180
180
|
// The caller's handler ran first and can keep a key, and an IME that's
|
|
181
181
|
// composing owns every key.
|
|
182
|
-
if (event.defaultPrevented || isComposing$
|
|
182
|
+
if (event.defaultPrevented || isComposing$2(event))
|
|
183
183
|
return;
|
|
184
184
|
const { key, altKey } = event;
|
|
185
185
|
if (!open) {
|
|
@@ -94,7 +94,7 @@ function flatChildren(el) {
|
|
|
94
94
|
}
|
|
95
95
|
return Array.from(el.children);
|
|
96
96
|
}
|
|
97
|
-
const isShown = (el) => !el.hasAttribute('inert') && getComputedStyle(el).display !== 'none';
|
|
97
|
+
const isShown$1 = (el) => !el.hasAttribute('inert') && getComputedStyle(el).display !== 'none';
|
|
98
98
|
const isVisible = (el) => {
|
|
99
99
|
const { visibility } = getComputedStyle(el);
|
|
100
100
|
return visibility !== 'hidden' && visibility !== 'collapse';
|
|
@@ -108,7 +108,7 @@ const isVisible = (el) => {
|
|
|
108
108
|
function isShownUpTo(el, top) {
|
|
109
109
|
let below = null;
|
|
110
110
|
for (let node = el; node && node !== top; node = flatParent(node)) {
|
|
111
|
-
if (!isShown(node))
|
|
111
|
+
if (!isShown$1(node))
|
|
112
112
|
return false;
|
|
113
113
|
if (below &&
|
|
114
114
|
node.localName === 'details' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFocusTrap.js","sources":["../../../src/helpers/useFocusTrap.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\nimport { useIsHydrated } from './useIsHydrated';\nimport { getDeepestActiveElement } from './shadowDom';\n\n/**\n * Whether `el` is editable while its parent is not, which makes it an editing\n * host: the one tab stop an editable region gets. `contenteditable=\"false\"`\n * turns editing off, and a missing or unknown value inherits the parent's.\n */\nfunction isEditingHost(el: Element): boolean {\n const editable = (node: Element): boolean | null => {\n const value = node.getAttribute('contenteditable')?.toLowerCase();\n if (value === undefined) return null;\n if (value === '' || value === 'true' || value === 'plaintext-only') {\n return true;\n }\n return value === 'false' ? false : null;\n };\n if (editable(el) !== true) return false;\n for (let node = el.parentElement; node; node = node.parentElement) {\n const state = editable(node);\n if (state !== null) return !state;\n }\n return true;\n}\n\n/** Whether `el` is the summary of its `<details>`: the first one, not a stray. */\nconst isDetailsSummary = (el: Element): boolean =>\n el.parentElement?.localName === 'details' &&\n Array.from(el.parentElement.children).find(\n child => child.localName === 'summary'\n ) === el;\n\n/**\n * Whether the browser puts `el` in the tab order, before anything that hides\n * or disables it. The `tabIndex` property can't answer this on its own: it\n * can read `-1` for an editable region or an `<embed>` that Tab still visits,\n * and `0` for a `<video>` without controls that it doesn't. So a valid\n * `tabindex` attribute decides, and otherwise the element's kind does.\n * Internal like `focusTabStop`: `src/index.ts` names what it takes from here.\n */\nexport function isTabbableKind(el: Element): boolean {\n const tabindex = el.getAttribute('tabindex');\n if (tabindex !== null && /^\\s*[+-]?\\d/.test(tabindex)) {\n return (el as HTMLElement).tabIndex >= 0;\n }\n switch (el.localName) {\n case 'a':\n case 'area':\n return el.hasAttribute('href');\n case 'input':\n return (el as HTMLInputElement).type !== 'hidden';\n case 'button':\n case 'select':\n case 'textarea':\n case 'iframe':\n case 'embed':\n case 'object':\n return true;\n case 'audio':\n case 'video':\n return el.hasAttribute('controls');\n case 'summary':\n return isDetailsSummary(el);\n default:\n return isEditingHost(el);\n }\n}\n\n/**\n * The node's parent in the flattened tree, the one the browser renders and\n * tabs through: the slot it is assigned to, else its parent, else the host of\n * the shadow root it tops, and nothing above the document. A closed shadow\n * root hides its slots (`assignedSlot` reads `null` under one), so a child of\n * its host goes straight to the host, whether a slot takes it or not.\n */\nconst flatParent = (node: Node): Node | null =>\n (node as Element).assignedSlot ??\n node.parentElement ??\n (node.parentNode as ShadowRoot | null)?.host ??\n null;\n\n/**\n * The element's children in the flattened tree, in the order they render: a\n * host's shadow root content, a slot's assigned elements (or its fallback\n * content when nothing is assigned), anything else's own children. A host\n * whose shadow root is closed has no root to read, so its own children stand\n * in, including any that no slot takes and that aren't rendered.\n */\nfunction flatChildren(el: Element): Element[] {\n if (el.shadowRoot) return Array.from(el.shadowRoot.children);\n if (el.localName === 'slot') {\n const assigned = (el as HTMLSlotElement).assignedNodes();\n if (assigned.length > 0) {\n return assigned.filter(\n (node): node is Element => node.nodeType === Node.ELEMENT_NODE\n );\n }\n }\n return Array.from(el.children);\n}\n\nconst isShown = (el: Element): boolean =>\n !el.hasAttribute('inert') && getComputedStyle(el).display !== 'none';\n\nconst isVisible = (el: Element): boolean => {\n const { visibility } = getComputedStyle(el);\n return visibility !== 'hidden' && visibility !== 'collapse';\n};\n\n/**\n * Whether nothing from `el` up to `top` hides it: `inert`, `display: none`\n * (not inherited, so each element is checked) or a closed `<details>` it\n * isn't the summary of. `top` itself isn't checked, and `null` walks to the\n * top of the page.\n */\nfunction isShownUpTo(el: Element, top: Node | null): boolean {\n let below: Element | null = null;\n for (\n let node: Element | null = el;\n node && node !== top;\n node = flatParent(node) as Element | null\n ) {\n if (!isShown(node)) return false;\n if (\n below &&\n node.localName === 'details' &&\n !node.hasAttribute('open') &&\n !isDetailsSummary(below)\n ) {\n return false;\n }\n below = node;\n }\n return true;\n}\n\n/**\n * The images that use the image map `area` belongs to. An image names its\n * map with `usemap=\"#…\"`, matching the map's `name` or `id`.\n */\nfunction imagesUsingMapOf(area: Element): Element[] {\n const map = area.closest('map');\n if (!map) return [];\n const names = [map.getAttribute('name'), map.id].filter(name => name);\n return Array.from(\n (area.getRootNode() as ParentNode).querySelectorAll('img[usemap]')\n ).filter(img => {\n const ref = img.getAttribute('usemap') as string;\n return ref.startsWith('#') && names.includes(ref.slice(1));\n });\n}\n\n/**\n * Whether an image map area is shown. An area has no box of its own: the\n * HTML rendering rules give it `display: none`, though a browser may not\n * report that. So it counts where an image using its map is shown, as long\n * as nothing makes it inert.\n */\nfunction isAreaShown(area: Element, container: Element): boolean {\n for (\n let node: Element | null = area;\n node && node !== container;\n node = flatParent(node) as Element | null\n ) {\n if (node.hasAttribute('inert')) return false;\n }\n return imagesUsingMapOf(area).some(\n img => isShownUpTo(img, null) && isVisible(img)\n );\n}\n\n/**\n * Whether Tab can land on `el`, one of the kinds it visits. A disabled control\n * (including one inside a disabled `<fieldset>`), an inert subtree and\n * anything not rendered are skipped. `visibility` is inherited, so the\n * element's own computed value covers its ancestors.\n */\nfunction isRenderedAndEnabled(el: Element, container: Element): boolean {\n if (el.matches(':disabled')) return false;\n if (el.localName === 'area') return isAreaShown(el, container);\n return isShownUpTo(el, container) && isVisible(el);\n}\n\n/** A radio button with a name, which shares one tab stop with its group. */\nconst isGroupedRadio = (el: Element): el is HTMLInputElement =>\n el.localName === 'input' &&\n (el as HTMLInputElement).type === 'radio' &&\n (el as HTMLInputElement).name !== '';\n\n/** Whether two radio buttons are in one group: same name, form owner and tree. */\nconst sameGroup = (a: HTMLInputElement, b: Element): b is HTMLInputElement =>\n isGroupedRadio(b) &&\n b.name === a.name &&\n b.form === a.form &&\n b.getRootNode() === a.getRootNode();\n\n/**\n * The checked button of `radio`'s group. The group isn't bounded by the trap,\n * so this looks through the radio's whole tree.\n */\nconst checkedInGroup = (radio: HTMLInputElement): Element | undefined =>\n Array.from(\n (radio.getRootNode() as ParentNode).querySelectorAll('input:checked')\n ).find(el => sameGroup(radio, el));\n\n/** The flattened-tree ancestors of `node` below the container, outermost first, then `node`. */\nfunction flatChain(node: Node, container: Node): Node[] {\n const chain: Node[] = [];\n for (let n: Node | null = node; n && n !== container; n = flatParent(n)) {\n chain.unshift(n);\n }\n return chain;\n}\n\n/**\n * Whether `node` is inside the container in the flattened tree: in it, in a\n * shadow root it holds, or slotted into it. A child of a closed-root host\n * counts as inside wherever the host is, as its slot can't be seen.\n */\nfunction inside(container: Node, node: Node): boolean {\n for (let n: Node | null = node; n; n = flatParent(n)) {\n if (n === container) return true;\n }\n return false;\n}\n\n/**\n * `true` when Tab reaches `b` after `a`, which is their order in the\n * flattened tree: a shadow host comes before its shadow root's content, and\n * slotted content comes where its slot is. A closed root's slots can't be\n * seen, so its host's children keep their place in the light DOM. Two\n * flattened-tree siblings are always in one DOM tree, so their document\n * position decides between them.\n */\nfunction follows(container: Element, a: Node, b: Node): boolean {\n const chainA = flatChain(a, container);\n const chainB = flatChain(b, container);\n for (let i = 0; i < Math.max(chainA.length, chainB.length); i++) {\n const [x, y] = [chainA[i], chainB[i]];\n if (x === y) continue;\n if (!x) return true;\n if (!y) return false;\n return Boolean(\n x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING\n );\n }\n return false;\n}\n\n/**\n * Every element of a tabbable kind under `el` in the flattened tree, depth\n * first, which is the order Tab visits them. Under a host whose shadow root\n * is closed, that takes in the host's own children instead, rendered or not.\n */\nfunction collectCandidates(\n el: Element,\n out: HTMLElement[] = []\n): HTMLElement[] {\n for (const child of flatChildren(el)) {\n if (isTabbableKind(child)) out.push(child as HTMLElement);\n collectCandidates(child, out);\n }\n return out;\n}\n\ninterface TabStops {\n first: HTMLElement;\n last: HTMLElement;\n /** The stop that stands for `node`: its group's stop for a radio button. */\n stopFor(node: Element): Element;\n /** The stops from one end inward, the last first when `fromLast`. */\n from(fromLast: boolean): Generator<HTMLElement>;\n}\n\n/**\n * The first and last tab stops inside `container`, or `null` when there are\n * none. Only the ends matter for wrapping, so the style checks run from each\n * end until they find a stop rather than over every candidate.\n *\n * A radio group is one stop, the way the browser treats it: its checked\n * button, or its first when none is checked. Counting every button would make\n * the group's last one an end, and Tab from the checked one would leave. The\n * group goes by name, form owner and tree, not by the trap, so a checked\n * button outside the container that Tab can land on leaves the group no stop\n * inside. One that Tab can't land on leaves the group as if none were checked.\n */\nfunction findTabStops(container: HTMLElement): TabStops | null {\n const candidates = collectCandidates(container);\n const checked = new Map<Element, boolean>();\n const usable = (el: Element): boolean => {\n let ok = checked.get(el);\n if (ok === undefined) {\n ok = isRenderedAndEnabled(el, container);\n checked.set(el, ok);\n }\n return ok;\n };\n // Resolved once per group, filed under each of its buttons, since finding\n // the checked one scans the radio's whole tree.\n const groupStops = new Map<Element, HTMLElement | undefined>();\n const groupStop = (radio: HTMLInputElement): HTMLElement | undefined => {\n if (groupStops.has(radio)) return groupStops.get(radio);\n const group = candidates.filter(el => sameGroup(radio, el));\n const on = checkedInGroup(radio);\n const stop =\n on && isTabbableKind(on) && usable(on)\n ? group.find(el => el === on)\n : group.find(usable);\n for (const el of [radio, ...group]) groupStops.set(el, stop);\n return stop;\n };\n const isStop = (el: HTMLElement): boolean =>\n usable(el) && (!isGroupedRadio(el) || groupStop(el) === el);\n // Checked only as they're reached, and the checks are kept, so finding\n // both ends costs what it did when only the ends were looked for.\n function* from(fromLast: boolean): Generator<HTMLElement> {\n for (let i = 0; i < candidates.length; i++) {\n const el = candidates[fromLast ? candidates.length - 1 - i : i];\n if (isStop(el)) yield el;\n }\n }\n\n const first = from(false).next().value;\n if (!first) return null;\n return {\n first,\n last: from(true).next().value as HTMLElement,\n stopFor: node => (isGroupedRadio(node) && groupStop(node)) || node,\n from,\n };\n}\n\n/**\n * The element that has focus in the container's own document (an iframe's,\n * when it renders into one), inside open shadow roots too. Focus inside a\n * closed one reads as its host, which the comparisons above place like any\n * other element. Browsers fall back to <body> when nothing has\n * focus. jsdom, where consumers run their tests, reports nothing once focus\n * was inside a shadow root that was removed, so this falls back for it.\n */\nconst focusedElement = (doc: Document): Element =>\n getDeepestActiveElement(doc) ?? doc.body;\n\n/**\n * Moves focus to the first tab stop inside `container`, or the last when\n * `fromLast`, and to the container when there is none. Every move a trap\n * makes goes through here: into the container as it opens, to the other end\n * on a wrap, and back in after a Tab the browser carried out.\n *\n * A stop that doesn't take focus is passed over for the next one in. An\n * `<object>` or `<embed>` with nothing to show is one: it counts as a stop by\n * its kind, but browsers refuse to focus it, and which ones they refuse\n * depends on the browser and on what has loaded, so only trying tells. A\n * stop took focus when focus moved, wherever it went (a stop can hand focus\n * on), or when focus was on it already. `src/index.ts` names its exports from\n * this module, so this one stays internal.\n */\nexport function focusTabStop(container: HTMLElement, fromLast = false): void {\n const doc = container.ownerDocument;\n for (const stop of findTabStops(container)?.from(fromLast) ?? []) {\n const before = focusedElement(doc);\n stop.focus();\n const now = focusedElement(doc);\n if (now !== before || inside(stop, now)) return;\n }\n container.focus();\n}\n\n/**\n * Handles a Tab for a trap on `container`. When the browser has no tab stop\n * left in that direction inside the container, focus goes to the stop at the\n * other end and the key is marked used, and with no stops at all the\n * container takes focus. Focus outside the container goes in at that end\n * too. Returns whether it moved focus; otherwise the browser does.\n */\nfunction wrapTab(e: KeyboardEvent, container: HTMLElement): boolean {\n const stops = findTabStops(container);\n if (!stops) {\n e.preventDefault();\n container.focus();\n return true;\n }\n const focused = focusedElement(container.ownerDocument);\n const current = stops.stopFor(focused);\n // Wrap whenever the browser has no stop left in that direction inside the\n // container. Comparing positions rather than testing `=== first` also\n // covers focus resting on the container or on an element outside the tab\n // order, which the browser would otherwise walk straight out of.\n if (\n !inside(container, focused) ||\n (e.shiftKey\n ? !follows(container, stops.first, current)\n : !follows(container, current, stops.last))\n ) {\n e.preventDefault();\n focusTabStop(container, e.shiftKey);\n return true;\n }\n return false;\n}\n\n/**\n * Holds Tab inside the element `container` returns until the returned\n * function is called. Tab and Shift+Tab heard on `keyTarget` wrap at the\n * ends, unless something already marked the key used, and if a Tab the trap\n * let through still takes focus out, it sends focus back to the other end.\n *\n * `container` is read each time a key or a focus change arrives, so an\n * overlay whose nodes are remounted while it's open, as moving to another\n * portal target does, stays trapped without attaching again. `holds` is asked\n * on every Tab, and the trap leaves the key alone while it says no. Internal\n * like `focusTabStop`. It's for an overlay that holds Tab from a listener of\n * its own on `window` and asks the overlay stack first, so it stands aside\n * while another overlay is open over it, which a trap listening on the\n * container can't do.\n */\nexport function trapTab(\n container: () => HTMLElement | null,\n keyTarget: HTMLElement | Window,\n holds: () => boolean = () => true\n): () => void {\n // The document focus moves in: the window's own, or the element's.\n const doc =\n 'document' in keyTarget ? keyTarget.document : keyTarget.ownerDocument;\n // A window and an element type their listeners differently, so the trap\n // listens through the base type both share.\n const keys: EventTarget = keyTarget;\n // The end focus goes back to if a Tab the trap let the browser handle\n // takes it out (the last for Shift+Tab), held until that Tab has finished\n // moving focus, and `null` otherwise.\n let wrapFromLast: boolean | null = null;\n let wrapTimer: ReturnType<typeof setTimeout> | undefined;\n\n // `keyTarget` is any target, so the listener takes the base event type.\n const handleKeyDown = (event: Event) => {\n const e = event as KeyboardEvent;\n const box = container();\n // A trap nested inside this one has already wrapped focus.\n if (e.key !== 'Tab' || e.defaultPrevented || !box || !holds()) return;\n if (wrapTab(e, box)) return;\n wrapFromLast = e.shiftKey;\n clearTimeout(wrapTimer);\n wrapTimer = setTimeout(() => {\n wrapFromLast = null;\n });\n };\n\n // The browser moves focus as soon as the keydown is over, so focus that\n // lands outside while `wrapFromLast` is set got there by that Tab.\n const handleFocusIn = (e: FocusEvent) => {\n const box = container();\n if (wrapFromLast === null || !box) return;\n if (inside(box, e.composedPath()[0] as Node)) return;\n const fromLast = wrapFromLast;\n wrapFromLast = null;\n focusTabStop(box, fromLast);\n };\n\n keys.addEventListener('keydown', handleKeyDown);\n doc.addEventListener('focusin', handleFocusIn, true);\n return () => {\n keys.removeEventListener('keydown', handleKeyDown);\n doc.removeEventListener('focusin', handleFocusIn, true);\n clearTimeout(wrapTimer);\n };\n}\n\n/**\n * Options for `useFocusTrap`.\n */\nexport interface UseFocusTrapOptions {\n /**\n * Whether the trap is on. Turning it on moves focus into the container;\n * turning it off (or unmounting) releases Tab and restores focus.\n * @defaultValue true\n */\n active?: boolean;\n /**\n * The element inside the container to focus when the trap turns on. It has\n * to be one that can take focus, so a heading needs `tabIndex={-1}`. When\n * focusing it doesn't put focus inside the container (the ref is empty, or\n * its element is outside, disabled, hidden or can't take focus), focus goes\n * to the first tab stop inside the container that takes focus, and to the\n * container itself when none does.\n */\n initialFocusRef?: RefObject<HTMLElement | null>;\n /**\n * Where focus goes when the trap turns off. `true` returns it to the element\n * that had focus when the trap turned on; a ref sends it to that element\n * instead; `false` leaves it alone. Focus is only moved while the trap still\n * holds it, so a click that already put focus somewhere else outside the\n * container keeps it there.\n *\n * `true` reads focus after the container's content has mounted, so content\n * that focuses itself as it mounts (an `autoFocus` input) hides the element\n * that opened it. And some browsers don't focus a button when it is\n * clicked. For a panel opened from a button, pass the button's ref.\n * @defaultValue true\n */\n restoreFocus?: boolean | RefObject<HTMLElement | null>;\n}\n\n/**\n * Keeps keyboard focus inside a container while it is active: focus moves in\n * when the trap turns on, Tab and Shift+Tab wrap between the first and last\n * tab stops, and focus goes back where it came from when the trap turns off.\n *\n * Tab stops are what the browser's Tab visits, in document order: links,\n * form controls, frames, media with controls, a `<details>` summary, editable\n * regions, anything with `tabIndex={0}`, and the content of open shadow\n * roots. Hidden, disabled, inert and `tabIndex={-1}` elements are skipped,\n * and a radio group counts once. Give the container `tabIndex={-1}` so it can\n * hold focus itself when nothing inside can. The trap listens on the\n * container, so a trap nested inside another handles Tab first and the outer\n * one stands aside.\n *\n * The trap is about Tab. If a Tab it let through still takes focus out (a\n * browser can leave out a stop the page has, such as links when its settings\n * say to), it sends focus back to the other end. A pointer or a script moving\n * focus out is left alone, because pulling focus back from a click is modal\n * behaviour, and a modal also has to block the page behind it, which `Modal`\n * does. Content the container renders through a portal lives elsewhere in\n * the DOM, so it is outside the trap: render nested overlays inside the\n * container, or give them a trap of their own. To trap content a `Portal`\n * renders, pass a ref to the element inside the `Portal` as `containerRef`.\n *\n * The trap looks at `containerRef` again each time the component calling it\n * renders. A container that mounts after the trap turns on, such as a panel\n * waiting for a `Portal` target held in state, has it attach once that\n * component renders with the container in the DOM. When the container leaves\n * or is replaced, the trap lets go of it as it would turning off, handing\n * focus back, and attaches to the next one.\n * A child that mounts the container in a render of its own (from its own\n * state, or as a `Suspense` boundary resolves) goes unseen until the\n * component calling the hook renders again. The trap waits for hydration, so\n * that component renders again when the page hydrates, and portaled content,\n * which first appears then, is found.\n *\n * @function useFocusTrap\n * @param containerRef - Ref to the element focus stays inside.\n * @param options - When the trap is on, and where focus starts and ends.\n *\n * @example\n * const panelRef = useRef<HTMLDivElement>(null);\n * useFocusTrap(panelRef, { active: isOpen });\n * return isOpen ? (\n * <div ref={panelRef} role=\"dialog\" aria-label=\"Filters\" tabIndex={-1}>\n * …\n * </div>\n * ) : null;\n */\nexport function useFocusTrap(\n containerRef: RefObject<HTMLElement | null>,\n options: UseFocusTrapOptions = {}\n): void {\n const { active = true, initialFocusRef, restoreFocus = true } = options;\n // Portaled content has no server-rendered counterpart, so a portaled\n // container only exists from the commit after hydration.\n const hydrated = useIsHydrated();\n // The container the trap is attached to, or `null` while it has none.\n const heldRef = useRef<HTMLElement | null>(null);\n // Bumped to run the trap again when the container in the ref changes.\n const [refChanges, setRefChanges] = useState(0);\n\n useEffect(() => {\n heldRef.current = null;\n if (!active || !hydrated) return undefined;\n const container = containerRef.current;\n if (!container) return undefined;\n heldRef.current = container;\n const doc = container.ownerDocument;\n\n const opener = focusedElement(doc) as HTMLElement;\n\n // `initialFocusRef` counts only when focusing it puts focus inside. Focus\n // put outside would stay out, as Tab there never reaches the container's\n // listener, and focusing something that can't take focus (a heading\n // without `tabIndex`, a disabled control) leaves focus where it was.\n const initial = initialFocusRef?.current;\n const inTrap = initial && inside(container, initial) ? initial : null;\n inTrap?.focus();\n if (!inTrap || !inside(container, focusedElement(doc))) {\n focusTabStop(container);\n }\n\n const releaseTab = trapTab(() => container, container);\n return () => {\n releaseTab();\n let target = restoreFocus ? opener : null;\n // `null` is an object too, and a caller without types can pass it.\n if (restoreFocus && typeof restoreFocus === 'object') {\n // Read now rather than when the trap turned on: a trigger that\n // re-mounted in between has a new node.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n target = restoreFocus.current;\n }\n // Hand focus back only while the trap still holds it: inside the\n // container, or dropped to <body> because the container left the page.\n const now = focusedElement(doc);\n if (target && (now === doc.body || inside(container, now))) {\n target.focus();\n }\n };\n }, [\n active,\n hydrated,\n containerRef,\n initialFocusRef,\n restoreFocus,\n refChanges,\n ]);\n\n // Nothing says when a ref is set, so after every render, a ref that no\n // longer matches what the trap holds (a container that mounted, left or was\n // replaced) runs it again. Effects run in order, so whenever the effect\n // above ran in this commit, it read the ref just before this does, and a\n // mismatch means the ref changed in a render it didn't run for. The render\n // a bump asks for runs it, so the two match and the trap settles. An empty\n // ref matches a trap holding nothing, so a container that never mounts\n // costs no render.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose\n useEffect(() => {\n if (active && hydrated && containerRef.current !== heldRef.current) {\n setRefChanges(n => n + 1);\n }\n });\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFocusTrap.js","sources":["../../../src/helpers/useFocusTrap.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport type { RefObject } from 'react';\nimport { useIsHydrated } from './useIsHydrated';\nimport { getDeepestActiveElement } from './shadowDom';\n\n/**\n * Whether `el` is editable while its parent is not, which makes it an editing\n * host: the one tab stop an editable region gets. `contenteditable=\"false\"`\n * turns editing off, and a missing or unknown value inherits the parent's.\n */\nfunction isEditingHost(el: Element): boolean {\n const editable = (node: Element): boolean | null => {\n const value = node.getAttribute('contenteditable')?.toLowerCase();\n if (value === undefined) return null;\n if (value === '' || value === 'true' || value === 'plaintext-only') {\n return true;\n }\n return value === 'false' ? false : null;\n };\n if (editable(el) !== true) return false;\n for (let node = el.parentElement; node; node = node.parentElement) {\n const state = editable(node);\n if (state !== null) return !state;\n }\n return true;\n}\n\n/** Whether `el` is the summary of its `<details>`: the first one, not a stray. */\nconst isDetailsSummary = (el: Element): boolean =>\n el.parentElement?.localName === 'details' &&\n Array.from(el.parentElement.children).find(\n child => child.localName === 'summary'\n ) === el;\n\n/**\n * Whether the browser puts `el` in the tab order, before anything that hides\n * or disables it. The `tabIndex` property can't answer this on its own: it\n * can read `-1` for an editable region or an `<embed>` that Tab still visits,\n * and `0` for a `<video>` without controls that it doesn't. So a valid\n * `tabindex` attribute decides, and otherwise the element's kind does.\n * Internal like `focusTabStop`: `src/index.ts` names what it takes from here.\n */\nexport function isTabbableKind(el: Element): boolean {\n const tabindex = el.getAttribute('tabindex');\n if (tabindex !== null && /^\\s*[+-]?\\d/.test(tabindex)) {\n return (el as HTMLElement).tabIndex >= 0;\n }\n switch (el.localName) {\n case 'a':\n case 'area':\n return el.hasAttribute('href');\n case 'input':\n return (el as HTMLInputElement).type !== 'hidden';\n case 'button':\n case 'select':\n case 'textarea':\n case 'iframe':\n case 'embed':\n case 'object':\n return true;\n case 'audio':\n case 'video':\n return el.hasAttribute('controls');\n case 'summary':\n return isDetailsSummary(el);\n default:\n return isEditingHost(el);\n }\n}\n\n/**\n * The node's parent in the flattened tree, the one the browser renders and\n * tabs through: the slot it is assigned to, else its parent, else the host of\n * the shadow root it tops, and nothing above the document. A closed shadow\n * root hides its slots (`assignedSlot` reads `null` under one), so a child of\n * its host goes straight to the host, whether a slot takes it or not.\n */\nconst flatParent = (node: Node): Node | null =>\n (node as Element).assignedSlot ??\n node.parentElement ??\n (node.parentNode as ShadowRoot | null)?.host ??\n null;\n\n/**\n * The element's children in the flattened tree, in the order they render: a\n * host's shadow root content, a slot's assigned elements (or its fallback\n * content when nothing is assigned), anything else's own children. A host\n * whose shadow root is closed has no root to read, so its own children stand\n * in, including any that no slot takes and that aren't rendered.\n */\nfunction flatChildren(el: Element): Element[] {\n if (el.shadowRoot) return Array.from(el.shadowRoot.children);\n if (el.localName === 'slot') {\n const assigned = (el as HTMLSlotElement).assignedNodes();\n if (assigned.length > 0) {\n return assigned.filter(\n (node): node is Element => node.nodeType === Node.ELEMENT_NODE\n );\n }\n }\n return Array.from(el.children);\n}\n\nconst isShown = (el: Element): boolean =>\n !el.hasAttribute('inert') && getComputedStyle(el).display !== 'none';\n\nconst isVisible = (el: Element): boolean => {\n const { visibility } = getComputedStyle(el);\n return visibility !== 'hidden' && visibility !== 'collapse';\n};\n\n/**\n * Whether nothing from `el` up to `top` hides it: `inert`, `display: none`\n * (not inherited, so each element is checked) or a closed `<details>` it\n * isn't the summary of. `top` itself isn't checked, and `null` walks to the\n * top of the page.\n */\nfunction isShownUpTo(el: Element, top: Node | null): boolean {\n let below: Element | null = null;\n for (\n let node: Element | null = el;\n node && node !== top;\n node = flatParent(node) as Element | null\n ) {\n if (!isShown(node)) return false;\n if (\n below &&\n node.localName === 'details' &&\n !node.hasAttribute('open') &&\n !isDetailsSummary(below)\n ) {\n return false;\n }\n below = node;\n }\n return true;\n}\n\n/**\n * The images that use the image map `area` belongs to. An image names its\n * map with `usemap=\"#…\"`, matching the map's `name` or `id`.\n */\nfunction imagesUsingMapOf(area: Element): Element[] {\n const map = area.closest('map');\n if (!map) return [];\n const names = [map.getAttribute('name'), map.id].filter(name => name);\n return Array.from(\n (area.getRootNode() as ParentNode).querySelectorAll('img[usemap]')\n ).filter(img => {\n const ref = img.getAttribute('usemap') as string;\n return ref.startsWith('#') && names.includes(ref.slice(1));\n });\n}\n\n/**\n * Whether an image map area is shown. An area has no box of its own: the\n * HTML rendering rules give it `display: none`, though a browser may not\n * report that. So it counts where an image using its map is shown, as long\n * as nothing makes it inert.\n */\nfunction isAreaShown(area: Element, container: Element): boolean {\n for (\n let node: Element | null = area;\n node && node !== container;\n node = flatParent(node) as Element | null\n ) {\n if (node.hasAttribute('inert')) return false;\n }\n return imagesUsingMapOf(area).some(\n img => isShownUpTo(img, null) && isVisible(img)\n );\n}\n\n/**\n * Whether Tab can land on `el`, one of the kinds it visits. A disabled control\n * (including one inside a disabled `<fieldset>`), an inert subtree and\n * anything not rendered are skipped. `visibility` is inherited, so the\n * element's own computed value covers its ancestors.\n */\nfunction isRenderedAndEnabled(el: Element, container: Element): boolean {\n if (el.matches(':disabled')) return false;\n if (el.localName === 'area') return isAreaShown(el, container);\n return isShownUpTo(el, container) && isVisible(el);\n}\n\n/** A radio button with a name, which shares one tab stop with its group. */\nconst isGroupedRadio = (el: Element): el is HTMLInputElement =>\n el.localName === 'input' &&\n (el as HTMLInputElement).type === 'radio' &&\n (el as HTMLInputElement).name !== '';\n\n/** Whether two radio buttons are in one group: same name, form owner and tree. */\nconst sameGroup = (a: HTMLInputElement, b: Element): b is HTMLInputElement =>\n isGroupedRadio(b) &&\n b.name === a.name &&\n b.form === a.form &&\n b.getRootNode() === a.getRootNode();\n\n/**\n * The checked button of `radio`'s group. The group isn't bounded by the trap,\n * so this looks through the radio's whole tree.\n */\nconst checkedInGroup = (radio: HTMLInputElement): Element | undefined =>\n Array.from(\n (radio.getRootNode() as ParentNode).querySelectorAll('input:checked')\n ).find(el => sameGroup(radio, el));\n\n/** The flattened-tree ancestors of `node` below the container, outermost first, then `node`. */\nfunction flatChain(node: Node, container: Node): Node[] {\n const chain: Node[] = [];\n for (let n: Node | null = node; n && n !== container; n = flatParent(n)) {\n chain.unshift(n);\n }\n return chain;\n}\n\n/**\n * Whether `node` is inside the container in the flattened tree: in it, in a\n * shadow root it holds, or slotted into it. A child of a closed-root host\n * counts as inside wherever the host is, as its slot can't be seen.\n */\nfunction inside(container: Node, node: Node): boolean {\n for (let n: Node | null = node; n; n = flatParent(n)) {\n if (n === container) return true;\n }\n return false;\n}\n\n/**\n * `true` when Tab reaches `b` after `a`, which is their order in the\n * flattened tree: a shadow host comes before its shadow root's content, and\n * slotted content comes where its slot is. A closed root's slots can't be\n * seen, so its host's children keep their place in the light DOM. Two\n * flattened-tree siblings are always in one DOM tree, so their document\n * position decides between them.\n */\nfunction follows(container: Element, a: Node, b: Node): boolean {\n const chainA = flatChain(a, container);\n const chainB = flatChain(b, container);\n for (let i = 0; i < Math.max(chainA.length, chainB.length); i++) {\n const [x, y] = [chainA[i], chainB[i]];\n if (x === y) continue;\n if (!x) return true;\n if (!y) return false;\n return Boolean(\n x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING\n );\n }\n return false;\n}\n\n/**\n * Every element of a tabbable kind under `el` in the flattened tree, depth\n * first, which is the order Tab visits them. Under a host whose shadow root\n * is closed, that takes in the host's own children instead, rendered or not.\n */\nfunction collectCandidates(\n el: Element,\n out: HTMLElement[] = []\n): HTMLElement[] {\n for (const child of flatChildren(el)) {\n if (isTabbableKind(child)) out.push(child as HTMLElement);\n collectCandidates(child, out);\n }\n return out;\n}\n\ninterface TabStops {\n first: HTMLElement;\n last: HTMLElement;\n /** The stop that stands for `node`: its group's stop for a radio button. */\n stopFor(node: Element): Element;\n /** The stops from one end inward, the last first when `fromLast`. */\n from(fromLast: boolean): Generator<HTMLElement>;\n}\n\n/**\n * The first and last tab stops inside `container`, or `null` when there are\n * none. Only the ends matter for wrapping, so the style checks run from each\n * end until they find a stop rather than over every candidate.\n *\n * A radio group is one stop, the way the browser treats it: its checked\n * button, or its first when none is checked. Counting every button would make\n * the group's last one an end, and Tab from the checked one would leave. The\n * group goes by name, form owner and tree, not by the trap, so a checked\n * button outside the container that Tab can land on leaves the group no stop\n * inside. One that Tab can't land on leaves the group as if none were checked.\n */\nfunction findTabStops(container: HTMLElement): TabStops | null {\n const candidates = collectCandidates(container);\n const checked = new Map<Element, boolean>();\n const usable = (el: Element): boolean => {\n let ok = checked.get(el);\n if (ok === undefined) {\n ok = isRenderedAndEnabled(el, container);\n checked.set(el, ok);\n }\n return ok;\n };\n // Resolved once per group, filed under each of its buttons, since finding\n // the checked one scans the radio's whole tree.\n const groupStops = new Map<Element, HTMLElement | undefined>();\n const groupStop = (radio: HTMLInputElement): HTMLElement | undefined => {\n if (groupStops.has(radio)) return groupStops.get(radio);\n const group = candidates.filter(el => sameGroup(radio, el));\n const on = checkedInGroup(radio);\n const stop =\n on && isTabbableKind(on) && usable(on)\n ? group.find(el => el === on)\n : group.find(usable);\n for (const el of [radio, ...group]) groupStops.set(el, stop);\n return stop;\n };\n const isStop = (el: HTMLElement): boolean =>\n usable(el) && (!isGroupedRadio(el) || groupStop(el) === el);\n // Checked only as they're reached, and the checks are kept, so finding\n // both ends costs what it did when only the ends were looked for.\n function* from(fromLast: boolean): Generator<HTMLElement> {\n for (let i = 0; i < candidates.length; i++) {\n const el = candidates[fromLast ? candidates.length - 1 - i : i];\n if (isStop(el)) yield el;\n }\n }\n\n const first = from(false).next().value;\n if (!first) return null;\n return {\n first,\n last: from(true).next().value as HTMLElement,\n stopFor: node => (isGroupedRadio(node) && groupStop(node)) || node,\n from,\n };\n}\n\n/**\n * The element that has focus in the container's own document (an iframe's,\n * when it renders into one), inside open shadow roots too. Focus inside a\n * closed one reads as its host, which the comparisons above place like any\n * other element. Browsers fall back to <body> when nothing has\n * focus. jsdom, where consumers run their tests, reports nothing once focus\n * was inside a shadow root that was removed, so this falls back for it.\n */\nconst focusedElement = (doc: Document): Element =>\n getDeepestActiveElement(doc) ?? doc.body;\n\n/**\n * Moves focus to the first tab stop inside `container`, or the last when\n * `fromLast`, and to the container when there is none. Every move a trap\n * makes goes through here: into the container as it opens, to the other end\n * on a wrap, and back in after a Tab the browser carried out.\n *\n * A stop that doesn't take focus is passed over for the next one in. An\n * `<object>` or `<embed>` with nothing to show is one: it counts as a stop by\n * its kind, but browsers refuse to focus it, and which ones they refuse\n * depends on the browser and on what has loaded, so only trying tells. A\n * stop took focus when focus moved, wherever it went (a stop can hand focus\n * on), or when focus was on it already. `src/index.ts` names its exports from\n * this module, so this one stays internal.\n */\nexport function focusTabStop(container: HTMLElement, fromLast = false): void {\n const doc = container.ownerDocument;\n for (const stop of findTabStops(container)?.from(fromLast) ?? []) {\n const before = focusedElement(doc);\n stop.focus();\n const now = focusedElement(doc);\n if (now !== before || inside(stop, now)) return;\n }\n container.focus();\n}\n\n/**\n * Handles a Tab for a trap on `container`. When the browser has no tab stop\n * left in that direction inside the container, focus goes to the stop at the\n * other end and the key is marked used, and with no stops at all the\n * container takes focus. Focus outside the container goes in at that end\n * too. Returns whether it moved focus; otherwise the browser does.\n */\nfunction wrapTab(e: KeyboardEvent, container: HTMLElement): boolean {\n const stops = findTabStops(container);\n if (!stops) {\n e.preventDefault();\n container.focus();\n return true;\n }\n const focused = focusedElement(container.ownerDocument);\n const current = stops.stopFor(focused);\n // Wrap whenever the browser has no stop left in that direction inside the\n // container. Comparing positions rather than testing `=== first` also\n // covers focus resting on the container or on an element outside the tab\n // order, which the browser would otherwise walk straight out of.\n if (\n !inside(container, focused) ||\n (e.shiftKey\n ? !follows(container, stops.first, current)\n : !follows(container, current, stops.last))\n ) {\n e.preventDefault();\n focusTabStop(container, e.shiftKey);\n return true;\n }\n return false;\n}\n\n/**\n * Holds Tab inside the element `container` returns until the returned\n * function is called. Tab and Shift+Tab heard on `keyTarget` wrap at the\n * ends, unless something already marked the key used, and if a Tab the trap\n * let through still takes focus out, it sends focus back to the other end.\n *\n * `container` is read each time a key or a focus change arrives, so an\n * overlay whose nodes are remounted while it's open, as moving to another\n * portal target does, stays trapped without attaching again. `holds` is asked\n * on every Tab, and the trap leaves the key alone while it says no. Internal\n * like `focusTabStop`. It's for an overlay that holds Tab from a listener of\n * its own on `window` and asks the overlay stack first, so it stands aside\n * while another overlay is open over it, which a trap listening on the\n * container can't do.\n */\nexport function trapTab(\n container: () => HTMLElement | null,\n keyTarget: HTMLElement | Window,\n holds: () => boolean = () => true\n): () => void {\n // The document focus moves in: the window's own, or the element's.\n const doc =\n 'document' in keyTarget ? keyTarget.document : keyTarget.ownerDocument;\n // A window and an element type their listeners differently, so the trap\n // listens through the base type both share.\n const keys: EventTarget = keyTarget;\n // The end focus goes back to if a Tab the trap let the browser handle\n // takes it out (the last for Shift+Tab), held until that Tab has finished\n // moving focus, and `null` otherwise.\n let wrapFromLast: boolean | null = null;\n let wrapTimer: ReturnType<typeof setTimeout> | undefined;\n\n // `keyTarget` is any target, so the listener takes the base event type.\n const handleKeyDown = (event: Event) => {\n const e = event as KeyboardEvent;\n const box = container();\n // A trap nested inside this one has already wrapped focus.\n if (e.key !== 'Tab' || e.defaultPrevented || !box || !holds()) return;\n if (wrapTab(e, box)) return;\n wrapFromLast = e.shiftKey;\n clearTimeout(wrapTimer);\n wrapTimer = setTimeout(() => {\n wrapFromLast = null;\n });\n };\n\n // The browser moves focus as soon as the keydown is over, so focus that\n // lands outside while `wrapFromLast` is set got there by that Tab.\n const handleFocusIn = (e: FocusEvent) => {\n const box = container();\n if (wrapFromLast === null || !box) return;\n if (inside(box, e.composedPath()[0] as Node)) return;\n const fromLast = wrapFromLast;\n wrapFromLast = null;\n focusTabStop(box, fromLast);\n };\n\n keys.addEventListener('keydown', handleKeyDown);\n doc.addEventListener('focusin', handleFocusIn, true);\n return () => {\n keys.removeEventListener('keydown', handleKeyDown);\n doc.removeEventListener('focusin', handleFocusIn, true);\n clearTimeout(wrapTimer);\n };\n}\n\n/**\n * Options for `useFocusTrap`.\n */\nexport interface UseFocusTrapOptions {\n /**\n * Whether the trap is on. Turning it on moves focus into the container;\n * turning it off (or unmounting) releases Tab and restores focus.\n * @defaultValue true\n */\n active?: boolean;\n /**\n * The element inside the container to focus when the trap turns on. It has\n * to be one that can take focus, so a heading needs `tabIndex={-1}`. When\n * focusing it doesn't put focus inside the container (the ref is empty, or\n * its element is outside, disabled, hidden or can't take focus), focus goes\n * to the first tab stop inside the container that takes focus, and to the\n * container itself when none does.\n */\n initialFocusRef?: RefObject<HTMLElement | null>;\n /**\n * Where focus goes when the trap turns off. `true` returns it to the element\n * that had focus when the trap turned on; a ref sends it to that element\n * instead; `false` leaves it alone. Focus is only moved while the trap still\n * holds it, so a click that already put focus somewhere else outside the\n * container keeps it there.\n *\n * `true` reads focus after the container's content has mounted, so content\n * that focuses itself as it mounts (an `autoFocus` input) hides the element\n * that opened it. And some browsers don't focus a button when it is\n * clicked. For a panel opened from a button, pass the button's ref.\n * @defaultValue true\n */\n restoreFocus?: boolean | RefObject<HTMLElement | null>;\n}\n\n/**\n * Keeps keyboard focus inside a container while it is active: focus moves in\n * when the trap turns on, Tab and Shift+Tab wrap between the first and last\n * tab stops, and focus goes back where it came from when the trap turns off.\n *\n * Tab stops are what the browser's Tab visits, in document order: links,\n * form controls, frames, media with controls, a `<details>` summary, editable\n * regions, anything with `tabIndex={0}`, and the content of open shadow\n * roots. Hidden, disabled, inert and `tabIndex={-1}` elements are skipped,\n * and a radio group counts once. Give the container `tabIndex={-1}` so it can\n * hold focus itself when nothing inside can. The trap listens on the\n * container, so a trap nested inside another handles Tab first and the outer\n * one stands aside.\n *\n * The trap is about Tab. If a Tab it let through still takes focus out (a\n * browser can leave out a stop the page has, such as links when its settings\n * say to), it sends focus back to the other end. A pointer or a script moving\n * focus out is left alone, because pulling focus back from a click is modal\n * behaviour, and a modal also has to block the page behind it, which `Modal`\n * does. Content the container renders through a portal lives elsewhere in\n * the DOM, so it is outside the trap: render nested overlays inside the\n * container, or give them a trap of their own. To trap content a `Portal`\n * renders, pass a ref to the element inside the `Portal` as `containerRef`.\n *\n * The trap looks at `containerRef` again each time the component calling it\n * renders. A container that mounts after the trap turns on, such as a panel\n * waiting for a `Portal` target held in state, has it attach once that\n * component renders with the container in the DOM. When the container leaves\n * or is replaced, the trap lets go of it as it would turning off, handing\n * focus back, and attaches to the next one.\n * A child that mounts the container in a render of its own (from its own\n * state, or as a `Suspense` boundary resolves) goes unseen until the\n * component calling the hook renders again. The trap waits for hydration, so\n * that component renders again when the page hydrates, and portaled content,\n * which first appears then, is found.\n *\n * @function useFocusTrap\n * @param containerRef - Ref to the element focus stays inside.\n * @param options - When the trap is on, and where focus starts and ends.\n *\n * @example\n * const panelRef = useRef<HTMLDivElement>(null);\n * useFocusTrap(panelRef, { active: isOpen });\n * return isOpen ? (\n * <div ref={panelRef} role=\"dialog\" aria-label=\"Filters\" tabIndex={-1}>\n * …\n * </div>\n * ) : null;\n */\nexport function useFocusTrap(\n containerRef: RefObject<HTMLElement | null>,\n options: UseFocusTrapOptions = {}\n): void {\n const { active = true, initialFocusRef, restoreFocus = true } = options;\n // Portaled content has no server-rendered counterpart, so a portaled\n // container only exists from the commit after hydration.\n const hydrated = useIsHydrated();\n // The container the trap is attached to, or `null` while it has none.\n const heldRef = useRef<HTMLElement | null>(null);\n // Bumped to run the trap again when the container in the ref changes.\n const [refChanges, setRefChanges] = useState(0);\n\n useEffect(() => {\n heldRef.current = null;\n if (!active || !hydrated) return undefined;\n const container = containerRef.current;\n if (!container) return undefined;\n heldRef.current = container;\n const doc = container.ownerDocument;\n\n const opener = focusedElement(doc) as HTMLElement;\n\n // `initialFocusRef` counts only when focusing it puts focus inside. Focus\n // put outside would stay out, as Tab there never reaches the container's\n // listener, and focusing something that can't take focus (a heading\n // without `tabIndex`, a disabled control) leaves focus where it was.\n const initial = initialFocusRef?.current;\n const inTrap = initial && inside(container, initial) ? initial : null;\n inTrap?.focus();\n if (!inTrap || !inside(container, focusedElement(doc))) {\n focusTabStop(container);\n }\n\n const releaseTab = trapTab(() => container, container);\n return () => {\n releaseTab();\n let target = restoreFocus ? opener : null;\n // `null` is an object too, and a caller without types can pass it.\n if (restoreFocus && typeof restoreFocus === 'object') {\n // Read now rather than when the trap turned on: a trigger that\n // re-mounted in between has a new node.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n target = restoreFocus.current;\n }\n // Hand focus back only while the trap still holds it: inside the\n // container, or dropped to <body> because the container left the page.\n const now = focusedElement(doc);\n if (target && (now === doc.body || inside(container, now))) {\n target.focus();\n }\n };\n }, [\n active,\n hydrated,\n containerRef,\n initialFocusRef,\n restoreFocus,\n refChanges,\n ]);\n\n // Nothing says when a ref is set, so after every render, a ref that no\n // longer matches what the trap holds (a container that mounted, left or was\n // replaced) runs it again. Effects run in order, so whenever the effect\n // above ran in this commit, it read the ref just before this does, and a\n // mismatch means the ref changed in a render it didn't run for. The render\n // a bump asks for runs it, so the two match and the trap settles. An empty\n // ref matches a trap holding nothing, so a container that never mounts\n // costs no render.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose\n useEffect(() => {\n if (active && hydrated && containerRef.current !== heldRef.current) {\n setRefChanges(n => n + 1);\n }\n });\n}\n"],"names":["isShown"],"mappings":"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"}
|