@lumx/react 3.19.0 → 3.19.1-alpha.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 (141) hide show
  1. package/index.d.ts +201 -117
  2. package/index.js +452 -464
  3. package/index.js.map +1 -1
  4. package/package.json +3 -3
  5. package/src/components/alert-dialog/AlertDialog.tsx +1 -1
  6. package/src/components/autocomplete/Autocomplete.tsx +1 -1
  7. package/src/components/autocomplete/AutocompleteMultiple.tsx +1 -1
  8. package/src/components/avatar/Avatar.tsx +1 -1
  9. package/src/components/badge/Badge.tsx +1 -1
  10. package/src/components/badge/BadgeWrapper.tsx +1 -1
  11. package/src/components/button/Button.test.tsx +5 -5
  12. package/src/components/button/Button.tsx +1 -1
  13. package/src/components/button/ButtonGroup.tsx +1 -1
  14. package/src/components/button/ButtonRoot.tsx +7 -37
  15. package/src/components/button/IconButton.tsx +1 -1
  16. package/src/components/checkbox/Checkbox.tsx +1 -1
  17. package/src/components/chip/Chip.tsx +2 -2
  18. package/src/components/chip/ChipGroup.tsx +2 -2
  19. package/src/components/comment-block/CommentBlock.tsx +1 -1
  20. package/src/components/date-picker/DatePickerControlled.tsx +1 -1
  21. package/src/components/date-picker/constants.ts +1 -1
  22. package/src/components/dialog/Dialog.tsx +1 -1
  23. package/src/components/divider/Divider.tsx +1 -1
  24. package/src/components/drag-handle/DragHandle.tsx +1 -1
  25. package/src/components/dropdown/Dropdown.tsx +1 -1
  26. package/src/components/expansion-panel/ExpansionPanel.tsx +1 -1
  27. package/src/components/flag/Flag.tsx +1 -1
  28. package/src/components/flex-box/FlexBox.tsx +2 -3
  29. package/src/components/generic-block/GenericBlock.tsx +1 -1
  30. package/src/components/grid/Grid.tsx +1 -1
  31. package/src/components/grid/GridItem.tsx +1 -1
  32. package/src/components/grid-column/GridColumn.tsx +1 -1
  33. package/src/components/heading/Heading.tsx +1 -1
  34. package/src/components/heading/constants.ts +1 -1
  35. package/src/components/icon/Icon.tsx +1 -1
  36. package/src/components/image-block/ImageBlock.tsx +1 -1
  37. package/src/components/image-lightbox/constants.ts +1 -1
  38. package/src/components/inline-list/InlineList.tsx +1 -1
  39. package/src/components/input-helper/InputHelper.tsx +1 -1
  40. package/src/components/input-label/InputLabel.test.tsx +1 -1
  41. package/src/components/input-label/InputLabel.tsx +1 -1
  42. package/src/components/lightbox/Lightbox.tsx +1 -1
  43. package/src/components/link/Link.test.tsx +8 -6
  44. package/src/components/link/Link.tsx +10 -21
  45. package/src/components/link-preview/LinkPreview.stories.tsx +1 -1
  46. package/src/components/link-preview/LinkPreview.test.tsx +1 -1
  47. package/src/components/link-preview/LinkPreview.tsx +1 -1
  48. package/src/components/list/List.tsx +1 -1
  49. package/src/components/list/ListDivider.tsx +1 -1
  50. package/src/components/list/ListItem.test.tsx +1 -3
  51. package/src/components/list/ListItem.tsx +20 -33
  52. package/src/components/list/ListSubheader.tsx +1 -1
  53. package/src/components/message/Message.tsx +1 -1
  54. package/src/components/mosaic/Mosaic.tsx +1 -1
  55. package/src/components/navigation/Navigation.test.tsx +1 -1
  56. package/src/components/navigation/Navigation.tsx +1 -1
  57. package/src/components/navigation/NavigationItem.tsx +7 -11
  58. package/src/components/navigation/NavigationSection.test.tsx +2 -1
  59. package/src/components/navigation/NavigationSection.tsx +5 -4
  60. package/src/components/navigation/context.tsx +2 -1
  61. package/src/components/notification/Notification.tsx +1 -1
  62. package/src/components/popover/Popover.tsx +1 -1
  63. package/src/components/popover-dialog/PopoverDialog.tsx +1 -1
  64. package/src/components/post-block/PostBlock.tsx +1 -1
  65. package/src/components/progress/Progress.tsx +1 -1
  66. package/src/components/progress/ProgressCircular.tsx +1 -1
  67. package/src/components/progress/ProgressLinear.tsx +1 -1
  68. package/src/components/progress-tracker/ProgressTracker.tsx +1 -1
  69. package/src/components/progress-tracker/ProgressTrackerStep.tsx +1 -1
  70. package/src/components/progress-tracker/ProgressTrackerStepPanel.tsx +1 -1
  71. package/src/components/radio-button/RadioButton.tsx +1 -1
  72. package/src/components/radio-button/RadioGroup.tsx +1 -1
  73. package/src/components/select/Select.test.tsx +1 -1
  74. package/src/components/select/Select.tsx +2 -2
  75. package/src/components/select/SelectMultiple.test.tsx +1 -1
  76. package/src/components/select/SelectMultiple.tsx +2 -2
  77. package/src/components/select/WithSelectContext.tsx +2 -2
  78. package/src/components/side-navigation/SideNavigation.tsx +1 -1
  79. package/src/components/side-navigation/SideNavigationItem.tsx +23 -28
  80. package/src/components/skeleton/SkeletonCircle.tsx +1 -1
  81. package/src/components/skeleton/SkeletonRectangle.tsx +1 -1
  82. package/src/components/skeleton/SkeletonTypography.tsx +1 -1
  83. package/src/components/slider/Slider.tsx +1 -1
  84. package/src/components/slideshow/Slides.tsx +1 -1
  85. package/src/components/slideshow/SlideshowControls.tsx +1 -1
  86. package/src/components/slideshow/SlideshowItem.tsx +1 -1
  87. package/src/components/slideshow/SlideshowItemGroup.tsx +1 -1
  88. package/src/components/switch/Switch.tsx +1 -1
  89. package/src/components/table/Table.tsx +1 -1
  90. package/src/components/table/TableBody.tsx +1 -1
  91. package/src/components/table/TableCell.tsx +1 -1
  92. package/src/components/table/TableHeader.tsx +1 -1
  93. package/src/components/table/TableRow.tsx +1 -1
  94. package/src/components/tabs/Tab.tsx +1 -1
  95. package/src/components/tabs/TabList.tsx +1 -1
  96. package/src/components/tabs/TabPanel.tsx +1 -1
  97. package/src/components/text/Text.tsx +1 -1
  98. package/src/components/text-field/TextField.test.tsx +1 -1
  99. package/src/components/text-field/TextField.tsx +1 -1
  100. package/src/components/thumbnail/Thumbnail.tsx +7 -12
  101. package/src/components/thumbnail/useFocusPointStyle.tsx +1 -1
  102. package/src/components/toolbar/Toolbar.tsx +1 -1
  103. package/src/components/tooltip/Tooltip.tsx +1 -1
  104. package/src/components/uploader/Uploader.tsx +1 -1
  105. package/src/components/user-block/UserBlock.tsx +1 -1
  106. package/src/hooks/useCallbackOnEscape.ts +1 -1
  107. package/src/index.ts +3 -1
  108. package/src/utils/partitionMulti.ts +2 -1
  109. package/src/utils/react/RawClickable.test.tsx +153 -0
  110. package/src/utils/react/RawClickable.tsx +65 -0
  111. package/src/utils/type/HasRequiredLinkHref.ts +1 -0
  112. package/src/utils/type/index.ts +3 -13
  113. package/src/components/index.ts +0 -160
  114. package/src/utils/browser/event.ts +0 -1
  115. package/src/utils/className/fontColorClass.test.ts +0 -15
  116. package/src/utils/className/fontColorClass.ts +0 -12
  117. package/src/utils/className/getBasicClass.test.ts +0 -20
  118. package/src/utils/className/getRootClassName.test.ts +0 -11
  119. package/src/utils/className/getRootClassName.ts +0 -24
  120. package/src/utils/className/getTypographyClassName.test.ts +0 -7
  121. package/src/utils/className/getTypographyClassName.ts +0 -9
  122. package/src/utils/className/handleBasicClasses.test.ts +0 -28
  123. package/src/utils/className/index.ts +0 -5
  124. package/src/utils/className/resolveColorWithVariants.test.ts +0 -33
  125. package/src/utils/className/resolveColorWithVariants.ts +0 -11
  126. package/src/utils/react/renderButtonOrLink.tsx +0 -16
  127. package/src/utils/react/renderLink.tsx +0 -17
  128. package/src/utils/type/Callback.ts +0 -4
  129. package/src/utils/type/Falsy.ts +0 -5
  130. package/src/utils/type/GenericProps.ts +0 -11
  131. package/src/utils/type/HasAriaLabelOrLabelledBy.ts +0 -19
  132. package/src/utils/type/HasClassName.ts +0 -6
  133. package/src/utils/type/HasCloseMode.ts +0 -7
  134. package/src/utils/type/HasTheme.ts +0 -8
  135. package/src/utils/type/HeadingElement.ts +0 -2
  136. package/src/utils/type/Point.ts +0 -4
  137. package/src/utils/type/Predicate.ts +0 -2
  138. package/src/utils/type/RectSize.ts +0 -4
  139. package/src/utils/type/TextElement.ts +0 -4
  140. package/src/utils/type/ValueOf.ts +0 -2
  141. package/src/utils/type/color/index.ts +0 -43
