@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
@@ -6,11 +6,10 @@ import isEmpty from 'lodash/isEmpty';
6
6
  import { mdiChevronDown, mdiChevronUp } from '@lumx/icons';
7
7
  import { Emphasis, Icon, Size, IconButton, IconButtonProps } from '@lumx/react';
8
8
  import { GenericProps, HasCloseMode, isComponent } from '@lumx/react/utils/type';
9
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
10
- import { renderLink } from '@lumx/react/utils/react/renderLink';
11
- import { renderButtonOrLink } from '@lumx/react/utils/react/renderButtonOrLink';
9
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
12
10
  import { useId } from '@lumx/react/hooks/useId';
13
11
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
12
+ import { RawClickable } from '@lumx/react/utils/react/RawClickable';
14
13
 
15
14
  /**
16
15
  * Defines the props of the component.
@@ -113,17 +112,15 @@ export const SideNavigationItem = forwardRef<SideNavigationItemProps, HTMLLIElem
113
112
  >
114
113
  {shouldSplitActions ? (
115
114
  <div className={`${CLASSNAME}__wrapper`}>
116
- {renderLink(
117
- {
118
- linkAs,
119
- ...linkProps,
120
- className: `${CLASSNAME}__link`,
121
- onClick,
122
- tabIndex: 0,
123
- },
124
- icon && <Icon className={`${CLASSNAME}__icon`} icon={icon} size={Size.xs} />,
125
- <span>{label}</span>,
126
- )}
115
+ <RawClickable
116
+ as={linkAs || linkProps?.href ? 'a' : 'button'}
117
+ {...(linkProps as any)}
118
+ className={`${CLASSNAME}__link`}
119
+ onClick={onClick}
120
+ >
121
+ {icon && <Icon className={`${CLASSNAME}__icon`} icon={icon} size={Size.xs} />}
122
+ <span>{label}</span>
123
+ </RawClickable>
127
124
 
128
125
  <IconButton
129
126
  {...toggleButtonProps}
@@ -136,25 +133,23 @@ export const SideNavigationItem = forwardRef<SideNavigationItemProps, HTMLLIElem
136
133
  />
137
134
  </div>
138
135
  ) : (
139
- renderButtonOrLink(
140
- {
141
- linkAs,
142
- ...linkProps,
143
- className: `${CLASSNAME}__link`,
144
- tabIndex: 0,
145
- onClick,
146
- ...ariaProps,
147
- },
148
- icon && <Icon className={`${CLASSNAME}__icon`} icon={icon} size={Size.xs} />,
149
- <span>{label}</span>,
150
- hasContent && (
136
+ <RawClickable
137
+ as={linkAs || linkProps?.href ? 'a' : 'button'}
138
+ {...linkProps}
139
+ className={`${CLASSNAME}__link`}
140
+ onClick={onClick}
141
+ {...ariaProps}
142
+ >
143
+ {icon && <Icon className={`${CLASSNAME}__icon`} icon={icon} size={Size.xs} />}
144
+ <span>{label}</span>
145
+ {hasContent && (
151
146
  <Icon
152
147
  className={`${CLASSNAME}__chevron`}
153
148
  icon={isOpen ? mdiChevronUp : mdiChevronDown}
154
149
  size={Size.xs}
155
150
  />
156
- ),
157
- )
151
+ )}
152
+ </RawClickable>
158
153
  )}
159
154
 
160
155
  {(closeMode === 'hide' || showChildren) && (
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { GlobalSize, Theme, ColorPalette } 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
 
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { AspectRatio, GlobalSize, Theme, ColorPalette } 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 { useTheme } from '@lumx/react/utils/theme/ThemeContext';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
 
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { Theme, TypographyInterface, ColorPalette } 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
 
@@ -6,7 +6,7 @@ import classNames from 'classnames';
6
6
  import { InputHelper, InputLabel, Theme } from '@lumx/react';
7
7
  import useEventCallback from '@lumx/react/hooks/useEventCallback';
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 { clamp } from '@lumx/react/utils/number/clamp';
11
11
  import { useId } from '@lumx/react/hooks/useId';
12
12
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
 
6
6
  import { FULL_WIDTH_PERCENT } from '@lumx/react/components/slideshow/constants';
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 range from 'lodash/range';
6
6
  import { mdiChevronLeft, mdiChevronRight, mdiPlayCircleOutline, mdiPauseCircleOutline } from '@lumx/icons';
7
7
  import { Emphasis, IconButton, IconButtonProps, 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 { WINDOW } from '@lumx/react/constants';
11
11
  import { useSlideshowControls, DEFAULT_OPTIONS } from '@lumx/react/hooks/useSlideshowControls';
12
12
  import { useRovingTabIndex } from '@lumx/react/hooks/useRovingTabIndex';
@@ -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
  /**
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  import classNames from 'classnames';
4
4
  import { mergeRefs } from '@lumx/react/utils/react/mergeRefs';
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
  import { useSlideFocusManagement } from './useSlideFocusManagement';
9
9
 
@@ -5,7 +5,7 @@ import isEmpty from 'lodash/isEmpty';
5
5
 
6
6
  import { Alignment, InputHelper, InputLabel, 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 { useId } from '@lumx/react/hooks/useId';
10
10
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
11
11
  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
 
@@ -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
  /**
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { mdiArrowDown, mdiArrowUp } from '@lumx/icons';
6
6
  import { Icon, Size } from '@lumx/react';
7
7
  import { GenericProps, 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
  /**
@@ -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
  /**
@@ -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, handleBasicClasses } from '@lumx/react/utils/className';
6
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
7
7
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
8
  import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
9
9
 
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { Icon, IconProps, Size, Text } from '@lumx/react';
6
6
  import { CSS_PREFIX } from '@lumx/react/constants';
7
7
  import { GenericProps } from '@lumx/react/utils/type';
8
- import { handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { handleBasicClasses } from '@lumx/core/js/utils/className';
9
9
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
10
10
 
11
11
  import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
  import { Alignment, Theme } from '@lumx/react';
6
6
  import { CSS_PREFIX } from '@lumx/react/constants';
7
7
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
8
- import { handleBasicClasses } from '@lumx/react/utils/className';
8
+ import { handleBasicClasses } from '@lumx/core/js/utils/className';
9
9
  import { mergeRefs } from '@lumx/react/utils/react/mergeRefs';
10
10
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
11
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -6,7 +6,7 @@ import { forwardRef } from '@lumx/react/utils/react/forwardRef';
6
6
  import { useTabProviderContext } from '@lumx/react/components/tabs/state';
7
7
  import { CSS_PREFIX } from '@lumx/react/constants';
8
8
  import { GenericProps } from '@lumx/react/utils/type';
9
- import { handleBasicClasses } from '@lumx/react/utils/className';
9
+ import { handleBasicClasses } from '@lumx/core/js/utils/className';
10
10
 
11
11
  /**
12
12
  * Defines the props of the component.
@@ -9,7 +9,7 @@ import {
9
9
  getRootClassName,
10
10
  handleBasicClasses,
11
11
  getTypographyClassName,
12
- } from '@lumx/react/utils/className';
12
+ } from '@lumx/core/js/utils/className';
13
13
  import { useOverflowTooltipLabel } from '@lumx/react/hooks/useOverflowTooltipLabel';
14
14
  import { useMergeRefs } from '@lumx/react/utils/react/mergeRefs';
15
15
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  import camelCase from 'lodash/camelCase';
4
4
 
5
5
  import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
6
- import { getBasicClass } from '@lumx/react/utils/className';
6
+ import { getBasicClass } from '@lumx/core/js/utils/className';
7
7
  import { render } from '@testing-library/react';
8
8
  import {
9
9
  getByClassName,
@@ -17,7 +17,7 @@ import {
17
17
  Theme,
18
18
  } from '@lumx/react';
19
19
  import { GenericProps, HasTheme } from '@lumx/react/utils/type';
20
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
20
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
21
21
  import { mergeRefs } from '@lumx/react/utils/react/mergeRefs';
22
22
  import { useId } from '@lumx/react/hooks/useId';
23
23
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -13,7 +13,7 @@ import classNames from 'classnames';
13
13
 
14
14
  import { AspectRatio, HorizontalAlignment, Icon, Size, Theme, ThumbnailObjectFit } from '@lumx/react';
15
15
  import { Falsy, GenericProps, HasTheme } from '@lumx/react/utils/type';
16
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
16
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
17
17
  import { mdiImageBroken } from '@lumx/icons';
18
18
  import { useMergeRefs } from '@lumx/react/utils/react/mergeRefs';
19
19
  import { useImageLoad } from '@lumx/react/components/thumbnail/useImageLoad';
@@ -22,6 +22,7 @@ import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
22
22
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
23
23
 
24
24
  import { useDisableStateProps } from '@lumx/react/utils/disabled';
25
+ import { RawClickable } from '@lumx/react/utils/react/RawClickable';
25
26
  import { FocusPoint, ThumbnailSize, ThumbnailVariant } from './types';
26
27
 
27
28
  type ImgHTMLProps = ImgHTMLAttributes<HTMLImageElement>;
@@ -100,7 +101,7 @@ const DEFAULT_PROPS: Partial<ThumbnailProps> = {
100
101
  * @return React element.
101
102
  */
