@lumx/react 3.8.2-alpha.2 → 3.9.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.
Files changed (34) hide show
  1. package/index.d.ts +1 -1
  2. package/index.js +53 -39
  3. package/index.js.map +1 -1
  4. package/package.json +4 -5
  5. package/src/components/alert-dialog/AlertDialog.test.tsx +1 -1
  6. package/src/components/alert-dialog/AlertDialog.tsx +3 -2
  7. package/src/components/checkbox/Checkbox.tsx +4 -3
  8. package/src/components/date-picker/DatePickerControlled.tsx +2 -3
  9. package/src/components/message/Message.tsx +1 -1
  10. package/src/components/navigation/NavigationSection.tsx +4 -3
  11. package/src/components/notification/constants.ts +1 -1
  12. package/src/components/radio-button/RadioButton.tsx +4 -3
  13. package/src/components/select/Select.test.tsx +1 -1
  14. package/src/components/select/SelectMultiple.test.tsx +1 -1
  15. package/src/components/select/WithSelectContext.tsx +4 -3
  16. package/src/components/side-navigation/SideNavigationItem.test.tsx +1 -1
  17. package/src/components/side-navigation/SideNavigationItem.tsx +2 -2
  18. package/src/components/slider/Slider.test.tsx +1 -1
  19. package/src/components/slider/Slider.tsx +3 -2
  20. package/src/components/switch/Switch.test.tsx +1 -1
  21. package/src/components/switch/Switch.tsx +4 -3
  22. package/src/components/tabs/state.ts +4 -6
  23. package/src/components/text-field/TextField.tsx +6 -15
  24. package/src/components/tooltip/Tooltip.test.tsx +1 -1
  25. package/src/components/tooltip/Tooltip.tsx +4 -4
  26. package/src/components/uploader/Uploader.tsx +3 -2
  27. package/src/components/user-block/UserBlock.stories.tsx +1 -1
  28. package/src/components/user-block/UserBlock.tsx +2 -2
  29. package/src/hooks/useId.test.tsx +23 -0
  30. package/src/hooks/useId.ts +15 -0
  31. package/src/hooks/useSlideshowControls.ts +7 -4
  32. package/src/stories/generated/UserBlock/Demos.stories.tsx +1 -0
  33. package/src/utils/date/formatDayNumber.test.ts +12 -0
  34. package/src/utils/date/formatDayNumber.ts +5 -0
package/index.d.ts CHANGED
@@ -2943,7 +2943,7 @@ declare const Uploader: Comp<UploaderProps>;
2943
2943
  /**
2944
2944
  * User block sizes.
2945
2945
  */
2946
- type UserBlockSize = Extract<Size, 's' | 'm' | 'l'>;
2946
+ type UserBlockSize = Extract<Size, 'xs' | 's' | 'm' | 'l'>;
2947
2947
  /**
2948
2948
  * Defines the props of the component.
2949
2949
  */
package/index.js CHANGED
@@ -19,7 +19,6 @@ import pick from 'lodash/pick';
19
19
  import isInteger from 'lodash/isInteger';
20
20
  import throttle from 'lodash/throttle';
21
21
  import take from 'lodash/take';
22
- import uniqueId from 'lodash/uniqueId';
23
22
  import isObject from 'lodash/isObject';
24
23
  import range from 'lodash/range';
25
24
  import chunk from 'lodash/chunk';