package/package.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "url": "https://github.com/lumapps/design-system/issues"
7
7
  },
8
8
  "dependencies": {
9
- "@lumx/core": "^3.19.0",
10
- "@lumx/icons": "^3.19.0",
9
+ "@lumx/core": "^3.19.1-alpha.0",
10
+ "@lumx/icons": "^3.19.1-alpha.0",
11
11
  "@popperjs/core": "^2.5.4",
12
12
  "body-scroll-lock": "^3.1.5",
13
13
  "classnames": "^2.3.2",
@@ -105,5 +105,5 @@
105
105
  "build:storybook": "storybook build"
106
106
  },
107
107
  "sideEffects": false,
108
- "version": "3.19.0"
108
+ "version": "3.19.1-alpha.0"
109
109
  }
@@ -15,7 +15,7 @@ import {
15
15
  ButtonProps,
16
16
  } from '@lumx/react';
17
17
  import { mdiAlert, mdiAlertCircle, mdiCheckCircle, mdiInformation } from '@lumx/icons';
18
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
18
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
19
19
  import { useId } from '@lumx/react/hooks/useId';
20
20
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
21
21
 
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { Dropdown, DropdownProps, IconButtonProps, Offset, Placement, TextField, TextFieldProps } from '@lumx/react';
6
6
 