102
103
  export const Thumbnail = forwardRef<ThumbnailProps>((props, ref) => {
103
- const { isAnyDisabled, otherProps } = useDisableStateProps(props);
104
+ const { isAnyDisabled, otherProps, disabledStateProps } = useDisableStateProps(props);
104
105
  const defaultTheme = useTheme() || Theme.light;
105
106
  const {
106
107
  align,
@@ -150,18 +151,12 @@ export const Thumbnail = forwardRef<ThumbnailProps>((props, ref) => {
150
151
  imageErrorStyle.display = 'none';
151
152
  }
152
153
 
153
- const isLink = Boolean(linkProps?.href || linkAs);
154
- const isButton = !!forwardedProps.onClick;
155
- const isClickable = !isAnyDisabled && (isButton || isLink);
154
+ const isClickable = !isAnyDisabled && (linkProps?.href || linkAs || forwardedProps.onClick);
156
155
 
157
- let Wrapper: any = 'div';
156
+ const Wrapper: any = isClickable ? RawClickable : 'div';
158
157
  const wrapperProps = { ...forwardedProps };
159
- if (!isAnyDisabled && isLink) {
160
- Wrapper = linkAs || 'a';
161
- Object.assign(wrapperProps, linkProps);
162
- } else if (!isAnyDisabled && isButton) {
163
- Wrapper = 'button';
164
- wrapperProps.type = forwardedProps.type || 'button';
158
+ if (isClickable) {
159
+ Object.assign(wrapperProps, linkProps, { as: linkAs || linkProps?.href ? 'a' : 'button' }, disabledStateProps);
165
160
  wrapperProps['aria-label'] = forwardedProps['aria-label'] || alt;
166
161
  }
167
162
 
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, useEffect, useMemo, useState } from 'react';
2
- import { AspectRatio } from '@lumx/react/components';
2
+ import { AspectRatio } from '@lumx/core/js/constants';
3
3
  import { ThumbnailProps } from '@lumx/react/components/thumbnail/Thumbnail';
4
4
  import { RectSize } from '@lumx/react/utils/type';
5
5
 
@@ -3,7 +3,7 @@ import React, { ReactNode } from 'react';
3
3
  import classNames from 'classnames';
4
4
 
5
5
  import { GenericProps } from '@lumx/react/utils/type';
6
- import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
6
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
7
7
  import { forwardRef } from '@lumx/react/utils/react/forwardRef';
8
8
 
9
9
  /**
@@ -5,7 +5,7 @@ import classNames from 'classnames';
5
5
 
6
6
  import { DOCUMENT, VISUALLY_HIDDEN } from '@lumx/react/constants';
7
7
  import { GenericProps, HasCloseMode } 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 { useMergeRefs } from '@lumx/react/utils/react/mergeRefs';
10
10
  import { Placement } from '@lumx/react/components/popover';
11
11
  import { TooltipContextProvider } from '@lumx/react/components/tooltip/context';
@@ -4,7 +4,7 @@ import classNames from 'classnames';
4
4
 
5
5
  import { AspectRatio, Icon, Size, Theme } 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 { useBooleanState } from '@lumx/react/hooks/useBooleanState';
9
9
  import { useId } from '@lumx/react/hooks/useId';
10
10
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -6,7 +6,7 @@ import set from 'lodash/set';
6
6
 
7
7
  import { Avatar, ColorPalette, Link, Orientation, Size, 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 { forwardRef } from '@lumx/react/utils/react/forwardRef';
11
11
 
12
12
  import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
@@ -1,6 +1,6 @@
1
1
  import { DOCUMENT } from '@lumx/react/constants';
2
2
  import { Callback } from '@lumx/react/utils/type';
3
- import { onEscapePressed } from '@lumx/react/utils/browser/event';
3
+ import { onEscapePressed } from '@lumx/core/js/utils';
4
4
  import { useEffect } from 'react';
5
5
  import { Listener, makeListenerTowerContext } from '@lumx/react/utils/function/makeListenerTowerContext';
6
6
 
package/src/index.ts CHANGED
@@ -2,7 +2,9 @@
2
2
  * Components listed here will be exposed to NPM in '@lumx/react'.
3
3
  */
4
4
 
5
- export * from './components';
5
+ export * from '@lumx/core/js/constants';
6
+ export * from '@lumx/core/js/types';
7
+
6
8
  export * from './components/alert-dialog';
7
9
  export * from './components/autocomplete';
8
10
  export * from './components/avatar';
@@ -3,7 +3,8 @@ import dropRight from 'lodash/dropRight';
3
3
  import last from 'lodash/last';
4
4
  import partition from 'lodash/partition';
5
5
  import reduce from 'lodash/reduce';
6
- import { Predicate } from './type';
6
+
7
+ import { Predicate } from '@lumx/core/js/types';
7
8
 
8
9
  /**
9
10
  * Similar to lodash `partition` function but working with multiple predicates.
@@ -0,0 +1,153 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { RawClickable, RawClickableProps } from './RawClickable';
5
+ import { CustomLink } from '../../stories/utils/CustomLink';
6
+
7
+ /**
8
+ * Mounts the component and returns common DOM elements / data needed in multiple tests.
9
+ */
10
+ const setup = (props: RawClickableProps<any>) => {
11
+ render(<RawClickable {...props} data-testid="raw-element" />);
12
+ const element = screen.getByTestId('raw-element');
13
+ return { props, element };
14
+ };
15
+
16
+ describe(`<RawClickable>`, () => {
17
+ describe('as a button', () => {
18
+ it('should render a button by default', () => {
19
+ const { element } = setup({ as: 'button', children: 'Click me' });
20
+ expect(element.tagName).toBe('BUTTON');
21
+ expect(element).toHaveAttribute('type', 'button');
22
+ expect(screen.getByRole('button', { name: 'Click me' })).toBe(element);
23
+ });
24
+
25
+ it('should trigger onClick', async () => {
26
+ const onClick = jest.fn();
27
+ const { element } = setup({ as: 'button', children: 'Click me', onClick });
28
+ await userEvent.click(element);
29
+ expect(onClick).toHaveBeenCalledTimes(1);
30
+ });
31
+
32
+ it('should be disabled with `disabled` prop', async () => {
33
+ const onClick = jest.fn();
34
+ const { element } = setup({ as: 'button', children: 'Click me', onClick, disabled: true });
35
+ expect(element).toBeDisabled();
36
+ await userEvent.click(element);
37
+ expect(onClick).not.toHaveBeenCalled();
38
+ });
39
+
40
+ it('should be disabled with `isDisabled` prop', async () => {
41
+ const onClick = jest.fn();
42
+ const { element } = setup({ as: 'button', children: 'Click me', onClick, isDisabled: true });
43
+ expect(element).toBeDisabled();
44
+ await userEvent.click(element);
45
+ expect(onClick).not.toHaveBeenCalled();
46
+ });
47
+
48
+ it('should be aria-disabled with `aria-disabled` prop', async () => {
49
+ const onClick = jest.fn();
50
+ const { element } = setup({ as: 'button', children: 'Click me', onClick, 'aria-disabled': true });
51
+ expect(element).not.toBeDisabled();
52
+ expect(element).toHaveAttribute('aria-disabled', 'true');
53
+ await userEvent.click(element);
54
+ expect(onClick).not.toHaveBeenCalled();
55
+ });
56
+ });
57
+
58
+ describe('as a link', () => {
59
+ const href = 'https://example.com';
60
+
61
+ it('should render a link with `href` prop', () => {
62
+ const { element } = setup({ as: 'a', children: 'Click me', href });
63
+ expect(element.tagName).toBe('A');
64
+ expect(element).toHaveAttribute('href', href);
65
+ expect(screen.getByRole('link', { name: 'Click me' })).toBe(element);
66
+ });
67
+
68
+ it('should trigger onClick', async () => {
69
+ const onClick = jest.fn((evt) => evt.preventDefault());
70
+ const { element } = setup({ as: 'a', children: 'Click me', href, onClick });
71
+ await userEvent.click(element);
72
+ expect(onClick).toHaveBeenCalledTimes(1);
73
+ });
74
+
75
+ it('should be disabled with `disabled` prop', async () => {
76
+ const onClick = jest.fn();
77
+ const { element } = setup({ as: 'a', children: 'Click me', href, onClick, disabled: true });
78
+ expect(element).toHaveAttribute('aria-disabled', 'true');
79
+ expect(element).toHaveAttribute('tabindex', '-1');
80
+ await userEvent.click(element);
81
+ expect(onClick).not.toHaveBeenCalled();
82
+ });
83
+
84
+ it('should be disabled with `isDisabled` prop', async () => {
85
+ const onClick = jest.fn();
86
+ const { element } = setup({ as: 'a', children: 'Click me', href, onClick, isDisabled: true });
87
+ expect(element).toHaveAttribute('aria-disabled', 'true');
88
+ expect(element).toHaveAttribute('tabindex', '-1');
89
+ await userEvent.click(element);
90
+ expect(onClick).not.toHaveBeenCalled();
91
+ });
92
+
93
+ it('should be aria-disabled with `aria-disabled` prop', async () => {
94
+ const onClick = jest.fn();
95
+ const { element } = setup({ as: 'a', children: 'Click me', href, onClick, 'aria-disabled': true });
96
+ expect(element).toHaveAttribute('aria-disabled', 'true');
97
+ await userEvent.click(element);
98
+ expect(onClick).not.toHaveBeenCalled();
99
+ });
100
+ });
101
+
102
+ describe('as a custom component', () => {
103
+ it('should render a custom component with `linkAs` prop', () => {
104
+ const { element } = setup({ as: CustomLink, children: 'Click me' });
105
+ expect(element).toHaveAttribute('data-custom-link');
106
+ });
107
+
108
+ it('should trigger onClick', async () => {
109
+ const onClick = jest.fn();
110
+ const { element } = setup({ as: CustomLink, children: 'Click me', onClick });
111
+ expect(element).toHaveAttribute('data-custom-link');
112
+ await userEvent.click(element);
113
+ expect(onClick).toHaveBeenCalledTimes(1);
114
+ });
115
+
116
+ it('should be disabled with `disabled` prop', async () => {
117
+ const onClick = jest.fn();
118
+ const { element } = setup({ as: CustomLink, children: 'Click me', onClick, disabled: true });
119
+ expect(element).toHaveAttribute('data-custom-link');
120
+ expect(element).toHaveAttribute('aria-disabled', 'true');
121
+ expect(element).toHaveAttribute('tabindex', '-1');
122
+ await userEvent.click(element);
123
+ expect(onClick).not.toHaveBeenCalled();
124
+ });
125
+ });
126
+
127
+ describe('prop forwarding', () => {
128
+ it('should forward className', () => {
129
+ const { element } = setup({ as:'button', className: 'foo bar' });
130
+ expect(element).toHaveClass('foo bar');
131
+ });
132
+
133
+ it('should forward ref and override type in button', () => {
134
+ const ref = React.createRef<HTMLButtonElement>();
135
+ const { element } = setup({ as: 'button', ref, type: 'submit' });
136
+ expect(element).toHaveAttribute('type', 'submit');
137
+ expect(ref.current).toBeInstanceOf(HTMLButtonElement);
138
+ });
139
+
140
+ it('should forward ref and override tabindex in link', () => {
141
+ const ref = React.createRef<HTMLAnchorElement>();
142
+ const { element } = setup({ as: 'a', ref, href: '#', tabIndex: -1 });
143
+ expect(ref.current).toBeInstanceOf(HTMLAnchorElement);
144
+ expect(element).toHaveAttribute('tabindex', '-1');
145
+ });
146
+
147
+ it('should forward ref to custom component', () => {
148
+ const ref = React.createRef<HTMLAnchorElement>();
149
+ setup({ as: CustomLink, ref });
150
+ expect(ref.current).toBeInstanceOf(HTMLAnchorElement);
151
+ });
152
+ });
153
+ });