@lumx/react 4.12.1-alpha.0 → 4.12.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +73 -156
- package/index.js.map +1 -1
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColorVariant as ColorVariant$1, Size as Size$1, VISUALLY_HIDDEN, Theme as Theme$1, AspectRatio as AspectRatio$1, DOCUMENT
|
|
1
|
+
import { ColorVariant as ColorVariant$1, Size as Size$1, VISUALLY_HIDDEN, Theme as Theme$1, AspectRatio as AspectRatio$1, DOCUMENT, IS_BROWSER as IS_BROWSER$1, Emphasis as Emphasis$1, WINDOW, DIALOG_TRANSITION_DURATION, Orientation as Orientation$1, NOTIFICATION_TRANSITION_DURATION, Kind as Kind$1, Alignment as Alignment$1, ColorPalette as ColorPalette$1 } from '@lumx/core/js/constants';
|
|
2
2
|
export * from '@lumx/core/js/constants';
|
|
3
3
|
export * from '@lumx/core/js/types';
|
|
4
4
|
import * as React from 'react';
|
|
@@ -204,11 +204,6 @@ const ColorVariant = {
|
|
|
204
204
|
*/
|
|
205
205
|
const IS_BROWSER = typeof window !== 'undefined' && !window.navigator.userAgent.includes('jsdom');
|
|
206
206
|
|
|
207
|
-
/**
|
|
208
|
-
* Optional global `document` instance (not defined when running SSR).
|
|
209
|
-
*/
|
|
210
|
-
const DOCUMENT = typeof document !== 'undefined' ? document : undefined;
|
|
211
|
-
|
|
212
207
|
function getDefaultExportFromCjs (x) {
|
|
213
208
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
214
209
|
}
|
|
@@ -5065,7 +5060,7 @@ const LISTENERS = makeListenerTowerContext();
|
|
|
5065
5060
|
*/
|
|
5066
5061
|
function useCallbackOnEscape(callback, closeOnEscape = true) {
|
|
5067
5062
|
useEffect(() => {
|
|
5068
|
-
const rootElement = DOCUMENT
|
|
5063
|
+
const rootElement = DOCUMENT?.body;
|
|
5069
5064
|
if (!closeOnEscape || !callback || !rootElement) {
|
|
5070
5065
|
return undefined;
|
|
5071
5066
|
}
|
|
@@ -5280,7 +5275,7 @@ const Tooltip = forwardRef((props, ref) => {
|
|
|
5280
5275
|
...forwardedProps
|
|
5281
5276
|
} = props;
|
|
5282
5277
|
// Disable in SSR.
|
|
5283
|
-
if (!DOCUMENT
|
|
5278
|
+
if (!DOCUMENT) {
|
|
5284
5279
|
return /*#__PURE__*/jsx(Fragment, {
|
|
5285
5280
|
children: children
|
|
5286
5281
|
});
|
|
@@ -8818,14 +8813,8 @@ const ComboboxOptionMoreInfo$1 = (props, {
|
|
|
8818
8813
|
/** CSS selector listing all tabbable elements. */
|
|
8819
8814
|
const TABBABLE_ELEMENTS_SELECTOR = 'a[href], button, textarea, input:not([type="hidden"]):not([hidden]), [tabindex]';
|
|
8820
8815
|
|
|
8821
|
-
/**
|
|
8822
|
-
|
|
8823
|
-
*
|
|
8824
|
-
* Note: `aria-disabled` is intentionally NOT in this list — per ARIA semantics, an `aria-disabled` element
|
|
8825
|
-
* remains focusable (and discoverable by assistive tech). To remove an element from the tab order, use
|
|
8826
|
-
* `tabindex="-1"` instead.
|
|
8827
|
-
*/
|
|
8828
|
-
const DISABLED_SELECTOR = '[hidden], [tabindex="-1"], [disabled]:not([disabled="false"])';
|
|
8816
|
+
/** CSS selector matching element that are disabled (should not receive focus). */
|
|
8817
|
+
const DISABLED_SELECTOR = '[hidden], [tabindex="-1"], [disabled]:not([disabled="false"]), [aria-disabled]:not([aria-disabled="false"])';
|
|
8829
8818
|
|
|
8830
8819
|
const isNotDisabled = element => !element.matches(DISABLED_SELECTOR);
|
|
8831
8820
|
function getFocusableElements(element) {
|
|
@@ -8854,158 +8843,86 @@ function getFirstAndLastFocusable(parentElement) {
|
|
|
8854
8843
|
return {};
|
|
8855
8844
|
}
|
|
8856
8845
|
|
|
8857
|
-
/**
|
|
8858
|
-
* Shared listener tower for focus traps.
|
|
8859
|
-
*
|
|
8860
|
-
* When multiple traps are activated, only the last registered one is active. When it tears down, the previously
|
|
8861
|
-
* registered trap is re-enabled.
|
|
8862
|
-
*/
|
|
8863
8846
|
const FOCUS_TRAPS = makeListenerTowerContext();
|
|
8847
|
+
|
|
8864
8848
|
/**
|
|
8865
8849
|
* Trap 'Tab' focus switch inside the `focusZoneElement`.
|
|
8866
8850
|
*
|
|
8867
|
-
*
|
|
8868
|
-
*
|
|
8869
|
-
* 2. Otherwise focus the first focusable descendant.
|
|
8870
|
-
* 3. Otherwise focus the zone element itself (falling back to setting `tabindex="-1"` if needed) so that
|
|
8871
|
-
* keyboard users (especially screen reader users) land inside the trapped region (e.g. an empty dialog).
|
|
8872
|
-
*
|
|
8873
|
-
* Tab key behavior:
|
|
8874
|
-
* - With at least one focusable descendant: focus cycles between the first and last focusable in the zone.
|
|
8875
|
-
* - With no focusable descendant: Tab is swallowed and focus is restored to the zone element itself.
|
|
8876
|
-
*
|
|
8877
|
-
* Multiple traps stack — only the latest one is active; previous traps re-enable when the latest is torn down.
|
|
8851
|
+
* If multiple focus trap are activated, only the last one is maintained and when a focus trap closes, the previous one
|
|
8852
|
+
* gets activated again.
|
|
8878
8853
|
*
|
|
8879
|
-
* @param
|
|
8880
|
-
* @param
|
|
8854
|
+
* @param focusZoneElement The element in which to trap the focus.
|
|
8855
|
+
* @param focusElement The element to focus when the focus trap is activated (otherwise the first focusable element
|
|
8856
|
+
* will be focused).
|
|
8881
8857
|
*/
|
|
8882
|
-
function
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
// Body element can be undefined in SSR context.
|
|
8889
|
-
const rootElement = DOCUMENT?.body;
|
|
8890
|
-
if (!rootElement || !focusZoneElement || signal.aborted) {
|
|
8891
|
-
return;
|
|
8892
|
-
}
|
|
8893
|
-
|
|
8894
|
-
// Use the shadow root as focus zone when available.
|
|
8895
|
-
const focusZoneElementOrShadowRoot = focusZoneElement.shadowRoot || focusZoneElement;
|
|
8896
|
-
|
|
8897
|
-
// Track whether we added a `tabindex="-1"` so we can restore the original state on teardown.
|
|
8898
|
-
let addedTabIndex = false;
|
|
8899
|
-
|
|
8900
|
-
/** Make the zone element programmatically focusable (so we can fall back to it). */
|
|
8901
|
-
const ensureZoneIsFocusable = () => {
|
|
8902
|
-
if (!focusZoneElement.hasAttribute('tabindex')) {
|
|
8903
|
-
focusZoneElement.setAttribute('tabindex', '-1');
|
|
8904
|
-
addedTabIndex = true;
|
|
8858
|
+
function useFocusTrap(focusZoneElement, focusElement) {
|
|
8859
|
+
useEffect(() => {
|
|
8860
|
+
// Body element can be undefined in SSR context.
|
|
8861
|
+
const rootElement = DOCUMENT?.body;
|
|
8862
|
+
if (!rootElement || !focusZoneElement) {
|
|
8863
|
+
return undefined;
|
|
8905
8864
|
}
|
|
8906
|
-
};
|
|
8907
8865
|
|
|
8908
|
-
|
|
8909
|
-
|
|
8910
|
-
ensureZoneIsFocusable();
|
|
8911
|
-
focusZoneElement.focus({
|
|
8912
|
-
preventScroll: true
|
|
8913
|
-
});
|
|
8914
|
-
};
|
|
8866
|
+
// Use the shadow root as focusZoneElement when available
|
|
8867
|
+
const focusZoneElementOrShadowRoot = focusZoneElement.shadowRoot || focusZoneElement;
|
|
8915
8868
|
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8869
|
+
// Trap 'Tab' key down focus switch into the focus zone.
|
|
8870
|
+
const trapTabFocusInFocusZone = evt => {
|
|
8871
|
+
const {
|
|
8872
|
+
key
|
|
8873
|
+
} = evt;
|
|
8874
|
+
if (key !== 'Tab') {
|
|
8875
|
+
return;
|
|
8876
|
+
}
|
|
8877
|
+
const focusable = getFirstAndLastFocusable(focusZoneElementOrShadowRoot);
|
|
8922
8878
|
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
}
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
};
|
|
8879
|
+
// Prevent focus switch if no focusable available.
|
|
8880
|
+
if (!focusable.first) {
|
|
8881
|
+
evt.preventDefault();
|
|
8882
|
+
return;
|
|
8883
|
+
}
|
|
8884
|
+
const activeElement = focusZoneElement.shadowRoot ? focusZoneElement.shadowRoot.activeElement : document.activeElement;
|
|
8885
|
+
if (
|
|
8886
|
+
// No previous focus
|
|
8887
|
+
!activeElement ||
|
|
8888
|
+
// Previous focus is at the end of the focus zone.
|
|
8889
|
+
!evt.shiftKey && activeElement === focusable.last ||
|
|
8890
|
+
// Previous focus is outside the focus zone
|
|
8891
|
+
!focusZoneElementOrShadowRoot.contains(activeElement)) {
|
|
8892
|
+
focusable.first.focus();
|
|
8893
|
+
evt.preventDefault();
|
|
8894
|
+
return;
|
|
8895
|
+
}
|
|
8896
|
+
if (
|
|
8897
|
+
// Focus order reversed
|
|
8898
|
+
evt.shiftKey &&
|
|
8899
|
+
// Previous focus is at the start of the focus zone.
|
|
8900
|
+
activeElement === focusable.first) {
|
|
8901
|
+
focusable.last.focus();
|
|
8902
|
+
evt.preventDefault();
|
|
8903
|
+
}
|
|
8904
|
+
};
|
|
8905
|
+
const focusTrap = {
|
|
8906
|
+
enable: () => rootElement.addEventListener('keydown', trapTabFocusInFocusZone),
|
|
8907
|
+
disable: () => rootElement.removeEventListener('keydown', trapTabFocusInFocusZone)
|
|
8908
|
+
};
|
|
8954
8909
|
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
preventScroll: true
|
|
8960
|
-
});
|
|
8961
|
-
} else {
|
|
8962
|
-
const firstFocusable = getFirstAndLastFocusable(focusZoneElementOrShadowRoot).first;
|
|
8963
|
-
if (firstFocusable) {
|
|
8964
|
-
// Focus the first focusable descendant.
|
|
8965
|
-
firstFocusable.focus({
|
|
8910
|
+
// SETUP:
|
|
8911
|
+
if (focusElement && focusZoneElementOrShadowRoot.contains(focusElement)) {
|
|
8912
|
+
// Focus the given element.
|
|
8913
|
+
focusElement.focus({
|
|
8966
8914
|
preventScroll: true
|
|
8967
8915
|
});
|
|
8968
8916
|
} else {
|
|
8969
|
-
//
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
FOCUS_TRAPS.register(focusTrap);
|
|
8974
|
-
|
|
8975
|
-
// TEARDOWN.
|
|
8976
|
-
signal.addEventListener('abort', () => {
|
|
8977
|
-
FOCUS_TRAPS.unregister(focusTrap);
|
|
8978
|
-
if (addedTabIndex) {
|
|
8979
|
-
focusZoneElement.removeAttribute('tabindex');
|
|
8917
|
+
// Focus the first focusable element in the zone.
|
|
8918
|
+
getFirstAndLastFocusable(focusZoneElementOrShadowRoot).first?.focus({
|
|
8919
|
+
preventScroll: true
|
|
8920
|
+
});
|
|
8980
8921
|
}
|
|
8981
|
-
|
|
8982
|
-
once: true
|
|
8983
|
-
});
|
|
8984
|
-
}
|
|
8922
|
+
FOCUS_TRAPS.register(focusTrap);
|
|
8985
8923
|
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
*
|
|
8989
|
-
* If multiple focus traps are activated, only the last one is maintained and when a focus trap closes, the previous one
|
|
8990
|
-
* gets activated again.
|
|
8991
|
-
*
|
|
8992
|
-
* If the zone has no focusable descendant, the zone element itself receives focus (with a fallback `tabindex="-1"`).
|
|
8993
|
-
*
|
|
8994
|
-
* @param focusZoneElement The element in which to trap the focus.
|
|
8995
|
-
* @param focusElement The element to focus when the focus trap is activated (otherwise the first focusable element
|
|
8996
|
-
* will be focused — and finally the zone element itself if no focusable is found).
|
|
8997
|
-
*/
|
|
8998
|
-
function useFocusTrap(focusZoneElement, focusElement) {
|
|
8999
|
-
useEffect(() => {
|
|
9000
|
-
if (!focusZoneElement) {
|
|
9001
|
-
return undefined;
|
|
9002
|
-
}
|
|
9003
|
-
const controller = new AbortController();
|
|
9004
|
-
setupFocusTrap({
|
|
9005
|
-
focusZoneElement,
|
|
9006
|
-
focusElement
|
|
9007
|
-
}, controller.signal);
|
|
9008
|
-
return () => controller.abort();
|
|
8924
|
+
// TEARDOWN:
|
|
8925
|
+
return () => FOCUS_TRAPS.unregister(focusTrap);
|
|
9009
8926
|
}, [focusElement, focusZoneElement]);
|
|
9010
8927
|
}
|
|
9011
8928
|
|
|
@@ -9546,7 +9463,7 @@ _InnerPopover.displayName = COMPONENT_NAME$15;
|
|
|
9546
9463
|
*/
|
|
9547
9464
|
const Popover = skipRender(
|
|
9548
9465
|
// Skip render in SSR
|
|
9549
|
-
() => Boolean(DOCUMENT
|
|
9466
|
+
() => Boolean(DOCUMENT), _InnerPopover);
|
|
9550
9467
|
Popover.displayName = COMPONENT_NAME$15;
|
|
9551
9468
|
Popover.className = CLASSNAME$14;
|
|
9552
9469
|
Popover.defaultProps = DEFAULT_PROPS$V;
|
|
@@ -11831,7 +11748,7 @@ const DEFAULT_PROPS$P = {
|
|
|
11831
11748
|
* @return React element.
|
|
11832
11749
|
*/
|
|
11833
11750
|
const Dialog = forwardRef((props, ref) => {
|
|
11834
|
-
if (!DOCUMENT
|
|
11751
|
+
if (!DOCUMENT) {
|
|
11835
11752
|
// Can't render in SSR.
|
|
11836
11753
|
return null;
|
|
11837
11754
|
}
|
|
@@ -14240,7 +14157,7 @@ const Lightbox = forwardRef((props, ref) => {
|
|
|
14240
14157
|
zIndex,
|
|
14241
14158
|
...forwardedProps
|
|
14242
14159
|
} = props;
|
|
14243
|
-
if (!DOCUMENT
|
|
14160
|
+
if (!DOCUMENT) {
|
|
14244
14161
|
// Can't render in SSR.
|
|
14245
14162
|
return null;
|
|
14246
14163
|
}
|
|
@@ -15199,7 +15116,7 @@ const Notification = forwardRef((props, ref) => {
|
|
|
15199
15116
|
style,
|
|
15200
15117
|
...forwardedProps
|
|
15201
15118
|
} = props;
|
|
15202
|
-
if (!DOCUMENT
|
|
15119
|
+
if (!DOCUMENT) {
|
|
15203
15120
|
// Can't render in SSR.
|
|
15204
15121
|
return null;
|
|
15205
15122
|
}
|