7
7
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
8
- import { getRootClassName } from '@lumx/react/utils/className';
8
+ import { getRootClassName } from '@lumx/core/js/utils/className';
9
9
  import { useFocus } from '@lumx/react/hooks/useFocus';
10
10
  import { mergeRefs } from '@lumx/react/utils/react/mergeRefs';
11
11
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { mdiClose } from '@lumx/icons';
6
6
 
7
7
  import { Autocomplete, AutocompleteProps, Chip, HorizontalAlignment, Icon, Size } from '@lumx/react';
8
- import { getRootClassName } from '@lumx/react/utils/className';
8
+ import { getRootClassName } from '@lumx/core/js/utils/className';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
11
11
 
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { AspectRatio, Size, Theme, Thumbnail, ThumbnailProps } from '@lumx/react';
6
6
 
7
7
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
8
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
9
9
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
10
10
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
11
 
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { ColorPalette } from '@lumx/react';
6
6
  import { GenericProps } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  /**
@@ -2,7 +2,7 @@ import React, { ReactElement, ReactNode } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
- import { getRootClassName } from '@lumx/react/utils/className';
5
+ import { getRootClassName } from '@lumx/core/js/utils/className';
6
6
  import { GenericProps } from '@lumx/react/utils/type';
7
7
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
8
 
@@ -78,9 +78,10 @@ describe(`<${Button.displayName}>`, () => {
78
78
  it('should render disabled link', async () => {
79
79
  const onClick = jest.fn();
80
80
  const { button } = setup({ children: 'Label', disabled: true, href: 'https://example.com', onClick });
81
- // Disabled link do not exist so we fallback to a button
82
- expect(screen.queryByRole('link')).not.toBeInTheDocument();
83
- expect(button).toHaveAttribute('disabled');
81
+ expect(screen.queryByRole('link')).toBeInTheDocument();
82
+ expect(button).toHaveAttribute('aria-disabled', 'true');
83
+ // Simulate standard disabled state (not focusable)
84
+ expect(button).toHaveAttribute('tabindex', '-1');
84
85
  await userEvent.click(button);
85
86
  expect(onClick).not.toHaveBeenCalled();
86
87
  });
@@ -102,8 +103,7 @@ describe(`<${Button.displayName}>`, () => {
102
103
  onClick,
103
104
  });
104
105
  expect(button).toHaveAccessibleName('Label');
105
- // Disabled link do not exist so we fallback to a button
106
- expect(screen.queryByRole('link')).not.toBeInTheDocument();
106
+ expect(screen.queryByRole('link')).toBeInTheDocument();
107
107
  expect(button).toHaveAttribute('aria-disabled', 'true');
108
108
  await userEvent.click(button);
109
109
  expect(onClick).not.toHaveBeenCalled();
@@ -5,7 +5,7 @@ import isEmpty from 'lodash/isEmpty';
5
5
 
6
6
  import { Emphasis, Icon, Size, Theme, Text, ThemeProvider } from '@lumx/react';
7
7
  import { isComponent } from '@lumx/react/utils/type';
8
- import { getBasicClass, getRootClassName } from '@lumx/react/utils/className';
8
+ import { getBasicClass, getRootClassName } from '@lumx/core/js/utils/className';
9
9
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
10
10
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
11
 
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  import classNames from 'classnames';
4
4
 
5
5
  import { GenericProps } from '@lumx/react/utils/type';
6
- import { getRootClassName } from '@lumx/react/utils/className';
6
+ import { getRootClassName } from '@lumx/core/js/utils/className';
7
7
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
8
 
9
9
  /**
@@ -1,17 +1,15 @@
1
1
  import React, { AriaAttributes, ButtonHTMLAttributes, DetailedHTMLProps, RefObject } from 'react';
2
2
 
3
- import isEmpty from 'lodash/isEmpty';
4
-
5
3
  import classNames from 'classnames';
6
4
 
7
5
  import { ColorPalette, Emphasis, Size, Theme } from '@lumx/react';
8
6
  import { CSS_PREFIX } from '@lumx/react/constants';
9
7
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
10
- import { handleBasicClasses } from '@lumx/react/utils/className';
11
- import { renderLink } from '@lumx/react/utils/react/renderLink';
8
+ import { handleBasicClasses } from '@lumx/core/js/utils/className';
12
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
13
- import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
14
10
  import { HasAriaDisabled } from '@lumx/react/utils/type/HasAriaDisabled';
11
+ import { RawClickable } from '@lumx/react/utils/react/RawClickable';
12
+ import { useDisableStateProps } from '@lumx/react/utils/disabled';
15
13
 
16
14
  type HTMLButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
17
15
 
@@ -107,18 +105,14 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
107
105
  color,
108
106
  emphasis,
109
107
  hasBackground,
110
- href,
111
108
  isSelected,
112
109
  isActive,
113
110
  isFocused,
114
111
  isHovered,
115
112
  linkAs,
116
- name,
117
113
  size,
118
- target,
119
114
  theme,
120
115
  variant,
121
- type = 'button',
122
116
  fullWidth,
123
117
  ...forwardedProps
124
118
  } = otherProps;
@@ -139,7 +133,7 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
139
133
  color: adaptedColor,
140
134
  emphasis,
141
135
  isSelected,
142
- isDisabled: isAnyDisabled,
136
+ isDisabled: props.isDisabled || props['aria-disabled'],
143
137
  isActive,
144
138
  isFocused,
145
139
  isHovered,
@@ -151,42 +145,18 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
151
145
  }),
152
146
  );
153
147
 
154
- /**
155
- * If the linkAs prop is used, we use the linkAs component instead of a <button>.
156
- * If there is an href attribute, we display an <a> instead of a <button>.
157
- *
158
- * However, in any case, if the component is disabled, we returned a <button> since disabled is not compatible with <a>.
159
- */
160
- if ((linkAs || !isEmpty(props.href)) && !isAnyDisabled) {
161
- return renderLink(
162
- {
163
- linkAs,
164
- ...forwardedProps,
165
- 'aria-label': ariaLabel,
166
- href,
167
- target,
168
- className: buttonClassName,
169
- ref: ref as RefObject<HTMLAnchorElement>,
170
- },
171
- children,
172
- );
173
- }
174
148
  return (
175
- <button
149
+ <RawClickable
150
+ as={linkAs || forwardedProps.href ? 'a' : 'button'}
176
151
  {...forwardedProps}
177
152
  {...disabledStateProps}
178
153
  aria-disabled={isAnyDisabled}
179
154
  aria-label={ariaLabel}
180
155
  ref={ref as RefObject<HTMLButtonElement>}
181
156
  className={buttonClassName}
182
- name={name}
183
- type={
184
- // eslint-disable-next-line react/button-has-type
185
- type
186
- }
187
157
  >
188
158
  {children}
189
- </button>
159
+ </RawClickable>
190
160
  );
