@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 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 = useDelayedVisibility(!!isOpen, LIGHTBOX_TRANSITION_DURATION);
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 isVisible = useDelayedVisibility(!!isOpen, NOTIFICATION_TRANSITION_DURATION);
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 radioButtonId = useMemo(() => id || `${CLASSNAME$K.toLowerCase()}-${uid()}`, [id]);
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: radioButtonId,
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
- }), /*#__PURE__*/React.createElement("div", {
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: radioButtonId,
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 switchId = useMemo(() => id || `switch-${uid()}`, [id]);
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: switchId,
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: switchId,
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)));