@lumx/react 3.10.1-alpha.1 → 3.10.1-alpha.3
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/_internal/index.d.ts +1 -1
- package/_internal/index.js +99 -0
- package/_internal/index.js.map +1 -0
- package/index.d.ts +34 -57
- package/index.js +125 -107
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/button/Button.tsx +4 -5
- package/src/components/button/ButtonRoot.tsx +1 -3
- package/src/components/chip/Chip.tsx +6 -10
- package/src/components/dialog/Dialog.tsx +1 -1
- package/src/components/expansion-panel/ExpansionPanel.tsx +14 -18
- package/src/components/flex-box/FlexBox.tsx +1 -1
- package/src/components/generic-block/GenericBlock.tsx +6 -7
- package/src/components/generic-block/constants.ts +9 -4
- package/src/components/grid-column/GridColumn.tsx +1 -2
- package/src/components/link/Link.tsx +3 -5
- package/src/components/list/ListItem.tsx +1 -2
- package/src/components/list/useInteractiveList.tsx +1 -2
- package/src/components/mosaic/Mosaic.test.tsx +3 -3
- package/src/components/mosaic/Mosaic.tsx +2 -3
- package/src/components/navigation/Navigation.tsx +42 -37
- package/src/components/navigation/NavigationSection.tsx +76 -79
- package/src/components/notification/Notification.tsx +1 -5
- package/src/components/post-block/PostBlock.tsx +4 -8
- package/src/components/progress-tracker/ProgressTracker.stories.tsx +11 -11
- package/src/components/select/Select.stories.tsx +14 -5
- package/src/components/select/Select.tsx +1 -2
- package/src/components/select/SelectMultiple.stories.tsx +12 -10
- package/src/components/side-navigation/SideNavigationItem.tsx +1 -1
- package/src/components/slideshow/Slides.tsx +1 -1
- package/src/components/slideshow/SlideshowControls.tsx +1 -1
- package/src/components/switch/Switch.tsx +1 -2
- package/src/components/tabs/Tabs.stories.tsx +3 -4
- package/src/components/text-field/TextField.test.tsx +2 -2
- package/src/components/text-field/TextField.tsx +2 -3
- package/src/components/user-block/UserBlock.tsx +7 -9
- package/src/hooks/useClickAway.tsx +1 -2
- package/src/hooks/useInterval.tsx +1 -4
- package/src/hooks/useKeyboardListNavigation.tsx +2 -4
- package/src/hooks/useStopPropagation.ts +1 -2
- package/src/stories/decorators/withCombinations.tsx +1 -1
- package/src/testing/utils/commonTestsSuiteRTL.tsx +2 -2
- package/src/utils/collection/castArray.test.ts +15 -0
- package/src/utils/collection/castArray.ts +3 -0
- package/src/utils/collection/chunk.test.ts +15 -0
- package/src/utils/collection/chunk.ts +6 -0
- package/src/utils/collection/isEmpty.test.js +20 -0
- package/src/utils/collection/isEmpty.ts +4 -0
- package/src/utils/collection/last.ts +2 -0
- package/src/utils/collection/partitionMulti.test.ts +35 -0
- package/src/utils/{partitionMulti.ts → collection/partitionMulti.ts} +13 -12
- package/src/utils/collection/pull.test.ts +17 -0
- package/src/utils/collection/pull.ts +7 -0
- package/src/utils/collection/range.test.js +9 -0
- package/src/utils/collection/range.ts +2 -0
- package/src/utils/date/getMonthCalendar.ts +3 -4
- package/src/utils/flattenChildren.ts +2 -3
- package/src/utils/makeListenerTowerContext.ts +2 -2
- package/src/utils/react/forwardRef.ts +3 -2
- package/src/utils/react/forwardRefPolymorphic.ts +1 -2
- package/src/utils/utils.test.ts +0 -27
- package/utils/index.js +1 -96
- package/utils/index.js.map +1 -1
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.10.1-alpha.
|
|
10
|
-
"@lumx/icons": "^3.10.1-alpha.
|
|
9
|
+
"@lumx/core": "^3.10.1-alpha.3",
|
|
10
|
+
"@lumx/icons": "^3.10.1-alpha.3",
|
|
11
11
|
"@popperjs/core": "^2.5.4",
|
|
12
12
|
"body-scroll-lock": "^3.1.5",
|
|
13
13
|
"classnames": "^2.3.2",
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"build:storybook": "storybook build"
|
|
111
111
|
},
|
|
112
112
|
"sideEffects": false,
|
|
113
|
-
"version": "3.10.1-alpha.
|
|
113
|
+
"version": "3.10.1-alpha.3"
|
|
114
114
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import isEmpty from 'lodash/isEmpty';
|
|
5
4
|
|
|
6
5
|
import { Emphasis, Icon, Size, Theme, Text } from '@lumx/react';
|
|
7
6
|
import { isComponent } from '@lumx/react/utils/type';
|
|
@@ -62,8 +61,8 @@ export const Button = forwardRef<ButtonProps, HTMLButtonElement | HTMLAnchorElem
|
|
|
62
61
|
|
|
63
62
|
const buttonClassName = classNames(
|
|
64
63
|
className,
|
|
65
|
-
getBasicClass({ prefix: CLASSNAME, type: 'hasLeftIcon', value:
|
|
66
|
-
getBasicClass({ prefix: CLASSNAME, type: 'hasRightIcon', value:
|
|
64
|
+
getBasicClass({ prefix: CLASSNAME, type: 'hasLeftIcon', value: !!leftIcon }),
|
|
65
|
+
getBasicClass({ prefix: CLASSNAME, type: 'hasRightIcon', value: !!rightIcon }),
|
|
67
66
|
);
|
|
68
67
|
|
|
69
68
|
return (
|
|
@@ -73,9 +72,9 @@ export const Button = forwardRef<ButtonProps, HTMLButtonElement | HTMLAnchorElem
|
|
|
73
72
|
className={buttonClassName}
|
|
74
73
|
variant="button"
|
|
75
74
|
>
|
|
76
|
-
{leftIcon &&
|
|
75
|
+
{leftIcon && <Icon icon={leftIcon} />}
|
|
77
76
|
{children && (isComponent(Text)(children) ? children : <span>{children}</span>)}
|
|
78
|
-
{rightIcon &&
|
|
77
|
+
{rightIcon && <Icon icon={rightIcon} />}
|
|
79
78
|
</ButtonRoot>
|
|
80
79
|
);
|
|
81
80
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
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';
|
|
@@ -155,7 +153,7 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
|
|
|
155
153
|
*
|
|
156
154
|
* However, in any case, if the component is disabled, we returned a <button> since disabled is not compatible with <a>.
|
|
157
155
|
*/
|
|
158
|
-
if ((linkAs ||
|
|
156
|
+
if ((linkAs || props.href) && !isDisabled) {
|
|
159
157
|
return renderLink(
|
|
160
158
|
{
|
|
161
159
|
linkAs,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { MouseEventHandler, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import isFunction from 'lodash/isFunction';
|
|
5
4
|
|
|
6
5
|
import { ColorPalette, Size, Theme } from '@lumx/react';
|
|
7
6
|
import { useStopPropagation } from '@lumx/react/hooks/useStopPropagation';
|
|
@@ -89,11 +88,8 @@ export const Chip = forwardRef<ChipProps, HTMLAnchorElement>((props, ref) => {
|
|
|
89
88
|
onKeyDown,
|
|
90
89
|
...forwardedProps
|
|
91
90
|
} = props;
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const hasOnClick = isFunction(onClick);
|
|
95
|
-
const isButton = hasOnClick && !href;
|
|
96
|
-
const isClickable = Boolean(hasOnClick) || Boolean(href) || propIsClickable;
|
|
91
|
+
const isButton = onClick && !href;
|
|
92
|
+
const isClickable = Boolean(onClick) || Boolean(href) || propIsClickable;
|
|
97
93
|
|
|
98
94
|
// Adapt color to the theme.
|
|
99
95
|
const chipColor = color || (theme === Theme.light ? ColorPalette.dark : ColorPalette.light);
|
|
@@ -102,7 +98,7 @@ export const Chip = forwardRef<ChipProps, HTMLAnchorElement>((props, ref) => {
|
|
|
102
98
|
const handleOnAfterClick = useStopPropagation(onAfterClick);
|
|
103
99
|
const handleKeyDown = (evt: React.KeyboardEvent) => {
|
|
104
100
|
onKeyDown?.(evt);
|
|
105
|
-
if (
|
|
101
|
+
if (onClick) {
|
|
106
102
|
onEnterPressed(onClick)(evt);
|
|
107
103
|
}
|
|
108
104
|
};
|
|
@@ -131,14 +127,14 @@ export const Chip = forwardRef<ChipProps, HTMLAnchorElement>((props, ref) => {
|
|
|
131
127
|
}),
|
|
132
128
|
)}
|
|
133
129
|
aria-disabled={(isClickable && isDisabled) || undefined}
|
|
134
|
-
onClick={
|
|
130
|
+
onClick={onClick || undefined}
|
|
135
131
|
onKeyDown={handleKeyDown}
|
|
136
132
|
>
|
|
137
133
|
{before && (
|
|
138
134
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
|
|
139
135
|
<div
|
|
140
136
|
className={classNames(`${CLASSNAME}__before`, {
|
|
141
|
-
[`${CLASSNAME}__before--is-clickable`]:
|
|
137
|
+
[`${CLASSNAME}__before--is-clickable`]: !!onBeforeClick,
|
|
142
138
|
})}
|
|
143
139
|
onClick={handleOnBeforeClick}
|
|
144
140
|
>
|
|
@@ -150,7 +146,7 @@ export const Chip = forwardRef<ChipProps, HTMLAnchorElement>((props, ref) => {
|
|
|
150
146
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
|
|
151
147
|
<div
|
|
152
148
|
className={classNames(`${CLASSNAME}__after`, {
|
|
153
|
-
[`${CLASSNAME}__after--is-clickable`]:
|
|
149
|
+
[`${CLASSNAME}__after--is-clickable`]: !!onAfterClick,
|
|
154
150
|
})}
|
|
155
151
|
onClick={handleOnAfterClick}
|
|
156
152
|
>
|
|
@@ -11,7 +11,7 @@ import { useFocusTrap } from '@lumx/react/hooks/useFocusTrap';
|
|
|
11
11
|
import { useIntersectionObserver } from '@lumx/react/hooks/useIntersectionObserver';
|
|
12
12
|
|
|
13
13
|
import { GenericProps, isComponent } from '@lumx/react/utils/type';
|
|
14
|
-
import { partitionMulti } from '@lumx/react/utils/partitionMulti';
|
|
14
|
+
import { partitionMulti } from '@lumx/react/utils/collection/partitionMulti';
|
|
15
15
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
16
16
|
import { ClickAwayProvider } from '@lumx/react/utils/ClickAwayProvider';
|
|
17
17
|
import { mergeRefs } from '@lumx/react/utils/mergeRefs';
|
|
@@ -4,18 +4,15 @@ import classNames from 'classnames';
|
|
|
4
4
|
|
|
5
5
|
import { mdiChevronDown, mdiChevronUp } from '@lumx/icons';
|
|
6
6
|
|
|
7
|
-
import get from 'lodash/get';
|
|
8
|
-
import isEmpty from 'lodash/isEmpty';
|
|
9
|
-
import isFunction from 'lodash/isFunction';
|
|
10
|
-
|
|
11
7
|
import { ColorPalette, DragHandle, Emphasis, IconButton, IconButtonProps, Theme } from '@lumx/react';
|
|
12
8
|
import { GenericProps, HasTheme, isComponent } from '@lumx/react/utils/type';
|
|
13
9
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
14
|
-
import { partitionMulti } from '@lumx/react/utils/partitionMulti';
|
|
10
|
+
import { partitionMulti } from '@lumx/react/utils/collection/partitionMulti';
|
|
15
11
|
import { useTransitionVisibility } from '@lumx/react/hooks/useTransitionVisibility';
|
|
16
12
|
import { EXPANSION_PANEL_TRANSITION_DURATION } from '@lumx/core/js/constants';
|
|
17
13
|
import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
|
|
18
14
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
15
|
+
import { isEmpty } from '@lumx/react/utils/collection/isEmpty';
|
|
19
16
|
|
|
20
17
|
/**
|
|
21
18
|
* Defines the props of the component.
|
|
@@ -90,24 +87,23 @@ export const ExpansionPanel = forwardRef<ExpansionPanelProps, HTMLDivElement>((p
|
|
|
90
87
|
|
|
91
88
|
// Either take the header in children or create one with the label.
|
|
92
89
|
const headerProps: PropsWithChildren<any> = React.isValidElement(header) ? header.props : {};
|
|
93
|
-
const headerContent =
|
|
94
|
-
headerProps.children
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
const headerContent =
|
|
91
|
+
React.Children.count(headerProps.children) > 0 ? (
|
|
92
|
+
headerProps.children
|
|
93
|
+
) : (
|
|
94
|
+
<span className={`${CLASSNAME}__label`}>{label}</span>
|
|
95
|
+
);
|
|
98
96
|
|
|
99
97
|
const toggleOpen = (event: React.MouseEvent) => {
|
|
100
98
|
const shouldOpen = !isOpen;
|
|
101
99
|
|
|
102
|
-
if (
|
|
103
|
-
onOpen(event);
|
|
104
|
-
}
|
|
105
|
-
if (isFunction(onClose) && !shouldOpen) {
|
|
106
|
-
onClose(event);
|
|
100
|
+
if (shouldOpen) {
|
|
101
|
+
onOpen?.(event);
|
|
107
102
|
}
|
|
108
|
-
if (
|
|
109
|
-
|
|
103
|
+
if (!shouldOpen) {
|
|
104
|
+
onClose?.(event);
|
|
110
105
|
}
|
|
106
|
+
onToggleOpen?.(shouldOpen, event);
|
|
111
107
|
};
|
|
112
108
|
|
|
113
109
|
const color = theme === Theme.dark ? ColorPalette.light : ColorPalette.dark;
|
|
@@ -134,7 +130,7 @@ export const ExpansionPanel = forwardRef<ExpansionPanelProps, HTMLDivElement>((p
|
|
|
134
130
|
// Switch max height on/off to activate the CSS transition (updates when children changes).
|
|
135
131
|
const [maxHeight, setMaxHeight] = useState('0');
|
|
136
132
|
useEffect(() => {
|
|
137
|
-
const height = isOpen ?
|
|
133
|
+
const height = isOpen ? wrapperRef.current?.offsetHeight ?? 0 : 0;
|
|
138
134
|
setMaxHeight(`${height}px`);
|
|
139
135
|
}, [children, isOpen]);
|
|
140
136
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import castArray from 'lodash/castArray';
|
|
5
4
|
|
|
6
5
|
import { Alignment, Orientation } from '@lumx/react';
|
|
6
|
+
import { castArray } from '@lumx/react/utils/collection/castArray';
|
|
7
7
|
import { GenericProps } from '@lumx/react/utils/type';
|
|
8
8
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
9
9
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, { Children, ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import isEmpty from 'lodash/isEmpty';
|
|
5
|
-
import noop from 'lodash/noop';
|
|
6
4
|
|
|
7
5
|
import { Comp, isComponentType } from '@lumx/react/utils/type';
|
|
8
6
|
import { getRootClassName } from '@lumx/react/utils/className';
|
|
9
|
-
import { partitionMulti } from '@lumx/react/utils/partitionMulti';
|
|
7
|
+
import { partitionMulti } from '@lumx/react/utils/collection/partitionMulti';
|
|
10
8
|
import { Orientation, Size, FlexBox, FlexBoxProps } from '@lumx/react';
|
|
11
9
|
import { GenericBlockGapSize } from '@lumx/react/components/generic-block/constants';
|
|
12
10
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
@@ -101,13 +99,13 @@ interface GenericBlock extends BaseGenericBlock {
|
|
|
101
99
|
Actions: Comp<GenericBlockSectionProps>;
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
const Figure =
|
|
102
|
+
const Figure = (() => {}) as unknown as Comp<FlexBoxProps>;
|
|
105
103
|
const isFigure = isComponentType(Figure);
|
|
106
104
|
|
|
107
|
-
const Content =
|
|
105
|
+
const Content = (() => {}) as unknown as Comp<FlexBoxProps>;
|
|
108
106
|
const isContent = isComponentType(Content);
|
|
109
107
|
|
|
110
|
-
const Actions =
|
|
108
|
+
const Actions = (() => {}) as unknown as Comp<FlexBoxProps>;
|
|
111
109
|
const isActions = isComponentType(Actions);
|
|
112
110
|
|
|
113
111
|
/**
|
|
@@ -148,7 +146,8 @@ const BaseGenericBlock: BaseGenericBlock = forwardRef((props, ref) => {
|
|
|
148
146
|
contentChildProps: (contentChild as ReactElement)?.props,
|
|
149
147
|
actionsChild,
|
|
150
148
|
actionsChildProps: (actionsChild as ReactElement)?.props,
|
|
151
|
-
|
|
149
|
+
// TODO: check this is working
|
|
150
|
+
otherChildren: otherChildren.filter((child) => React.Children.count(child) > 0),
|
|
152
151
|
};
|
|
153
152
|
}, [children]);
|
|
154
153
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import pick from 'lodash/pick';
|
|
2
1
|
import { Size } from '@lumx/react';
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
export type GenericBlockGapSize = Extract<Size, 'tiny' | 'regular' | 'medium' | 'big' | 'huge'>;
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Accepted gap sizes for the generic block.
|
|
7
7
|
*/
|
|
8
|
-
export const GenericBlockGapSize
|
|
9
|
-
|
|
8
|
+
export const GenericBlockGapSize: { [S in GenericBlockGapSize]: S } = {
|
|
9
|
+
tiny: Size.tiny,
|
|
10
|
+
regular: Size.regular,
|
|
11
|
+
medium: Size.medium,
|
|
12
|
+
big: Size.big,
|
|
13
|
+
huge: Size.huge,
|
|
14
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
|
-
import isInteger from 'lodash/isInteger';
|
|
4
3
|
import classNames from 'classnames';
|
|
5
4
|
|
|
6
5
|
import { Size } from '@lumx/react';
|
|
@@ -74,7 +73,7 @@ export const GridColumn = forwardRef<GridColumnProps>((props, ref): ReactElement
|
|
|
74
73
|
)}
|
|
75
74
|
style={{
|
|
76
75
|
...style,
|
|
77
|
-
['--lumx-grid-column-item-min-width' as any]: isInteger(itemMinWidth) && `${itemMinWidth}px`,
|
|
76
|
+
['--lumx-grid-column-item-min-width' as any]: Number.isInteger(itemMinWidth) && `${itemMinWidth}px`,
|
|
78
77
|
['--lumx-grid-column-columns' as any]: maxColumns,
|
|
79
78
|
['--lumx-grid-column-gap' as any]: gap && `var(--lumx-spacing-unit-${gap})`,
|
|
80
79
|
}}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React, { RefObject, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
import isEmpty from 'lodash/isEmpty';
|
|
4
|
-
|
|
5
3
|
import classNames from 'classnames';
|
|
6
4
|
|
|
7
5
|
import { ColorPalette, ColorVariant, Icon, Size, Typography } from '@lumx/react';
|
|
@@ -102,7 +100,7 @@ export const Link = forwardRef<LinkProps, HTMLAnchorElement | HTMLButtonElement>
|
|
|
102
100
|
const renderedChildren = useMemo(
|
|
103
101
|
() => (
|
|
104
102
|
<>
|
|
105
|
-
{leftIcon &&
|
|
103
|
+
{leftIcon && (
|
|
106
104
|
<Icon icon={leftIcon} className={`${CLASSNAME}__left-icon`} size={getIconSize(typography)} />
|
|
107
105
|
)}
|
|
108
106
|
|
|
@@ -116,7 +114,7 @@ export const Link = forwardRef<LinkProps, HTMLAnchorElement | HTMLButtonElement>
|
|
|
116
114
|
</span>
|
|
117
115
|
)}
|
|
118
116
|
|
|
119
|
-
{rightIcon &&
|
|
117
|
+
{rightIcon && (
|
|
120
118
|
<Icon icon={rightIcon} className={`${CLASSNAME}__right-icon`} size={getIconSize(typography)} />
|
|
121
119
|
)}
|
|
122
120
|
</>
|
|
@@ -128,7 +126,7 @@ export const Link = forwardRef<LinkProps, HTMLAnchorElement | HTMLButtonElement>
|
|
|
128
126
|
* If there is no linkAs prop and no href, we returned a <button> instead of a <a>.
|
|
129
127
|
* If the component is disabled, we also returned a <button> since disabled is not compatible with <a>.
|
|
130
128
|
*/
|
|
131
|
-
if ((!linkAs &&
|
|
129
|
+
if ((!linkAs && href) || isDisabled) {
|
|
132
130
|
return (
|
|
133
131
|
<button
|
|
134
132
|
type="button"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { ReactNode, Ref, SyntheticEvent, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import isEmpty from 'lodash/isEmpty';
|
|
5
4
|
|
|
6
5
|
import { ListProps, Size } from '@lumx/react';
|
|
7
6
|
import { GenericProps } from '@lumx/react/utils/type';
|
|
@@ -65,7 +64,7 @@ const DEFAULT_PROPS: Partial<ListProps> = {
|
|
|
65
64
|
* @return `true` if the list item is clickable; `false` otherwise.
|
|
66
65
|
*/
|
|
67
66
|
export function isClickable({ linkProps, onItemSelected }: Partial<ListItemProps>): boolean {
|
|
68
|
-
return
|
|
67
|
+
return !!linkProps?.href || !!onItemSelected;
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
/**
|
|
@@ -4,7 +4,6 @@ import { isClickable } from '@lumx/react/components/list/ListItem';
|
|
|
4
4
|
import { isComponent } from '@lumx/react/utils/type';
|
|
5
5
|
import { flattenChildren } from '@lumx/react/utils/flattenChildren';
|
|
6
6
|
import { mergeRefs } from '@lumx/react/utils/mergeRefs';
|
|
7
|
-
import get from 'lodash/get';
|
|
8
7
|
import {
|
|
9
8
|
cloneElement,
|
|
10
9
|
Key,
|
|
@@ -147,7 +146,7 @@ export const useInteractiveList: useInteractiveList = (options) => {
|
|
|
147
146
|
setActiveItemIndex(nextIndex);
|
|
148
147
|
evt.preventDefault();
|
|
149
148
|
evt.stopPropagation();
|
|
150
|
-
onListItemNavigated?.(nextIndex,
|
|
149
|
+
onListItemNavigated?.(nextIndex, (items[nextIndex] as ReactElement)?.key);
|
|
151
150
|
};
|
|
152
151
|
|
|
153
152
|
/**
|
|
@@ -5,8 +5,8 @@ import { render, screen, within } from '@testing-library/react';
|
|
|
5
5
|
import { getByClassName, queryAllByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
6
|
import { Thumbnail } from '@lumx/react';
|
|
7
7
|
import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
|
|
8
|
-
import range from 'lodash/range';
|
|
9
8
|
import userEvent from '@testing-library/user-event';
|
|
9
|
+
import { range } from '@lumx/react/utils/collection/range';
|
|
10
10
|
|
|
11
11
|
const CLASSNAME = Mosaic.className as string;
|
|
12
12
|
|
|
@@ -19,8 +19,8 @@ const setup = (props: Partial<MosaicProps> = {}, { wrapper }: SetupRenderOptions
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const generateThumbnails = (count: number) =>
|
|
22
|
-
range(
|
|
23
|
-
image: `https://example.com/image${i}.png`,
|
|
22
|
+
range(count).map((i) => ({
|
|
23
|
+
image: `https://example.com/image${i + 1}.png`,
|
|
24
24
|
alt: '',
|
|
25
25
|
}));
|
|
26
26
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React, { MouseEventHandler, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import take from 'lodash/take';
|
|
5
|
-
import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
|
|
6
4
|
|
|
5
|
+
import { useTheme } from '@lumx/react/utils/theme/ThemeContext';
|
|
7
6
|
import { Alignment, AspectRatio, Theme, Thumbnail, ThumbnailProps } from '@lumx/react';
|
|
8
7
|
import { GenericProps, HasTheme } from '@lumx/react/utils/type';
|
|
9
8
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
@@ -66,7 +65,7 @@ export const Mosaic = forwardRef<MosaicProps, HTMLDivElement>((props, ref) => {
|
|
|
66
65
|
})}
|
|
67
66
|
>
|
|
68
67
|
<div className={`${CLASSNAME}__wrapper`}>
|
|
69
|
-
{
|
|
68
|
+
{thumbnails.slice(-4).map((thumbnail: any, index: number) => {
|
|
70
69
|
const { image, onClick, align, ...thumbnailProps } = thumbnail;
|
|
71
70
|
|
|
72
71
|
return (
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
2
3
|
import classNames from 'classnames';
|
|
4
|
+
|
|
3
5
|
import { HasAriaLabelOrLabelledBy, HasClassName, HasTheme } from '@lumx/react/utils/type';
|
|
4
6
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
5
7
|
import { Orientation, Theme } from '@lumx/react';
|
|
6
8
|
import { ThemeProvider, useTheme } from '@lumx/react/utils/theme/ThemeContext';
|
|
9
|
+
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
10
|
+
|
|
7
11
|
import { NavigationSection } from './NavigationSection';
|
|
8
12
|
import { NavigationItem } from './NavigationItem';
|
|
9
13
|
import { NavigationContext } from './context';
|
|
@@ -12,7 +16,7 @@ export type NavigationProps = React.ComponentProps<'nav'> &
|
|
|
12
16
|
HasClassName &
|
|
13
17
|
HasTheme & {
|
|
14
18
|
/** Content of the navigation. These components should be of type NavigationItem to be rendered */
|
|
15
|
-
children?: ReactNode;
|
|
19
|
+
children?: React.ReactNode;
|
|
16
20
|
orientation?: Orientation;
|
|
17
21
|
} & HasAriaLabelOrLabelledBy;
|
|
18
22
|
|
|
@@ -33,38 +37,39 @@ const DEFAULT_PROPS = {
|
|
|
33
37
|
orientation: Orientation.vertical,
|
|
34
38
|
};
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
40
|
+
type SubComponents = {
|
|
41
|
+
Section: typeof NavigationSection;
|
|
42
|
+
Item: typeof NavigationItem;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const Navigation = forwardRef<NavigationProps, HTMLElement, SubComponents>((props, ref) => {
|
|
46
|
+
const defaultTheme = useTheme() || Theme.light;
|
|
47
|
+
const { children, className, theme = defaultTheme, orientation, ...forwardedProps } = props;
|
|
48
|
+
return (
|
|
49
|
+
<ThemeProvider value={theme}>
|
|
50
|
+
<nav
|
|
51
|
+
className={classNames(
|
|
52
|
+
className,
|
|
53
|
+
handleBasicClasses({
|
|
54
|
+
prefix: CLASSNAME,
|
|
55
|
+
theme,
|
|
56
|
+
orientation,
|
|
57
|
+
}),
|
|
58
|
+
)}
|
|
59
|
+
ref={ref}
|
|
60
|
+
{...forwardedProps}
|
|
61
|
+
>
|
|
62
|
+
<NavigationContext.Provider value={{ orientation }}>
|
|
63
|
+
<ul className={`${CLASSNAME}__list`}>{children}</ul>
|
|
64
|
+
</NavigationContext.Provider>
|
|
65
|
+
</nav>
|
|
66
|
+
</ThemeProvider>
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
Navigation.displayName = COMPONENT_NAME;
|
|
70
|
+
Navigation.className = CLASSNAME;
|
|
71
|
+
Navigation.defaultProps = DEFAULT_PROPS;
|
|
72
|
+
|
|
73
|
+
// Sub components
|
|
74
|
+
Navigation.Section = NavigationSection;
|
|
75
|
+
Navigation.Item = NavigationItem;
|