191
161
  });
192
162
  ButtonRoot.displayName = COMPONENT_NAME;
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  import { Emphasis, Icon, Size, Theme, ThemeProvider, Tooltip, TooltipProps } from '@lumx/react';
4
4
  import { BaseButtonProps, ButtonRoot } from '@lumx/react/components/button/ButtonRoot';
5
- import { getRootClassName } from '@lumx/react/utils/className';
5
+ import { getRootClassName } from '@lumx/core/js/utils/className';
6
6
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
7
7
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
8
 
@@ -6,7 +6,7 @@ import { mdiCheck, mdiMinus } from '@lumx/icons';
6
6
 
7
7
  import { Icon, InputHelper, InputLabel, Theme } from '@lumx/react';
8
8
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
9
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
9
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
10
10
  import { useId } from '@lumx/react/hooks/useId';
11
11
  import { useMergeRefs } from '@lumx/react/utils/react/mergeRefs';
12
12
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -7,8 +7,8 @@ import { ColorPalette, Size, Theme } from '@lumx/react';
7
7
  import { useStopPropagation } from '@lumx/react/hooks/useStopPropagation';
8
8
 
9
9
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
10
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
11
- import { onEnterPressed } from '@lumx/react/utils/browser/event';
10
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
11
+ import { onEnterPressed } from '@lumx/core/js/utils';
12
12
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
13
13
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
14
14
  import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