@@ -344,20 +343,6 @@ var classnames = createCommonjsModule(function (module) {
344
343
 
345
344
  const mdiAlert='M13 14h-2V9h2m0 9h-2v-2h2M1 21h22L12 2z';const mdiAlertCircle='M13 13h-2V7h2m0 10h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2';const mdiArrowDown='M11 4h2v12l5.5-5.5 1.42 1.42L12 19.84l-7.92-7.92L5.5 10.5 11 16z';const mdiArrowUp='M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z';const mdiCheck='M21 7 9 19l-5.5-5.5 1.41-1.41L9 16.17 19.59 5.59z';const mdiCheckCircle='M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8z';const mdiChevronDown='M7.41 8.58 12 13.17l4.59-4.59L18 10l-6 6-6-6z';const mdiChevronLeft='M15.41 16.58 10.83 12l4.58-4.59L14 6l-6 6 6 6z';const mdiChevronRight='M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6z';const mdiChevronUp='M7.41 15.41 12 10.83l4.59 4.58L18 14l-6-6-6 6z';const mdiClose='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z';const mdiCloseCircle='M12 2a10 10 0 1 1 0 20 10 10 0 1 1 0-20m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41z';const mdiDragVertical='M9 3h2v2H9zm4 0h2v2h-2zM9 7h2v2H9zm4 0h2v2h-2zm-4 4h2v2H9zm4 0h2v2h-2zm-4 4h2v2H9zm4 0h2v2h-2zm-4 4h2v2H9zm4 0h2v2h-2z';const mdiImageBroken='M19 3a2 2 0 0 1 2 2v6h-2v2h-2v2h-2v2h-2v2h-2v2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2zm2 12v4a2 2 0 0 1-2 2h-4v-2h2v-2h2v-2zm-2-6.5a.5.5 0 0 0-.5-.5h-13a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 .5.5H11v-1h2v-2h2v-2h2V9h2z';const mdiInformation='M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2';const mdiMagnifyMinusOutline='M15.5 14h-.79l-.28-.27A6.5 6.5 0 0 0 16 9.5 6.5 6.5 0 0 0 9.5 3 6.5 6.5 0 0 0 3 9.5 6.5 6.5 0 0 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 5 1.5-1.5zm-6 0C7 14 5 12 5 9.5S7 5 9.5 5 14 7 14 9.5 12 14 9.5 14M7 9h5v1H7z';const mdiMagnifyPlusOutline='m15.5 14 5 5-1.5 1.5-5-5v-.79l-.27-.28A6.5 6.5 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3 6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.57 4.23l.28.27zm-6 0C12 14 14 12 14 9.5S12 5 9.5 5 5 7 5 9.5 7 14 9.5 14m2.5-4h-2v2H9v-2H7V9h2V7h1v2h2z';const mdiMenuDown='m7 10 5 5 5-5z';const mdiMinus='M19 13H5v-2h14z';const mdiPauseCircleOutline='M13 16V8h2v8zm-4 0V8h2v8zm3-14a10 10 0 0 1 10 10 10 10 0 0 1-10 10A10 10 0 0 1 2 12 10 10 0 0 1 12 2m0 2a8 8 0 0 0-8 8 8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0-8-8';const mdiPlayCircleOutline='M12 20a8.01 8.01 0 0 1 0-16 8.01 8.01 0 0 1 0 16m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m-2 14.5 6-4.5-6-4.5z';const mdiRadioboxBlank='M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2';const mdiRadioboxMarked='M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 5a5 5 0 0 0-5 5 5 5 0 0 0 5 5 5 5 0 0 0 5-5 5 5 0 0 0-5-5';
346
345
 
347
- var IDX=256, HEX=[], SIZE=256, BUFFER;
348
- while (IDX--) HEX[IDX] = (IDX + 256).toString(16).substring(1);
349
-
350
- function uid(len) {
351
- var i=0, tmp=(len || 11);
352
- if (!BUFFER || ((IDX + tmp) > SIZE*2)) {
353
- for (BUFFER='',IDX=0; i < SIZE; i++) {
354
- BUFFER += HEX[Math.random() * 256 | 0];
355
- }
356
- }
357
-
358
- return BUFFER.substring(IDX, IDX++ + tmp);
359
- }
360
-
361
346
  /**
362
347
  * The prefix to use for the CSS classes.
363
348
  */
@@ -633,6 +618,20 @@ const getTypographyClassName = typography => {
633
618
  return `lumx-typography-${typography}`;
634
619
  };
635
620
 
621
+ let i = 0;
622
+
623
+ /**
624
+ * Generate a unique id (for use in a11y or other id based DOM linking).
625
+ *
626
+ * (Tries to emulate React 18 useId hook, to remove once we upgrade React)
627
+ */
628
+ function useId() {
629
+ return React.useMemo(() => {
630
+ i += 1;
631
+ return `:lumx${i}:`;
632
+ }, []);
633
+ }
634
+
636
635
  const _excluded$1 = ["id", "title", "className", "cancelProps", "confirmProps", "kind", "size", "dialogProps", "children"],
637
636
  _excluded2 = ["label", "onClick"],
638
637
  _excluded3 = ["label", "onClick"];
@@ -706,7 +705,8 @@ const AlertDialog = /*#__PURE__*/forwardRef((props, ref) => {
706
705
  } = CONFIG[kind] || {};
707
706
 
708
707
  // Define a unique ID to target title and description for aria attributes.
709
- const uniqueId = React.useMemo(() => id || uid(), [id]);
708
+ const generatedId = useId();
709
+ const uniqueId = id || generatedId;
710
710
  const titleId = `${uniqueId}-title`;
711
711
  const descriptionId = `${uniqueId}-description`;
712
712
 
@@ -1654,7 +1654,8 @@ const Checkbox = /*#__PURE__*/forwardRef((props, ref) => {
1654
1654
  } = props,
1655
1655
  forwardedProps = _objectWithoutProperties(props, _excluded$b);
1656
1656
  const localInputRef = React.useRef(null);
1657
- const inputId = useMemo(() => id || `${CLASSNAME$8.toLowerCase()}-${uid()}`, [id]);
1657
+ const generatedInputId = useId();
1658
+ const inputId = id || generatedInputId;
1658
1659
  const handleChange = event => {
1659
1660
  if (onChange) {
1660
1661
  onChange(!isChecked, value, name, event);
@@ -2299,6 +2300,14 @@ const getYearDisplayName = locale => {
2299
2300
  return label;
2300
2301
  };
2301
2302
 
2303
+ function formatDayNumber(locale, date) {
2304
+ const formattedDate = date.toLocaleDateString(locale, {
2305
+ day: 'numeric'
2306
+ });
2307
+ if (formattedDate.match(/\d/)) return formattedDate.replace(/\D*(\d+)\D*/g, '$1');
2308
+ return formattedDate;
2309
+ }
2310
+
2302
2311
  /**
2303
2312
  * Defines the props of the component.
2304
2313
  */
@@ -2463,9 +2472,7 @@ const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2463
2472
  onClick: () => onChange(date)
2464
2473
  }, /*#__PURE__*/React.createElement("span", {
2465
2474
  "aria-hidden": true
2466
- }, date.toLocaleDateString(locale, {
2467
- day: 'numeric'
2468
- })), /*#__PURE__*/React.createElement("span", {
2475
+ }, formatDayNumber(locale, date)), /*#__PURE__*/React.createElement("span", {
2469
2476
  className: "visually-hidden"
2470
2477
  }, date.toLocaleDateString(locale, {
2471
2478
  day: 'numeric',
@@ -9203,7 +9210,7 @@ const CONFIG$1 = {
9203
9210
  icon: mdiAlert
9204
9211
  },
9205
9212
  [Kind.info]: {
9206
- color: ColorPalette.dark,
9213
+ color: ColorPalette.blue,
9207
9214
  icon: mdiInformation
9208
9215
  },
9209
9216
  [Kind.success]: {
@@ -9449,7 +9456,7 @@ const NavigationSection = Object.assign( /*#__PURE__*/forwardRef((props, ref) =>
9449
9456
  forwardedProps = _objectWithoutProperties(props, _excluded$N);
9450
9457
  const [isOpen, setIsOpen] = useState(false);
9451
9458
  const buttonRef = useRef(null);
9452
- const sectionId = useMemo(() => uniqueId('section'), []);
9459
+ const sectionId = useId();
9453
9460
  const {
9454
9461
  orientation
9455
9462
  } = useContext(NavigationContext) || {};
@@ -9569,7 +9576,7 @@ const NOTIFICATION_CONFIGURATION = {
9569
9576
  icon: mdiAlert
9570
9577
  },
9571
9578
  info: {
9572
- color: 'dark',
9579
+ color: 'blue',
9573
9580
  icon: mdiInformation
9574
9581
  },
9575
9582
  success: {
@@ -10093,9 +10100,8 @@ const useTabProviderContext = (type, originalId) => {
10093
10100
  const [state, dispatch] = context;
10094
10101
 
10095
10102
  // Current tab or tab panel id.
10096
- const id = useMemo(() => originalId || `${type}-${uid()}`,
10097
- // eslint-disable-next-line react-hooks/exhaustive-deps
10098
- []);
10103
+ const generatedId = useId();
10104
+ const id = originalId || generatedId;
10099
10105
  useEffect(() => {
10100
10106
  // On mount: register tab or tab panel id.
10101
10107
  dispatch({
@@ -10563,7 +10569,8 @@ const RadioButton = /*#__PURE__*/forwardRef((props, ref) => {
10563
10569
  inputProps
10564
10570
  } = props,
10565
10571
  forwardedProps = _objectWithoutProperties(props, _excluded$Z);
10566
- const inputId = useMemo(() => id || `${CLASSNAME$S.toLowerCase()}-${uid()}`, [id]);
10572
+ const generatedInputId = useId();
10573
+ const inputId = id || generatedInputId;
10567
10574
  const handleChange = event => {
10568
10575
  if (onChange) {
10569
10576
  onChange(value, name, event);
@@ -10728,7 +10735,8 @@ const WithSelectContext = (SelectElement, _ref, ref) => {
10728
10735
  variant = DEFAULT_PROPS$H.variant
10729
10736
  } = _ref,
10730
10737
  forwardedProps = _objectWithoutProperties(_ref, _excluded$$);
10731
- const selectId = useMemo(() => id || `select-${uid()}`, [id]);
10738
+ const generatedSelectId = useId();
10739
+ const selectId = id || generatedSelectId;
10732
10740
  const anchorRef = useRef(null);
10733
10741
  const selectRef = useRef(null);
10734
10742
  const dropdownRef = useRef(null);
@@ -11155,7 +11163,7 @@ const SideNavigationItem = /*#__PURE__*/forwardRef((props, ref) => {
11155
11163
  const hasContent = !isEmpty(content);
11156
11164
  const shouldSplitActions = Boolean(onActionClick);
11157
11165
  const showChildren = hasContent && isOpen;
11158
- const contentId = React.useMemo(uid, []);
11166
+ const contentId = useId();
11159
11167
  const ariaProps = {};
11160
11168
  if (hasContent) {
11161
11169
  ariaProps['aria-expanded'] = !!showChildren;
@@ -11496,7 +11504,8 @@ const Slider = /*#__PURE__*/forwardRef((props, ref) => {
11496
11504
  value
11497
11505
  } = props,
11498
11506
  forwardedProps = _objectWithoutProperties(props, _excluded$18);
11499
- const sliderId = useMemo(() => id || `slider-${uid()}`, [id]);
11507
+ const generatedId = useId();
11508
+ const sliderId = id || generatedId;
11500
11509
  const sliderLabelId = useMemo(() => `label-${sliderId}`, [sliderId]);
11501
11510
  const sliderRef = useRef(null);
11502
11511
 
@@ -11843,8 +11852,10 @@ const useSlideshowControls = _ref => {
11843
11852
  if (!onChange) return;
11844
11853
  onChange(currentIndex);
11845
11854
  }, [currentIndex, onChange]);
11846
- const slideshowId = useMemo(() => id || uniqueId('slideshow'), [id]);
11847
- const slideshowSlidesId = useMemo(() => slidesId || uniqueId('slideshow-slides'), [slidesId]);
11855
+ const generatedSlideshowId = useId();
11856
+ const slideshowId = id || generatedSlideshowId;
11857
+ const generatedSlidesId = useId();
11858
+ const slideshowSlidesId = slidesId || generatedSlidesId;
11848
11859
  const toggleAutoPlay = () => {
11849
11860
  if (isSlideshowAutoPlaying) {
11850
11861
  stopAutoPlay();
@@ -12547,7 +12558,8 @@ const Switch = /*#__PURE__*/forwardRef((props, ref) => {
12547
12558
  inputProps = {}
12548
12559
  } = props,
12549
12560
  forwardedProps = _objectWithoutProperties(props, _excluded$1e);
12550
- const inputId = useMemo(() => id || `switch-${uid()}`, [id]);
12561
+ const generatedInputId = useId();
12562
+ const inputId = id || generatedInputId;
12551
12563
  const handleChange = event => {
12552
12564
  if (onChange) {
12553
12565
  onChange(!isChecked, value, name, event);
@@ -13349,7 +13361,8 @@ const TextField = /*#__PURE__*/forwardRef((props, ref) => {
13349
13361
  afterElement
13350
13362
  } = props,
13351
13363
  forwardedProps = _objectWithoutProperties(props, _excluded2$3);
13352
- const textFieldId = useMemo(() => id || `text-field-${uid()}`, [id]);
13364
+ const generatedTextFieldId = useId();
13365
+ const textFieldId = id || generatedTextFieldId;
13353
13366
  /** Keep a clean local input ref to manage focus */
13354
13367
  const localInputRef = useRef(null);
13355
13368
  /** Merge prop input ref and local input ref */
@@ -13360,8 +13373,8 @@ const TextField = /*#__PURE__*/forwardRef((props, ref) => {
13360
13373
  * we want to first use the most important one, which is the errorId. That way, screen readers will read first
13361
13374
  * the error and then the helper
13362
13375
  */
13363
- const helperId = helper ? `text-field-helper-${uid()}` : undefined;
13364
- const errorId = error ? `text-field-error-${uid()}` : undefined;
13376
+ const helperId = helper ? `text-field-helper-${generatedTextFieldId}` : undefined;
13377
+ const errorId = error ? `text-field-error-${generatedTextFieldId}` : undefined;
13365
13378
  const describedByIds = [errorId, helperId, forwardedProps['aria-describedby']].filter(Boolean);
13366
13379
  const describedById = describedByIds.length === 0 ? undefined : describedByIds.join(' ');
13367
13380
  const [isFocus, setFocus] = useState(false);
@@ -14118,7 +14131,7 @@ const Tooltip = /*#__PURE__*/forwardRef((props, ref) => {
14118
14131
  if (!DOCUMENT || !label) {
14119
14132
  return /*#__PURE__*/React.createElement(TooltipContextProvider, null, children);
14120
14133
  }
14121
- const id = useMemo(() => `tooltip-${uid()}`, []);
14134
+ const id = useId();
14122
14135
  const [popperElement, setPopperElement] = useState(null);
14123
14136
  const [anchorElement, setAnchorElement] = useState(null);
14124
14137
  const {
@@ -14227,7 +14240,8 @@ const Uploader = /*#__PURE__*/forwardRef((props, ref) => {
14227
14240
  forwardedProps = _objectWithoutProperties(props, _excluded$1s);
14228
14241
  // Adjust to square aspect ratio when using circle variants.
14229
14242
  const adjustedAspectRatio = variant === UploaderVariant.circle ? AspectRatio.square : aspectRatio;
14230
- const inputId = React.useMemo(() => (fileInputProps === null || fileInputProps === void 0 ? void 0 : fileInputProps.id) || uniqueId('uploader-input-'), [fileInputProps === null || fileInputProps === void 0 ? void 0 : fileInputProps.id]);
14243
+ const generatedInputId = useId();
14244
+ const inputId = (fileInputProps === null || fileInputProps === void 0 ? void 0 : fileInputProps.id) || generatedInputId;
14231
14245
  const [isDragHovering, unsetDragHovering, setDragHovering] = useBooleanState(false);
14232
14246
  const wrapper = fileInputProps ? {
14233
14247
  Component: 'label',
@@ -14370,7 +14384,7 @@ const UserBlock = /*#__PURE__*/forwardRef((props, ref) => {
14370
14384
  }
14371
14385
  return /*#__PURE__*/React.createElement(NameComponent, nProps, name);
14372
14386
  }, [avatarProps, isClickable, linkAs, linkProps, name, nameProps, onClick]);
14373
- const fieldsBlock = fields && componentSize !== Size.s && /*#__PURE__*/React.createElement("div", {
14387
+ const fieldsBlock = fields && componentSize !== Size.s && componentSize !== Size.xs && /*#__PURE__*/React.createElement("div", {
14374
14388
  className: `${CLASSNAME$1j}__fields`
14375
14389
  }, fields.map((field, idx) => /*#__PURE__*/React.createElement("span", {
14376
14390
  key: idx,