@lumx/react 3.0.4 → 3.0.5-alpha.2
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.d.ts +2 -0
- package/index.js +82 -63
- package/index.js.map +1 -1
- package/package.json +4 -4
- package/src/components/dialog/Dialog.tsx +5 -5
- package/src/components/expansion-panel/ExpansionPanel.test.tsx +64 -93
- package/src/components/expansion-panel/ExpansionPanel.tsx +1 -0
- package/src/components/lightbox/Lightbox.tsx +2 -4
- package/src/components/notification/Notification.tsx +7 -5
- package/src/components/radio-button/RadioButton.tsx +10 -5
- package/src/components/radio-button/__snapshots__/RadioButton.test.tsx.snap +2 -0
- package/src/components/switch/Switch.tsx +5 -4
- package/src/components/switch/__snapshots__/Switch.test.tsx.snap +3 -0
- package/src/hooks/useTransitionVisibility.ts +54 -0
- package/src/utils/userHasReducedMotion.ts +7 -0
- package/src/components/expansion-panel/__snapshots__/ExpansionPanel.test.tsx.snap +0 -32
- package/src/hooks/useDelayedVisibility.tsx +0 -44
package/index.d.ts
CHANGED
|
@@ -1802,6 +1802,8 @@ interface RadioButtonProps extends GenericProps, HasTheme {
|
|
|
1802
1802
|
value?: string;
|
|
1803
1803
|
/** On change callback. */
|
|
1804
1804
|
onChange?(value?: string, name?: string, event?: SyntheticEvent): void;
|
|
1805
|
+
/** optional props for input */
|
|
1806
|
+
inputProps?: InputHTMLAttributes<HTMLInputElement>;
|
|
1805
1807
|
}
|
|
1806
1808
|
/**
|
|
1807
1809
|
* RadioButton component.
|
package/index.js
CHANGED
|
@@ -343,13 +343,6 @@ function uid(len) {
|
|
|
343
343
|
*/
|
|
344
344
|
const CSS_PREFIX = 'lumx';
|
|
345
345
|
|
|
346
|
-
/**
|
|
347
|
-
* Animation duration constants. Take into consideration that if you change one of these variables,
|
|
348
|
-
* you need to update their scss counterpart as well
|
|
349
|
-
*/
|
|
350
|
-
const DIALOG_TRANSITION_DURATION = 400;
|
|
351
|
-
const NOTIFICATION_TRANSITION_DURATION = 200;
|
|
352
|
-
|
|
353
346
|
/**
|
|
354
347
|
* Delay on hover after which we open or close the tooltip.
|
|
355
348
|
* Only applies to devices supporting pointer hover.
|
|
@@ -2465,42 +2458,6 @@ function partitionMulti(elements, predicates) {
|
|
|
2465
2458
|
return reduce(predicates, (partitioned, predicate) => concat(dropRight(partitioned), partition(last(partitioned), predicate)), [elements]);
|
|
2466
2459
|
}
|
|
2467
2460
|
|
|
2468
|
-
/**
|
|
2469
|
-
* Returns true if the component is visible taking into account the component's
|
|
2470
|
-
* own visibility and the animations delay
|
|
2471
|
-
*
|
|
2472
|
-
* @param isComponentVisible Whether the component intends to be visible or not.
|
|
2473
|
-
* @param transitionDuration time in ms that the transition takes for the specific component.
|
|
2474
|
-
* @param onVisibilityChange Callback called when the visibility changes.
|
|
2475
|
-
* @return true if the component should be rendered
|
|
2476
|
-
*/
|
|
2477
|
-
function useDelayedVisibility(isComponentVisible, transitionDuration, onVisibilityChange) {
|
|
2478
|
-
// Delay visibility to account for the 400ms of CSS opacity animation.
|
|
2479
|
-
const [isVisible, setVisible] = useState(isComponentVisible);
|
|
2480
|
-
useEffect(() => {
|
|
2481
|
-
if (isComponentVisible) {
|
|
2482
|
-
setVisible(true);
|
|
2483
|
-
} else {
|
|
2484
|
-
setTimeout(() => setVisible(false), transitionDuration);
|
|
2485
|
-
}
|
|
2486
|
-
}, [isComponentVisible, transitionDuration]);
|
|
2487
|
-
|
|
2488
|
-
/**
|
|
2489
|
-
* Since we don't want onVisibiltyChange function to trigger itself if when it changes,
|
|
2490
|
-
* we store the previous visibility and only trigger when visibility is different
|
|
2491
|
-
* than previous value.
|
|
2492
|
-
*/
|
|
2493
|
-
|
|
2494
|
-
const previousVisibility = useRef(isVisible);
|
|
2495
|
-
useEffect(() => {
|
|
2496
|
-
if (onVisibilityChange && previousVisibility.current !== isVisible) {
|
|
2497
|
-
onVisibilityChange(isVisible);
|
|
2498
|
-
previousVisibility.current = isVisible;
|
|
2499
|
-
}
|
|
2500
|
-
}, [isVisible, onVisibilityChange]);
|
|
2501
|
-
return isComponentVisible || isVisible;
|
|
2502
|
-
}
|
|
2503
|
-
|
|
2504
2461
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
2505
2462
|
|
|
2506
2463
|
// Older browsers don't support event options, feature detect it.
|
|
@@ -2716,6 +2673,62 @@ const useDisableBodyScroll = modalElement => {
|
|
|
2716
2673
|
}, [modalElement]);
|
|
2717
2674
|
};
|
|
2718
2675
|
|
|
2676
|
+
const userHasReducedMotion = () => {
|
|
2677
|
+
try {
|
|
2678
|
+
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
2679
|
+
} catch (e) {
|
|
2680
|
+
return false;
|
|
2681
|
+
}
|
|
2682
|
+
};
|
|
2683
|
+
|
|
2684
|
+
/**
|
|
2685
|
+
* Returns true if the component is visible tracking the opacity transition.
|
|
2686
|
+
*
|
|
2687
|
+
* @param ref Element on which to listen the transition event.
|
|
2688
|
+
* @param isComponentVisible Whether the component intends to be visible or not.
|
|
2689
|
+
* @param onVisibilityChange Callback called when the visibility changes.
|
|
2690
|
+
* @return true if the component should be rendered
|
|
2691
|
+
*/
|
|
2692
|
+
const useTransitionVisibility = (ref, isComponentVisible, onVisibilityChange) => {
|
|
2693
|
+
const [isVisible, setVisible] = useState(isComponentVisible);
|
|
2694
|
+
const previousVisibility = useRef(isVisible);
|
|
2695
|
+
|
|
2696
|
+
// On component visibility change.
|
|
2697
|
+
useEffect(() => {
|
|
2698
|
+
if (isComponentVisible) {
|
|
2699
|
+
setVisible(true);
|
|
2700
|
+
return undefined;
|
|
2701
|
+
}
|
|
2702
|
+
const {
|
|
2703
|
+
current: element
|
|
2704
|
+
} = ref;
|
|
2705
|
+
|
|
2706
|
+
// Transition event is not supported or the user prefers reduced motion.
|
|
2707
|
+
// => Skip `transitionend` event listening and set visibility to false directly.
|
|
2708
|
+
if (!element || !window.TransitionEvent || userHasReducedMotion()) {
|
|
2709
|
+
setVisible(false);
|
|
2710
|
+
return undefined;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
// Update visibility on opacity transition end.
|
|
2714
|
+
const onTransitionEnd = e => {
|
|
2715
|
+
if (e.target !== ref.current || e.propertyName !== 'opacity') return;
|
|
2716
|
+
setVisible(wasVisible => !wasVisible);
|
|
2717
|
+
};
|
|
2718
|
+
element.addEventListener('transitionend', onTransitionEnd);
|
|
2719
|
+
return () => {
|
|
2720
|
+
element.removeEventListener('transitionend', onTransitionEnd);
|
|
2721
|
+
};
|
|
2722
|
+
}, [isComponentVisible, ref]);
|
|
2723
|
+
useEffect(() => {
|
|
2724
|
+
if (onVisibilityChange && previousVisibility.current !== isVisible) {
|
|
2725
|
+
onVisibilityChange(isVisible);
|
|
2726
|
+
previousVisibility.current = isVisible;
|
|
2727
|
+
}
|
|
2728
|
+
}, [isVisible, onVisibilityChange]);
|
|
2729
|
+
return isVisible || isComponentVisible;
|
|
2730
|
+
};
|
|
2731
|
+
|
|
2719
2732
|
const _excluded$h = ["children", "className", "header", "focusElement", "forceFooterDivider", "forceHeaderDivider", "footer", "isLoading", "isOpen", "onClose", "parentElement", "contentRef", "preventAutoClose", "size", "zIndex", "dialogProps", "onVisibilityChange"];
|
|
2720
2733
|
|
|
2721
2734
|
/**
|
|
@@ -2827,14 +2840,14 @@ const Dialog = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
2827
2840
|
const footerChildProps = footerChild === null || footerChild === void 0 ? void 0 : footerChild.props;
|
|
2828
2841
|
const footerChildContent = footerChildProps === null || footerChildProps === void 0 ? void 0 : footerChildProps.children;
|
|
2829
2842
|
|
|
2830
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2831
|
-
const isVisible = useDelayedVisibility(Boolean(isOpen), DIALOG_TRANSITION_DURATION, onVisibilityChange);
|
|
2832
|
-
|
|
2833
2843
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2834
2844
|
const clickAwayRefs = useRef([wrapperRef]);
|
|
2835
2845
|
|
|
2836
2846
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2837
2847
|
const rootRef = useRef(null);
|
|
2848
|
+
|
|
2849
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
2850
|
+
const isVisible = useTransitionVisibility(rootRef, Boolean(isOpen), onVisibilityChange);
|
|
2838
2851
|
return isOpen || isVisible ? /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement("div", _extends({
|
|
2839
2852
|
ref: mergeRefs(rootRef, ref)
|
|
2840
2853
|
}, forwardedProps, {
|
|
@@ -6402,7 +6415,8 @@ const ExpansionPanel = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
6402
6415
|
}, /*#__PURE__*/React.createElement(IconButton, _extends({}, toggleButtonProps, {
|
|
6403
6416
|
color: color,
|
|
6404
6417
|
emphasis: Emphasis.low,
|
|
6405
|
-
icon: isOpen ? mdiChevronUp : mdiChevronDown
|
|
6418
|
+
icon: isOpen ? mdiChevronUp : mdiChevronDown,
|
|
6419
|
+
"aria-expanded": isOpen || 'false'
|
|
6406
6420
|
})))), (isOpen || isContentVisible()) && /*#__PURE__*/React.createElement("div", {
|
|
6407
6421
|
className: `${CLASSNAME$k}__wrapper`,
|
|
6408
6422
|
style: {
|
|
@@ -7266,7 +7280,6 @@ InputLabel.className = CLASSNAME$w;
|
|
|
7266
7280
|
InputLabel.defaultProps = DEFAULT_PROPS$s;
|
|
7267
7281
|
|
|
7268
7282
|
const _excluded$B = ["ariaLabel", "children", "className", "closeButtonProps", "isOpen", "onClose", "parentElement", "preventAutoClose", "theme", "zIndex"];
|
|
7269
|
-
const LIGHTBOX_TRANSITION_DURATION = 400;
|
|
7270
7283
|
|
|
7271
7284
|
/**
|
|
7272
7285
|
* Defines the props of the component.
|
|
@@ -7318,7 +7331,7 @@ const Lightbox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
7318
7331
|
useDisableBodyScroll(isOpen && wrapperRef.current);
|
|
7319
7332
|
|
|
7320
7333
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
7321
|
-
const isVisible =
|
|
7334
|
+
const isVisible = useTransitionVisibility(wrapperRef, !!isOpen);
|
|
7322
7335
|
|
|
7323
7336
|
// Handle focus trap.
|
|
7324
7337
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -7906,7 +7919,8 @@ const Notification = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
7906
7919
|
color,
|
|
7907
7920
|
icon
|
|
7908
7921
|
} = NOTIFICATION_CONFIGURATION[type] || {};
|
|
7909
|
-
const
|
|
7922
|
+
const rootRef = useRef(null);
|
|
7923
|
+
const isVisible = useTransitionVisibility(rootRef, !!isOpen);
|
|
7910
7924
|
const hasAction = Boolean(onActionClick) && Boolean(actionLabel);
|
|
7911
7925
|
const handleCallback = evt => {
|
|
7912
7926
|
if (isFunction(onActionClick)) {
|
|
@@ -7918,7 +7932,7 @@ const Notification = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
7918
7932
|
/*#__PURE__*/
|
|
7919
7933
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
7920
7934
|
React.createElement("div", _extends({
|
|
7921
|
-
ref: ref,
|
|
7935
|
+
ref: mergeRefs(ref, rootRef),
|
|
7922
7936
|
role: "alert"
|
|
7923
7937
|
}, forwardedProps, {
|
|
7924
7938
|
className: classnames(className, handleBasicClasses({
|
|
@@ -8607,7 +8621,7 @@ ProgressTrackerStepPanel.displayName = COMPONENT_NAME$M;
|
|
|
8607
8621
|
ProgressTrackerStepPanel.className = CLASSNAME$J;
|
|
8608
8622
|
ProgressTrackerStepPanel.defaultProps = DEFAULT_PROPS$B;
|
|
8609
8623
|
|
|
8610
|
-
const _excluded$P = ["checked", "className", "disabled", "helper", "id", "inputRef", "isChecked", "isDisabled", "label", "name", "onChange", "theme", "value"];
|
|
8624
|
+
const _excluded$P = ["checked", "className", "disabled", "helper", "id", "inputRef", "isChecked", "isDisabled", "label", "name", "onChange", "theme", "value", "inputProps"];
|
|
8611
8625
|
|
|
8612
8626
|
/**
|
|
8613
8627
|
* Defines the props of the component.
|
|
@@ -8651,10 +8665,11 @@ const RadioButton = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
8651
8665
|
name,
|
|
8652
8666
|
onChange,
|
|
8653
8667
|
theme,
|
|
8654
|
-
value
|
|
8668
|
+
value,
|
|
8669
|
+
inputProps
|
|
8655
8670
|
} = props,
|
|
8656
8671
|
forwardedProps = _objectWithoutProperties(props, _excluded$P);
|
|
8657
|
-
const
|
|
8672
|
+
const inputId = useMemo(() => id || `${CLASSNAME$K.toLowerCase()}-${uid()}`, [id]);
|
|
8658
8673
|
const handleChange = event => {
|
|
8659
8674
|
if (onChange) {
|
|
8660
8675
|
onChange(value, name, event);
|
|
@@ -8672,18 +8687,19 @@ const RadioButton = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
8672
8687
|
}))
|
|
8673
8688
|
}), /*#__PURE__*/React.createElement("div", {
|
|
8674
8689
|
className: `${CLASSNAME$K}__input-wrapper`
|
|
8675
|
-
}, /*#__PURE__*/React.createElement("input", {
|
|
8690
|
+
}, /*#__PURE__*/React.createElement("input", _extends({
|
|
8676
8691
|
ref: inputRef,
|
|
8677
8692
|
className: `${CLASSNAME$K}__input-native`,
|
|
8678
8693
|
disabled: isDisabled,
|
|
8679
|
-
id:
|
|
8694
|
+
id: inputId,
|
|
8680
8695
|
tabIndex: isDisabled ? -1 : 0,
|
|
8681
8696
|
type: "radio",
|
|
8682
8697
|
name: name,
|
|
8683
8698
|
value: value,
|
|
8684
8699
|
checked: isChecked,
|
|
8685
|
-
onChange: handleChange
|
|
8686
|
-
|
|
8700
|
+
onChange: handleChange,
|
|
8701
|
+
"aria-describedby": helper ? `${inputId}-helper` : undefined
|
|
8702
|
+
}, inputProps)), /*#__PURE__*/React.createElement("div", {
|
|
8687
8703
|
className: `${CLASSNAME$K}__input-placeholder`
|
|
8688
8704
|
}, /*#__PURE__*/React.createElement("div", {
|
|
8689
8705
|
className: `${CLASSNAME$K}__input-background`
|
|
@@ -8692,10 +8708,11 @@ const RadioButton = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
8692
8708
|
}))), /*#__PURE__*/React.createElement("div", {
|
|
8693
8709
|
className: `${CLASSNAME$K}__content`
|
|
8694
8710
|
}, label && /*#__PURE__*/React.createElement(InputLabel, {
|
|
8695
|
-
htmlFor:
|
|
8711
|
+
htmlFor: inputId,
|
|
8696
8712
|
theme: theme,
|
|
8697
8713
|
className: `${CLASSNAME$K}__label`
|
|
8698
8714
|
}, label), helper && /*#__PURE__*/React.createElement(InputHelper, {
|
|
8715
|
+
id: `${inputId}-helper`,
|
|
8699
8716
|
theme: theme,
|
|
8700
8717
|
className: `${CLASSNAME$K}__helper`
|
|
8701
8718
|
}, helper)));
|
|
@@ -10572,7 +10589,7 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
10572
10589
|
inputProps = {}
|
|
10573
10590
|
} = props,
|
|
10574
10591
|
forwardedProps = _objectWithoutProperties(props, _excluded$13);
|
|
10575
|
-
const
|
|
10592
|
+
const inputId = useMemo(() => id || `switch-${uid()}`, [id]);
|
|
10576
10593
|
const handleChange = event => {
|
|
10577
10594
|
if (onChange) {
|
|
10578
10595
|
onChange(!isChecked, value, name, event);
|
|
@@ -10595,14 +10612,15 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
10595
10612
|
}, /*#__PURE__*/React.createElement("input", _extends({
|
|
10596
10613
|
type: "checkbox",
|
|
10597
10614
|
role: "switch",
|
|
10598
|
-
id:
|
|
10615
|
+
id: inputId,
|
|
10599
10616
|
className: `${CLASSNAME$Z}__input-native`,
|
|
10600
10617
|
name: name,
|
|
10601
10618
|
value: value,
|
|
10602
10619
|
disabled: isDisabled,
|
|
10603
10620
|
checked: isChecked,
|
|
10604
10621
|
"aria-checked": Boolean(isChecked),
|
|
10605
|
-
onChange: handleChange
|
|
10622
|
+
onChange: handleChange,
|
|
10623
|
+
"aria-describedby": helper ? `${inputId}-helper` : undefined
|
|
10606
10624
|
}, inputProps)), /*#__PURE__*/React.createElement("div", {
|
|
10607
10625
|
className: `${CLASSNAME$Z}__input-placeholder`
|
|
10608
10626
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -10612,10 +10630,11 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
10612
10630
|
}))), Children.count(children) > 0 && /*#__PURE__*/React.createElement("div", {
|
|
10613
10631
|
className: `${CLASSNAME$Z}__content`
|
|
10614
10632
|
}, /*#__PURE__*/React.createElement(InputLabel, {
|
|
10615
|
-
htmlFor:
|
|
10633
|
+
htmlFor: inputId,
|
|
10616
10634
|
theme: theme,
|
|
10617
10635
|
className: `${CLASSNAME$Z}__label`
|
|
10618
10636
|
}, children), !isEmpty(helper) && /*#__PURE__*/React.createElement(InputHelper, {
|
|
10637
|
+
id: `${inputId}-helper`,
|
|
10619
10638
|
theme: theme,
|
|
10620
10639
|
className: `${CLASSNAME$Z}__helper`
|
|
10621
10640
|
}, helper)));
|