@@ -2,9 +2,9 @@ import React, { ReactNode } from 'react';
2
2
 
3
3
  import classNames from 'classnames';
4
4
 
5
- import { HorizontalAlignment } from '@lumx/react/components';
5
+ import { HorizontalAlignment } from '@lumx/core/js/constants';
6
6
  import { GenericProps } from '@lumx/react/utils/type';
7
- import { getRootClassName } from '@lumx/react/utils/className';
7
+ import { getRootClassName } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  import { useChipGroupNavigation } from '@lumx/react/hooks/useChipGroupNavigation';
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Avatar, Size, Theme, Tooltip } from '@lumx/react';
6
6
  import { GenericProps, HasTheme, ValueOf } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -21,7 +21,7 @@ import { parseLocale } from '@lumx/react/utils/locale/parseLocale';
21
21
  import { Locale } from '@lumx/react/utils/locale/types';
22
22
  import { usePreviousValue } from '@lumx/react/hooks/usePreviousValue';
23
23
  import { getYearDisplayName } from '@lumx/react/utils/date/getYearDisplayName';
24
- import { onEnterPressed } from '@lumx/react/utils/browser/event';
24
+ import { onEnterPressed } from '@lumx/core/js/utils';
25
25
  import { addMonthResetDay } from '@lumx/react/utils/date/addMonthResetDay';
26
26
  import { formatDayNumber } from '@lumx/react/utils/date/formatDayNumber';
27
27
  import { VISUALLY_HIDDEN } from '@lumx/react/constants';
@@ -1,4 +1,4 @@
1
- import { getRootClassName } from '@lumx/react/utils/className';
1
+ import { getRootClassName } from '@lumx/core/js/utils/className';
2
2
 
3
3
  /**
4
4
  * Component display name.
@@ -11,7 +11,7 @@ import { useIntersectionObserver } from '@lumx/react/hooks/useIntersectionObserv
11
11
 
12
12
  import { GenericProps, isComponent } from '@lumx/react/utils/type';
13
13
  import { partitionMulti } from '@lumx/react/utils/partitionMulti';
14
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
14
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
15
15
  import { ClickAwayProvider } from '@lumx/react/utils/ClickAwayProvider';
16
16
  import { mergeRefs } from '@lumx/react/utils/react/mergeRefs';
17
17
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Theme } from '@lumx/react';
6
6
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
 
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { mdiDragVertical } from '@lumx/icons';
6
6
  import { ColorPalette, Icon, Size, Theme } from '@lumx/react';
7
7
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
8
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
9
9
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
10
10
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
11
 
@@ -6,7 +6,7 @@ import { List, ListProps } from '@lumx/react/components/list/List';
6
6
  import { Popover, PopoverProps } from '@lumx/react/components/popover/Popover';
7
7
  import { useInfiniteScroll } from '@lumx/react/hooks/useInfiniteScroll';
8
8
  import { GenericProps, isComponent } from '@lumx/react/utils/type';
9
- import { getRootClassName } from '@lumx/react/utils/className';
9
+ import { getRootClassName } from '@lumx/core/js/utils/className';
10
10
  import { Offset, Placement } from '@lumx/react/components/popover/constants';
11
11
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
12
12
 
@@ -8,7 +8,7 @@ import isEmpty from 'lodash/isEmpty';
8
8
 
9
9
  import { ColorPalette, DragHandle, Emphasis, IconButton, IconButtonProps, Theme } from '@lumx/react';
10
10
  import { GenericProps, HasCloseMode, HasTheme, isComponent } from '@lumx/react/utils/type';
11
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
11
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
12
12
  import { partitionMulti } from '@lumx/react/utils/partitionMulti';
13
13
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
14
14
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { ColorPalette, Icon, Size, Theme, Text } from '@lumx/react';
6
6
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
 
@@ -3,11 +3,10 @@ import React, { ReactNode } from 'react';
3
3
  import classNames from 'classnames';
4
4
  import castArray from 'lodash/castArray';
5
5
 
6
- import { Alignment, Orientation } from '@lumx/react';
6
+ import { Alignment, Orientation, HorizontalAlignment, Size, VerticalAlignment } from '@lumx/core/js/constants';
7
7
  import { GenericProps } from '@lumx/react/utils/type';
8
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
- import { HorizontalAlignment, Size, VerticalAlignment } from '..';
11
10
 
12
11
  export type MarginAutoAlignment = Extract<Alignment, 'top' | 'bottom' | 'right' | 'left'>;
13
12
  export type GapSize = Extract<Size, 'tiny' | 'regular' | 'medium' | 'big' | 'huge'>;
@@ -5,7 +5,7 @@ import isEmpty from 'lodash/isEmpty';
5
5
  import noop from 'lodash/noop';
6
6
 
7
7
  import { Comp, isComponentType } from '@lumx/react/utils/type';
8
- import { getRootClassName } from '@lumx/react/utils/className';
8
+ import { getRootClassName } from '@lumx/core/js/utils/className';
9
9
  import { partitionMulti } from '@lumx/react/utils/partitionMulti';
10
10
  import { Orientation, Size, FlexBox, FlexBoxProps } from '@lumx/react';
11
11
  import { GenericBlockGapSize } from '@lumx/react/components/generic-block/constants';
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Alignment, Orientation, Size } from '@lumx/react';
6
6
  import { GenericProps } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  type GridGutterSize = Extract<Size, 'regular' | 'big' | 'huge'>;
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Alignment } from '@lumx/react';
6
6
  import { GenericProps } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  type Columns = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12';
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
 
6
6
  import { Size } from '@lumx/react';
7
7
  import { GenericProps } from '@lumx/react/utils/type';
8
- import { getRootClassName } from '@lumx/react/utils/className';
8
+ import { getRootClassName } from '@lumx/core/js/utils/className';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
 
11
11
  export type GridColumnGapSize = Extract<Size, 'tiny' | 'regular' | 'big' | 'huge'>;
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  import classNames from 'classnames';
4
4
 
5
5
  import { HeadingElement } from '@lumx/react/utils/type';
6
- import { getRootClassName } from '@lumx/react/utils/className';
6
+ import { getRootClassName } from '@lumx/core/js/utils/className';
7
7
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
8
 
9
9
  import { Text, TextProps } from '../text';
@@ -1,4 +1,4 @@
1
- import { Typography } from '..';
1
+ import { Typography } from '@lumx/core/js/constants';
2
2
 
3
3
  /** The maximum authorized heading level. */
4
4
  export const MAX_HEADING_LEVEL = 6;
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { mdiAlertCircle } from '@lumx/icons';
6
6
  import { ColorPalette, ColorVariant, ColorWithVariants, Size, Theme } from '@lumx/react';
7
7
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
8
- import { getRootClassName, handleBasicClasses, resolveColorWithVariants } from '@lumx/react/utils/className';
8
+ import { getRootClassName, handleBasicClasses, resolveColorWithVariants } from '@lumx/core/js/utils/className';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
11
11
 
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { Alignment, HorizontalAlignment, Size, Theme, Thumbnail } from '@lumx/react';
6
6
 
7
7
  import { GenericProps, HasTheme, ValueOf } from '@lumx/react/utils/type';
8
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
 
11
11
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -1,4 +1,4 @@
1
- import { getRootClassName } from '@lumx/react/utils/className';
1
+ import { getRootClassName } from '@lumx/core/js/utils/className';
2
2
 
3
3
  /**
4
4
  * Component display name.
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { ColorVariant, ColorWithVariants, Typography } from '@lumx/react';
6
6
  import { GenericProps } from '@lumx/react/utils/type';
7
- import { fontColorClass, getRootClassName, getTypographyClassName } from '@lumx/react/utils/className';
7
+ import { fontColorClass, getRootClassName, getTypographyClassName } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  /**
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Kind, Theme } from '@lumx/react';
6
6
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
 
10
10
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  import { Theme, Typography } from '@lumx/react';
4
4
  import { getByClassName } from '@lumx/react/testing/utils/queries';
5
- import { getTypographyClassName } from '@lumx/react/utils/className';
5
+ import { getTypographyClassName } from '@lumx/core/js/utils/className';
6
6
  import { render } from '@testing-library/react';
7
7
  import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
8
8
  import { InputLabel, InputLabelProps } from './InputLabel';
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Theme, Typography } from '@lumx/react';
6
6
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
7
- import { getRootClassName, handleBasicClasses, getTypographyClassName } from '@lumx/react/utils/className';
7
+ import { getRootClassName, handleBasicClasses, getTypographyClassName } from '@lumx/core/js/utils/className';
8
8
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
9
9
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
10
10
 
@@ -6,7 +6,7 @@ import { mdiClose } from '@lumx/icons';
6
6
  import { HeadingLevelProvider, IconButton, IconButtonProps } from '@lumx/react';
7
7
  import { DIALOG_TRANSITION_DURATION, DOCUMENT } from '@lumx/react/constants';
8
8
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
9
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
9
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
10
10
 
11
11
  import { useFocusTrap } from '@lumx/react/hooks/useFocusTrap';
12
12
  import { useDisableBodyScroll } from '@lumx/react/hooks/useDisableBodyScroll';
@@ -85,9 +85,10 @@ describe(`<${Link.displayName}>`, () => {
85
85
  it('should render disabled link', async () => {
86
86
  const onClick = jest.fn();
87
87
  const { link } = setup({ children: 'Label', isDisabled: true, href: 'https://example.com', onClick });
88
- // Disabled link do not exist so we fallback to a button
89
- expect(screen.queryByRole('link')).not.toBeInTheDocument();
90
- expect(link).toHaveAttribute('disabled');
88
+ expect(screen.queryByRole('link')).toBeInTheDocument();
89
+ expect(link).toHaveAttribute('aria-disabled');
90
+ // Simulate standard disabled state (not focusable)
91
+ expect(link).toHaveAttribute('tabindex', '-1');
91
92
  await userEvent.click(link);
92
93
  expect(onClick).not.toHaveBeenCalled();
93
94
  });
@@ -95,7 +96,9 @@ describe(`<${Link.displayName}>`, () => {
95
96
  it('should render aria-disabled button', async () => {
96
97
  const onClick = jest.fn();
97
98
  const { link } = setup({ children: 'Label', 'aria-disabled': true, onClick });
98
- expect(link).toHaveAttribute('aria-disabled');
99
+ expect(screen.queryByRole('button')).toBeInTheDocument();
100
+ expect(link).toHaveAttribute('aria-disabled', 'true');
101
+ expect(link).not.toHaveAttribute('tabindex');
99
102
  await userEvent.click(link);
100
103
  expect(onClick).not.toHaveBeenCalled();
101
104
  });
@@ -109,8 +112,7 @@ describe(`<${Link.displayName}>`, () => {
109
112
  onClick,
110
113
  });
111
114
  expect(link).toHaveAccessibleName('Label');
112
- // Disabled link do not exist so we fallback to a button
113
- expect(screen.queryByRole('link')).not.toBeInTheDocument();
115
+ expect(screen.queryByRole('link')).toBeInTheDocument();
114
116
  expect(link).toHaveAttribute('aria-disabled', 'true');
115
117
  await userEvent.click(link);
116
118
  expect(onClick).not.toHaveBeenCalled();
@@ -9,11 +9,12 @@ import {
9
9
  getTypographyClassName,
10
10
  handleBasicClasses,
11
11
  resolveColorWithVariants,
12
- } from '@lumx/react/utils/className';
12
+ } from '@lumx/core/js/utils/className';
13
13
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
14
14
  import { wrapChildrenIconWithSpaces } from '@lumx/react/utils/react/wrapChildrenIconWithSpaces';
15
- import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
16
15
  import { HasAriaDisabled } from '@lumx/react/utils/type/HasAriaDisabled';
16
+ import { RawClickable } from '@lumx/react/utils/react/RawClickable';
17
+ import { useDisableStateProps } from '@lumx/react/utils/disabled';
17
18
 
18
19
  type HTMLAnchorProps = React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;
19
20
 
@@ -67,38 +68,26 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
67
68
  * @return React element.
68
69
  */
69
70
  export const Link = forwardRef<LinkProps, HTMLAnchorElement | HTMLButtonElement>((props, ref) => {
70
- const { isAnyDisabled, disabledStateProps, otherProps } = useDisableStateProps(props);
71
+ const { disabledStateProps, otherProps } = useDisableStateProps(props);
71
72
  const {
72
73
  children,
73
74
  className,
74
75
  color: propColor,
75
76
  colorVariant: propColorVariant,
76
- href,
77
77
  leftIcon,
78
- linkAs,
79
78
  rightIcon,
80
- target,
81
79
  typography,
80
+ linkAs,
82
81
  ...forwardedProps
83
82
  } = otherProps;
84
83
  const [color, colorVariant] = resolveColorWithVariants(propColor, propColorVariant);
85
84
 
86
- const isLink = linkAs || href;
87
- const Component = isLink && !isAnyDisabled ? linkAs || 'a' : 'button';
88
- const baseProps: React.ComponentProps<typeof Component> = {};
89
- if (Component === 'button') {
90
- baseProps.type = 'button';
91
- Object.assign(baseProps, disabledStateProps);
92
- } else if (isLink) {
93
- baseProps.href = href;
94
- baseProps.target = target;
95
- }
96
-
97
85
  return (
98
- <Component
99
- ref={ref}
86
+ <RawClickable
87
+ ref={ref as any}
88
+ as={linkAs || forwardedProps.href ? 'a' : 'button'}
100
89
  {...forwardedProps}
101
- {...baseProps}
90
+ {...disabledStateProps}
102
91
  className={classNames(
103
92
  className,
104
93
  handleBasicClasses({ prefix: CLASSNAME, color, colorVariant, hasTypography: !!typography }),
@@ -112,7 +101,7 @@ export const Link = forwardRef<LinkProps, HTMLAnchorElement | HTMLButtonElement>
112
101
  {rightIcon && <Icon icon={rightIcon} className={`${CLASSNAME}__right-icon`} />}
113
102
  </>,
114
103
  )}
115
- </Component>
104
+ </RawClickable>
116
105
  );
117
106
  });
118
107
  Link.displayName = COMPONENT_NAME;