@lumx/react 2.1.1 → 2.1.5
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/README.md +1 -1
- package/esm/_internal/Avatar2.js +5 -1
- package/esm/_internal/Avatar2.js.map +1 -1
- package/esm/_internal/Button2.js.map +1 -1
- package/esm/_internal/ButtonRoot.js +14 -4
- package/esm/_internal/ButtonRoot.js.map +1 -1
- package/esm/_internal/ClickAwayProvider.js +1 -1
- package/esm/_internal/Dialog2.js +13 -8
- package/esm/_internal/Dialog2.js.map +1 -1
- package/esm/_internal/DragHandle.js +1 -1
- package/esm/_internal/DragHandle.js.map +1 -1
- package/esm/_internal/Flag2.js +1 -3
- package/esm/_internal/Flag2.js.map +1 -1
- package/esm/_internal/IconButton.js +0 -2
- package/esm/_internal/IconButton.js.map +1 -1
- package/esm/_internal/List2.js +16 -9
- package/esm/_internal/List2.js.map +1 -1
- package/esm/_internal/Message2.js +2 -2
- package/esm/_internal/Message2.js.map +1 -1
- package/esm/_internal/SlideshowControls.js +3 -3
- package/esm/_internal/SlideshowControls.js.map +1 -1
- package/esm/_internal/TextField.js +5 -2
- package/esm/_internal/TextField.js.map +1 -1
- package/esm/_internal/Thumbnail2.js +29 -34
- package/esm/_internal/Thumbnail2.js.map +1 -1
- package/esm/_internal/Tooltip2.js +1 -1
- package/esm/_internal/UserBlock.js +44 -14
- package/esm/_internal/UserBlock.js.map +1 -1
- package/esm/_internal/getRootClassName.js +17 -1
- package/esm/_internal/getRootClassName.js.map +1 -1
- package/esm/_internal/user-block.js +1 -0
- package/esm/_internal/user-block.js.map +1 -1
- package/package.json +4 -8
- package/src/components/avatar/Avatar.stories.tsx +1 -1
- package/src/components/avatar/Avatar.tsx +8 -0
- package/src/components/button/Button.stories.tsx +85 -15
- package/src/components/button/Button.tsx +2 -0
- package/src/components/button/ButtonRoot.test.tsx +13 -0
- package/src/components/button/ButtonRoot.tsx +10 -1
- package/src/components/button/IconButton.test.tsx +9 -0
- package/src/components/button/IconButton.tsx +11 -26
- package/src/components/button/__snapshots__/ButtonRoot.test.tsx.snap +13 -0
- package/src/components/button/__snapshots__/IconButton.test.tsx.snap +19 -0
- package/src/components/comment-block/CommentBlock.stories.tsx +1 -1
- package/src/components/dialog/Dialog.stories.tsx +45 -3
- package/src/components/dialog/Dialog.tsx +15 -11
- package/src/components/dialog/__snapshots__/Dialog.test.tsx.snap +76 -0
- package/src/components/drag-handle/DragHandle.tsx +5 -1
- package/src/components/flag/Flag.test.tsx +1 -2
- package/src/components/flag/Flag.tsx +2 -10
- package/src/components/flag/__snapshots__/Flag.test.tsx.snap +0 -15
- package/src/components/image-block/ImageBlock.stories.tsx +1 -1
- package/src/components/link-preview/LinkPreview.stories.tsx +1 -1
- package/src/components/list/List.stories.tsx +7 -1
- package/src/components/list/ListItem.stories.tsx +28 -3
- package/src/components/list/ListItem.tsx +25 -7
- package/src/components/list/__snapshots__/List.test.tsx.snap +23 -3
- package/src/components/list/__snapshots__/ListItem.test.tsx.snap +84 -11
- package/src/components/list/useInteractiveList.tsx +1 -1
- package/src/components/message/Message.tsx +2 -2
- package/src/components/skeleton/SkeletonRectangle.stories.tsx +1 -1
- package/src/components/slideshow/useKeyNavigate.ts +2 -2
- package/src/components/text-field/TextField.stories.tsx +97 -82
- package/src/components/text-field/TextField.tsx +5 -0
- package/src/components/thumbnail/Thumbnail.stories.tsx +22 -1
- package/src/components/thumbnail/Thumbnail.test.tsx +20 -2
- package/src/components/thumbnail/Thumbnail.tsx +40 -15
- package/src/components/thumbnail/__snapshots__/Thumbnail.test.tsx.snap +53 -6
- package/src/components/user-block/UserBlock.stories.tsx +28 -5
- package/src/components/user-block/UserBlock.tsx +40 -16
- package/src/components/user-block/__snapshots__/UserBlock.test.tsx.snap +244 -145
- package/src/stories/generated/Button/Demos.stories.tsx +1 -0
- package/src/stories/knobs/buttonKnob.ts +9 -0
- package/src/stories/knobs/emphasisKnob.ts +8 -0
- package/src/utils/MaterialThemeSwitcher/MaterialThemeSwitcher.tsx +54 -0
- package/src/utils/MaterialThemeSwitcher/index.ts +1 -0
- package/src/stories/knobs/index.ts +0 -2
- package/types.d.ts +0 -2561
|
@@ -4,27 +4,17 @@ import { Emphasis, Icon, Size, Theme, Tooltip, TooltipProps } from '@lumx/react'
|
|
|
4
4
|
import { BaseButtonProps, ButtonRoot } from '@lumx/react/components/button/ButtonRoot';
|
|
5
5
|
import { Comp, getRootClassName } from '@lumx/react/utils';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| {
|
|
19
|
-
/**
|
|
20
|
-
* Image URL (use icon SVG path when possible).
|
|
21
|
-
*/
|
|
22
|
-
image: string;
|
|
23
|
-
icon?: undefined;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/** Props common to icon and image type icon. */
|
|
27
|
-
export interface IconButtonBaseProps {
|
|
7
|
+
export interface IconButtonProps extends BaseButtonProps {
|
|
8
|
+
/**
|
|
9
|
+
* Icon (SVG path).
|
|
10
|
+
* If `image` is also set, `image` will be used instead.
|
|
11
|
+
*/
|
|
12
|
+
icon?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Image (image url).
|
|
15
|
+
* Has priority over `icon`.
|
|
16
|
+
*/
|
|
17
|
+
image?: string;
|
|
28
18
|
/**
|
|
29
19
|
* Label text (required for a11y purpose).
|
|
30
20
|
* If you really don't want an aria-label, you can set an empty label (this is not recommended).
|
|
@@ -39,11 +29,6 @@ export interface IconButtonBaseProps {
|
|
|
39
29
|
hideTooltip?: boolean;
|
|
40
30
|
}
|
|
41
31
|
|
|
42
|
-
/**
|
|
43
|
-
* Defines the props of the component.
|
|
44
|
-
*/
|
|
45
|
-
export type IconButtonProps = IconButtonBaseProps & ImageOrIconType & BaseButtonProps;
|
|
46
|
-
|
|
47
32
|
/**
|
|
48
33
|
* Component display name.
|
|
49
34
|
*/
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
+
exports[`<ButtonRoot> Props should be full width 1`] = `
|
|
4
|
+
<ButtonRoot
|
|
5
|
+
emphasis="high"
|
|
6
|
+
fullWidth={true}
|
|
7
|
+
theme="light"
|
|
8
|
+
>
|
|
9
|
+
<button
|
|
10
|
+
className="lumx-button lumx-button--color-primary lumx-button--emphasis-high lumx-button--theme-light lumx-button--is-full-width"
|
|
11
|
+
type="button"
|
|
12
|
+
/>
|
|
13
|
+
</ButtonRoot>
|
|
14
|
+
`;
|
|
15
|
+
|
|
3
16
|
exports[`<ButtonRoot> Props should not have default color in low or medium emphasis 1`] = `
|
|
4
17
|
<ButtonRoot
|
|
5
18
|
emphasis="low"
|
|
@@ -67,3 +67,22 @@ exports[`<IconButton> Snapshots and structure should render icon button with an
|
|
|
67
67
|
</ButtonRoot>
|
|
68
68
|
</Tooltip>
|
|
69
69
|
`;
|
|
70
|
+
|
|
71
|
+
exports[`<IconButton> Snapshots and structure should render icon button with an image if both props are set 1`] = `
|
|
72
|
+
<Tooltip
|
|
73
|
+
delay={500}
|
|
74
|
+
placement="bottom"
|
|
75
|
+
>
|
|
76
|
+
<ButtonRoot
|
|
77
|
+
emphasis="high"
|
|
78
|
+
size="m"
|
|
79
|
+
theme="light"
|
|
80
|
+
variant="icon"
|
|
81
|
+
>
|
|
82
|
+
<img
|
|
83
|
+
alt=""
|
|
84
|
+
src="http://foo.com"
|
|
85
|
+
/>
|
|
86
|
+
</ButtonRoot>
|
|
87
|
+
</Tooltip>
|
|
88
|
+
`;
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { mdiDotsHorizontal, mdiHeart, mdiReply } from '@lumx/icons';
|
|
3
3
|
import { Button, CommentBlock, Emphasis, Size } from '@lumx/react';
|
|
4
4
|
import { IconButton } from '@lumx/react/components/button/IconButton';
|
|
5
|
-
import { avatarImageKnob } from '@lumx/react/stories/knobs';
|
|
5
|
+
import { avatarImageKnob } from '@lumx/react/stories/knobs/image';
|
|
6
6
|
|
|
7
7
|
export default { title: 'LumX components/comment-block/CommentBlock' };
|
|
8
8
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mdiClose } from '@lumx/icons';
|
|
2
2
|
import {
|
|
3
|
+
AlertDialog,
|
|
3
4
|
Button,
|
|
4
5
|
Checkbox,
|
|
5
6
|
DatePickerField,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
import { select } from '@storybook/addon-knobs';
|
|
18
19
|
import React, { RefObject, useRef, useState } from 'react';
|
|
19
20
|
import { Dialog, DialogSizes } from './Dialog';
|
|
20
|
-
import { loremIpsum } from '../../stories/knobs';
|
|
21
|
+
import { loremIpsum } from '../../stories/knobs/lorem';
|
|
21
22
|
|
|
22
23
|
export default {
|
|
23
24
|
title: 'LumX components/dialog/Dialog',
|
|
@@ -32,9 +33,9 @@ const content = <div className="lumx-spacing-padding">{loremIpsum('short')}</div
|
|
|
32
33
|
const longContent = <div className="lumx-spacing-padding">{loremIpsum('long')}</div>;
|
|
33
34
|
const footer = <footer className="lumx-spacing-padding">Dialog footer</footer>;
|
|
34
35
|
|
|
35
|
-
function useOpenButton(theme: Theme) {
|
|
36
|
+
function useOpenButton(theme: Theme, defaultState = true) {
|
|
36
37
|
const buttonRef = useRef() as RefObject<HTMLButtonElement>;
|
|
37
|
-
const [isOpen, setOpen] = useState(
|
|
38
|
+
const [isOpen, setOpen] = useState(defaultState);
|
|
38
39
|
const openDialog = () => setOpen(true);
|
|
39
40
|
const closeDialog = () => setOpen(false);
|
|
40
41
|
|
|
@@ -45,6 +46,7 @@ function useOpenButton(theme: Theme) {
|
|
|
45
46
|
</Button>
|
|
46
47
|
),
|
|
47
48
|
buttonRef,
|
|
49
|
+
openDialog,
|
|
48
50
|
closeDialog,
|
|
49
51
|
isOpen,
|
|
50
52
|
};
|
|
@@ -83,6 +85,46 @@ export const PreventDialogAutoClose = ({ theme }: any) => {
|
|
|
83
85
|
);
|
|
84
86
|
};
|
|
85
87
|
|
|
88
|
+
export const DialogWithAlertDialog = ({ theme }: any) => {
|
|
89
|
+
const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
|
|
90
|
+
const { openDialog: openAlertDialog, closeDialog: closeAlertDialog, isOpen: isAlertDialogOpen } = useOpenButton(
|
|
91
|
+
theme,
|
|
92
|
+
false,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const handleSubmitDialog = () => {
|
|
96
|
+
closeDialog();
|
|
97
|
+
openAlertDialog();
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<>
|
|
102
|
+
{button}
|
|
103
|
+
<Dialog isOpen={isOpen} onClose={closeDialog} parentElement={buttonRef}>
|
|
104
|
+
{content}
|
|
105
|
+
<footer>
|
|
106
|
+
<Toolbar
|
|
107
|
+
after={
|
|
108
|
+
<Button onClick={handleSubmitDialog} emphasis={Emphasis.low}>
|
|
109
|
+
Close
|
|
110
|
+
</Button>
|
|
111
|
+
}
|
|
112
|
+
/>
|
|
113
|
+
</footer>
|
|
114
|
+
</Dialog>
|
|
115
|
+
<AlertDialog
|
|
116
|
+
isOpen={isAlertDialogOpen}
|
|
117
|
+
onClose={closeDialog}
|
|
118
|
+
parentElement={buttonRef}
|
|
119
|
+
title="Default (info)"
|
|
120
|
+
confirmProps={{ onClick: closeAlertDialog, label: 'Confirm' }}
|
|
121
|
+
>
|
|
122
|
+
Consequat deserunt officia aute laborum tempor anim sint est.
|
|
123
|
+
</AlertDialog>
|
|
124
|
+
</>
|
|
125
|
+
);
|
|
126
|
+
};
|
|
127
|
+
|
|
86
128
|
export const Sizes = ({ theme }: any) => {
|
|
87
129
|
const { button, buttonRef, closeDialog, isOpen } = useOpenButton(theme);
|
|
88
130
|
const sizes: DialogSizes[] = [Size.tiny, Size.regular, Size.big, Size.huge];
|
|
@@ -115,18 +115,22 @@ export const Dialog: Comp<DialogProps, HTMLDivElement> = forwardRef((props, ref)
|
|
|
115
115
|
...forwardedProps
|
|
116
116
|
} = props;
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
119
|
+
const previousOpen = React.useRef(isOpen);
|
|
120
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
121
|
+
React.useEffect(() => {
|
|
122
|
+
if (isOpen !== previousOpen.current) {
|
|
123
|
+
previousOpen.current = isOpen;
|
|
124
|
+
|
|
125
|
+
// Focus the parent element on close.
|
|
126
|
+
if (!isOpen && parentElement && parentElement.current) {
|
|
127
|
+
parentElement.current.focus();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}, [isOpen, parentElement]);
|
|
127
131
|
|
|
128
132
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
129
|
-
useCallbackOnEscape(
|
|
133
|
+
useCallbackOnEscape(onClose, isOpen && !preventAutoClose);
|
|
130
134
|
|
|
131
135
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
132
136
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
@@ -192,7 +196,7 @@ export const Dialog: Comp<DialogProps, HTMLDivElement> = forwardRef((props, ref)
|
|
|
192
196
|
<div className={`${CLASSNAME}__overlay`} />
|
|
193
197
|
|
|
194
198
|
<section className={`${CLASSNAME}__container`} role="dialog" aria-modal="true" {...dialogProps}>
|
|
195
|
-
<ClickAwayProvider callback={!preventAutoClose &&
|
|
199
|
+
<ClickAwayProvider callback={!preventAutoClose && onClose} refs={clickAwayRefs}>
|
|
196
200
|
<div className={`${CLASSNAME}__wrapper`} ref={wrapperRef}>
|
|
197
201
|
{(header || headerChildContent) && (
|
|
198
202
|
<header
|
|
@@ -1,5 +1,81 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
+
exports[`<Dialog> Snapshots and structure should render story DialogWithAlertDialog 1`] = `
|
|
4
|
+
<Fragment>
|
|
5
|
+
<Button
|
|
6
|
+
emphasis="high"
|
|
7
|
+
onClick={[Function]}
|
|
8
|
+
size="m"
|
|
9
|
+
theme="light"
|
|
10
|
+
>
|
|
11
|
+
Open dialog
|
|
12
|
+
</Button>
|
|
13
|
+
<Dialog
|
|
14
|
+
isOpen={true}
|
|
15
|
+
onClose={[Function]}
|
|
16
|
+
parentElement={
|
|
17
|
+
Object {
|
|
18
|
+
"current": undefined,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
size="big"
|
|
22
|
+
>
|
|
23
|
+
<div
|
|
24
|
+
className="lumx-spacing-padding"
|
|
25
|
+
>
|
|
26
|
+
|
|
27
|
+
Nihil hic munitissimus habendi senatus locus, nihil horum? At nos hinc posthac, sitientis piros
|
|
28
|
+
Afros. Magna pars studiorum, prodita quaerimus. Integer legentibus erat a ante historiarum
|
|
29
|
+
dapibus. Praeterea iter est quasdam res quas ex communi. Ullamco laboris nisi ut aliquid ex ea
|
|
30
|
+
commodi consequat. Inmensae subtilitatis, obscuris et malesuada fames. Me non paenitet nullum
|
|
31
|
+
festiviorem excogitasse ad hoc. Cum ceteris in veneratione tui montes, nascetur mus. Etiam
|
|
32
|
+
habebis sem dicantur magna mollis euismod. Quis aute iure reprehenderit in voluptate velit esse.
|
|
33
|
+
Phasellus laoreet lorem vel dolor tempus vehicula. Ambitioni dedisse scripsisse iudicaretur.
|
|
34
|
+
Paullum deliquit, ponderibus modulisque suis ratio utitur. Ab illo tempore, ab est sed
|
|
35
|
+
immemorabili. Nec dubitamus multa iter quae et nos invenerat. Tu quoque, Brute, fili mi, nihil
|
|
36
|
+
timor populi, nihil! Morbi fringilla convallis sapien, id pulvinar odio volutpat. Cras mattis
|
|
37
|
+
iudicium purus sit amet fermentum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
|
|
38
|
+
Quisque ut dolor gravida, placerat libero vel, euismod. Unam incolunt Belgae, aliam Aquitani,
|
|
39
|
+
tertiam. Cras mattis iudicium purus sit amet fermentum
|
|
40
|
+
</div>
|
|
41
|
+
<footer>
|
|
42
|
+
<Toolbar
|
|
43
|
+
after={
|
|
44
|
+
<Button
|
|
45
|
+
emphasis="low"
|
|
46
|
+
onClick={[Function]}
|
|
47
|
+
size="m"
|
|
48
|
+
theme="light"
|
|
49
|
+
>
|
|
50
|
+
Close
|
|
51
|
+
</Button>
|
|
52
|
+
}
|
|
53
|
+
/>
|
|
54
|
+
</footer>
|
|
55
|
+
</Dialog>
|
|
56
|
+
<AlertDialog
|
|
57
|
+
confirmProps={
|
|
58
|
+
Object {
|
|
59
|
+
"label": "Confirm",
|
|
60
|
+
"onClick": [Function],
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
isOpen={false}
|
|
64
|
+
kind="info"
|
|
65
|
+
onClose={[Function]}
|
|
66
|
+
parentElement={
|
|
67
|
+
Object {
|
|
68
|
+
"current": undefined,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
size="tiny"
|
|
72
|
+
title="Default (info)"
|
|
73
|
+
>
|
|
74
|
+
Consequat deserunt officia aute laborum tempor anim sint est.
|
|
75
|
+
</AlertDialog>
|
|
76
|
+
</Fragment>
|
|
77
|
+
`;
|
|
78
|
+
|
|
3
79
|
exports[`<Dialog> Snapshots and structure should render story DialogWithFocusableElements 1`] = `
|
|
4
80
|
<Fragment>
|
|
5
81
|
<Button
|
|
@@ -40,7 +40,11 @@ export const DragHandle: Comp<DragHandleProps, HTMLDivElement> = forwardRef((pro
|
|
|
40
40
|
{...forwardedProps}
|
|
41
41
|
className={classNames(className, handleBasicClasses({ prefix: CLASSNAME, theme }))}
|
|
42
42
|
>
|
|
43
|
-
<Icon
|
|
43
|
+
<Icon
|
|
44
|
+
icon={mdiDragVertical}
|
|
45
|
+
color={theme === Theme.dark ? ColorPalette.light : ColorPalette.dark}
|
|
46
|
+
size={Size.xs}
|
|
47
|
+
/>
|
|
44
48
|
</div>
|
|
45
49
|
);
|
|
46
50
|
});
|
|
@@ -69,9 +69,8 @@ describe(`<${Flag.displayName} />`, () => {
|
|
|
69
69
|
|
|
70
70
|
it('should use the color', () => {
|
|
71
71
|
const color = ColorPalette.green;
|
|
72
|
-
const { wrapper
|
|
72
|
+
const { wrapper } = setup({ icon: mdiAbTesting, color });
|
|
73
73
|
|
|
74
|
-
expect(iconEl.prop('color')).toEqual(color);
|
|
75
74
|
expect(wrapper).toHaveClassName(
|
|
76
75
|
getBasicClass({
|
|
77
76
|
prefix: CLASSNAME,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
|
|
4
|
-
import { ColorPalette,
|
|
4
|
+
import { ColorPalette, Icon, Size, Theme } from '@lumx/react';
|
|
5
5
|
import { Comp, GenericProps, getRootClassName, handleBasicClasses } from '@lumx/react/utils';
|
|
6
6
|
|
|
7
7
|
export interface FlagProps extends GenericProps {
|
|
@@ -38,15 +38,7 @@ export const Flag: Comp<FlagProps, HTMLDivElement> = forwardRef((props, ref) =>
|
|
|
38
38
|
className={classNames(className, handleBasicClasses({ prefix: CLASSNAME, color: flagColor }))}
|
|
39
39
|
ref={ref}
|
|
40
40
|
>
|
|
41
|
-
{icon &&
|
|
42
|
-
<Icon
|
|
43
|
-
icon={icon}
|
|
44
|
-
color={color}
|
|
45
|
-
colorVariant={ColorVariant.D2}
|
|
46
|
-
size={Size.xxs}
|
|
47
|
-
className={`${CLASSNAME}__icon`}
|
|
48
|
-
/>
|
|
49
|
-
)}
|
|
41
|
+
{icon && <Icon icon={icon} size={Size.xxs} className={`${CLASSNAME}__icon`} />}
|
|
50
42
|
<span className={`${CLASSNAME}__label`}>{label}</span>
|
|
51
43
|
</div>
|
|
52
44
|
);
|
|
@@ -19,8 +19,6 @@ Array [
|
|
|
19
19
|
>
|
|
20
20
|
<Icon
|
|
21
21
|
className="lumx-flag__icon"
|
|
22
|
-
color="blue"
|
|
23
|
-
colorVariant="D2"
|
|
24
22
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
25
23
|
size="xxs"
|
|
26
24
|
/>
|
|
@@ -35,8 +33,6 @@ Array [
|
|
|
35
33
|
>
|
|
36
34
|
<Icon
|
|
37
35
|
className="lumx-flag__icon"
|
|
38
|
-
color="dark"
|
|
39
|
-
colorVariant="D2"
|
|
40
36
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
41
37
|
size="xxs"
|
|
42
38
|
/>
|
|
@@ -51,8 +47,6 @@ Array [
|
|
|
51
47
|
>
|
|
52
48
|
<Icon
|
|
53
49
|
className="lumx-flag__icon"
|
|
54
|
-
color="green"
|
|
55
|
-
colorVariant="D2"
|
|
56
50
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
57
51
|
size="xxs"
|
|
58
52
|
/>
|
|
@@ -67,8 +61,6 @@ Array [
|
|
|
67
61
|
>
|
|
68
62
|
<Icon
|
|
69
63
|
className="lumx-flag__icon"
|
|
70
|
-
color="primary"
|
|
71
|
-
colorVariant="D2"
|
|
72
64
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
73
65
|
size="xxs"
|
|
74
66
|
/>
|
|
@@ -83,8 +75,6 @@ Array [
|
|
|
83
75
|
>
|
|
84
76
|
<Icon
|
|
85
77
|
className="lumx-flag__icon"
|
|
86
|
-
color="red"
|
|
87
|
-
colorVariant="D2"
|
|
88
78
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
89
79
|
size="xxs"
|
|
90
80
|
/>
|
|
@@ -99,8 +89,6 @@ Array [
|
|
|
99
89
|
>
|
|
100
90
|
<Icon
|
|
101
91
|
className="lumx-flag__icon"
|
|
102
|
-
color="secondary"
|
|
103
|
-
colorVariant="D2"
|
|
104
92
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
105
93
|
size="xxs"
|
|
106
94
|
/>
|
|
@@ -115,8 +103,6 @@ Array [
|
|
|
115
103
|
>
|
|
116
104
|
<Icon
|
|
117
105
|
className="lumx-flag__icon"
|
|
118
|
-
color="yellow"
|
|
119
|
-
colorVariant="D2"
|
|
120
106
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
121
107
|
size="xxs"
|
|
122
108
|
/>
|
|
@@ -135,7 +121,6 @@ exports[`<Flag /> Snapshots and structure should render story 'withIcon' 1`] = `
|
|
|
135
121
|
>
|
|
136
122
|
<Icon
|
|
137
123
|
className="lumx-flag__icon"
|
|
138
|
-
colorVariant="D2"
|
|
139
124
|
icon="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
|
|
140
125
|
size="xxs"
|
|
141
126
|
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LANDSCAPE_IMAGES, landscapeImageKnob } from '@lumx/react/stories/knobs';
|
|
1
|
+
import { LANDSCAPE_IMAGES, landscapeImageKnob } from '@lumx/react/stories/knobs/image';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
4
|
import { Alignment, AspectRatio, Chip, ChipGroup, ImageBlock, Size } from '@lumx/react';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* istanbul ignore file */
|
|
2
|
-
import { landscapeImageKnob, portraitImageKnob } from '@lumx/react/stories/knobs';
|
|
2
|
+
import { landscapeImageKnob, portraitImageKnob } from '@lumx/react/stories/knobs/image';
|
|
3
3
|
import { text } from '@storybook/addon-knobs';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { Size } from '..';
|
|
@@ -46,10 +46,16 @@ export const KeyboardNavigation = () => {
|
|
|
46
46
|
<ListItem linkProps={{ href: '#' }}>Link item 2</ListItem>
|
|
47
47
|
<ListSubheader>Header</ListSubheader>
|
|
48
48
|
</>
|
|
49
|
+
<ListItem linkProps={{ href: '#' }} isDisabled>
|
|
50
|
+
Disabled link item
|
|
51
|
+
</ListItem>
|
|
52
|
+
<ListItem onItemSelected={action('onItemSelected')} isDisabled>
|
|
53
|
+
Disabled button item
|
|
54
|
+
</ListItem>
|
|
49
55
|
<CustomListItem />
|
|
50
56
|
{[
|
|
51
57
|
<ListItem key="1" linkProps={{ href: '#' }}>
|
|
52
|
-
Link item
|
|
58
|
+
Link item 4
|
|
53
59
|
</ListItem>,
|
|
54
60
|
]}
|
|
55
61
|
</List>
|
|
@@ -2,12 +2,37 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { Size } from '@lumx/react';
|
|
4
4
|
import { select, text } from '@storybook/addon-knobs';
|
|
5
|
+
import { action } from '@storybook/addon-actions';
|
|
5
6
|
|
|
6
7
|
import { ListItem } from './ListItem';
|
|
7
8
|
|
|
8
9
|
export default { title: 'LumX components/list/ListItem' };
|
|
9
10
|
|
|
10
|
-
export const
|
|
11
|
+
export const NonClickable = ({ theme }: any) => <ListItem theme={theme}>{text('text', 'Text')}</ListItem>;
|
|
12
|
+
|
|
13
|
+
export const Link = ({ theme }: any) => (
|
|
14
|
+
<ListItem theme={theme} linkProps={{ href: '#' }}>
|
|
15
|
+
{text('text', 'Text')}
|
|
16
|
+
</ListItem>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export const Button = ({ theme }: any) => (
|
|
20
|
+
<ListItem theme={theme} onItemSelected={action('onItemSelected')}>
|
|
21
|
+
{text('text', 'Text')}
|
|
22
|
+
</ListItem>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const LinkDisabled = ({ theme }: any) => (
|
|
26
|
+
<ListItem theme={theme} linkProps={{ href: '#' }} isDisabled>
|
|
27
|
+
{text('text', 'Text')}
|
|
28
|
+
</ListItem>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export const ButtonDisabled = ({ theme }: any) => (
|
|
32
|
+
<ListItem theme={theme} onItemSelected={action('onItemSelected')} isDisabled>
|
|
33
|
+
{text('text', 'Text')}
|
|
34
|
+
</ListItem>
|
|
35
|
+
);
|
|
11
36
|
|
|
12
37
|
export const Selected = ({ theme }: any) => (
|
|
13
38
|
<ListItem theme={theme} linkProps={{ href: '#' }} isSelected>
|
|
@@ -28,10 +53,10 @@ export const Sizes = ({ theme }: any) => (
|
|
|
28
53
|
);
|
|
29
54
|
|
|
30
55
|
const CustomLink: React.FC = ({ children, ...props }) =>
|
|
31
|
-
React.createElement('a', { ...props, style: { color: 'red' } }, children);
|
|
56
|
+
React.createElement('a', { ...props, style: { color: 'red' }, href: 'http://google.com' }, children);
|
|
32
57
|
|
|
33
58
|
export const WithCustomLink = ({ theme }: any) => (
|
|
34
|
-
<ListItem theme={theme} linkAs={CustomLink}
|
|
59
|
+
<ListItem theme={theme} linkAs={CustomLink}>
|
|
35
60
|
My custom link
|
|
36
61
|
</ListItem>
|
|
37
62
|
);
|
|
@@ -4,7 +4,14 @@ import classNames from 'classnames';
|
|
|
4
4
|
import isEmpty from 'lodash/isEmpty';
|
|
5
5
|
|
|
6
6
|
import { ListProps, Size } from '@lumx/react';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Comp,
|
|
9
|
+
GenericProps,
|
|
10
|
+
getRootClassName,
|
|
11
|
+
handleBasicClasses,
|
|
12
|
+
onEnterPressed,
|
|
13
|
+
onButtonPressed,
|
|
14
|
+
} from '@lumx/react/utils';
|
|
8
15
|
import { renderLink } from '@lumx/react/utils/renderLink';
|
|
9
16
|
|
|
10
17
|
export type ListItemSize = Extract<Size, 'tiny' | 'regular' | 'big' | 'huge'>;
|
|
@@ -23,6 +30,8 @@ export interface ListItemProps extends GenericProps {
|
|
|
23
30
|
isHighlighted?: boolean;
|
|
24
31
|
/** Whether the component is selected or not. */
|
|
25
32
|
isSelected?: boolean;
|
|
33
|
+
/** Whether link/button is disabled or not. */
|
|
34
|
+
isDisabled?: boolean;
|
|
26
35
|
/** Reference to the <li> element. */
|
|
27
36
|
listItemRef?: Ref<HTMLLIElement>;
|
|
28
37
|
/** Custom react component for the link (can be used to inject react router Link). */
|
|
@@ -33,6 +42,7 @@ export interface ListItemProps extends GenericProps {
|
|
|
33
42
|
linkRef?: Ref<HTMLAnchorElement>;
|
|
34
43
|
/** Size variant. */
|
|
35
44
|
size?: ListItemSize;
|
|
45
|
+
|
|
36
46
|
/** On selected callback. */
|
|
37
47
|
onItemSelected?(evt: SyntheticEvent): void;
|
|
38
48
|
}
|
|
@@ -77,6 +87,7 @@ export const ListItem: Comp<ListItemProps, HTMLLIElement> = forwardRef((props, r
|
|
|
77
87
|
className,
|
|
78
88
|
isHighlighted,
|
|
79
89
|
isSelected,
|
|
90
|
+
isDisabled,
|
|
80
91
|
linkAs,
|
|
81
92
|
linkProps = {},
|
|
82
93
|
linkRef,
|
|
@@ -84,9 +95,13 @@ export const ListItem: Comp<ListItemProps, HTMLLIElement> = forwardRef((props, r
|
|
|
84
95
|
size,
|
|
85
96
|
...forwardedProps
|
|
86
97
|
} = props;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
|
|
99
|
+
const role = linkAs || linkProps.href ? 'link' : 'button';
|
|
100
|
+
const onKeyDown = useMemo(() => {
|
|
101
|
+
if (onItemSelected && role === 'link') return onEnterPressed(onItemSelected as any);
|
|
102
|
+
if (onItemSelected && role === 'button') return onButtonPressed(onItemSelected as any);
|
|
103
|
+
return undefined;
|
|
104
|
+
}, [role, onItemSelected]);
|
|
90
105
|
|
|
91
106
|
const content = (
|
|
92
107
|
<>
|
|
@@ -113,17 +128,20 @@ export const ListItem: Comp<ListItemProps, HTMLLIElement> = forwardRef((props, r
|
|
|
113
128
|
renderLink(
|
|
114
129
|
{
|
|
115
130
|
linkAs,
|
|
116
|
-
tabIndex: 0,
|
|
117
|
-
role
|
|
131
|
+
tabIndex: !isDisabled && role === 'button' ? 0 : undefined,
|
|
132
|
+
role,
|
|
133
|
+
'aria-disabled': isDisabled,
|
|
118
134
|
...linkProps,
|
|
135
|
+
href: isDisabled ? undefined : linkProps.href,
|
|
119
136
|
className: classNames(
|
|
120
137
|
handleBasicClasses({
|
|
121
138
|
prefix: `${CLASSNAME}__link`,
|
|
122
139
|
isHighlighted,
|
|
123
140
|
isSelected,
|
|
141
|
+
isDisabled,
|
|
124
142
|
}),
|
|
125
143
|
),
|
|
126
|
-
onClick: onItemSelected,
|
|
144
|
+
onClick: isDisabled ? undefined : onItemSelected,
|
|
127
145
|
onKeyDown,
|
|
128
146
|
ref: linkRef,
|
|
129
147
|
},
|
|
@@ -129,12 +129,32 @@ exports[`<List> Snapshots and structure should render story 'KeyboardNavigation'
|
|
|
129
129
|
>
|
|
130
130
|
Header
|
|
131
131
|
</ListSubheader>
|
|
132
|
-
<
|
|
132
|
+
<ListItem
|
|
133
|
+
isDisabled={true}
|
|
133
134
|
key=".4"
|
|
135
|
+
linkProps={
|
|
136
|
+
Object {
|
|
137
|
+
"href": "#",
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
size="regular"
|
|
141
|
+
>
|
|
142
|
+
Disabled link item
|
|
143
|
+
</ListItem>
|
|
144
|
+
<ListItem
|
|
145
|
+
isDisabled={true}
|
|
146
|
+
key=".5"
|
|
147
|
+
onItemSelected={[Function]}
|
|
148
|
+
size="regular"
|
|
149
|
+
>
|
|
150
|
+
Disabled button item
|
|
151
|
+
</ListItem>
|
|
152
|
+
<CustomListItem
|
|
153
|
+
key=".6"
|
|
134
154
|
/>
|
|
135
155
|
<ListItem
|
|
136
156
|
isHighlighted={false}
|
|
137
|
-
key=".
|
|
157
|
+
key=".7:$1"
|
|
138
158
|
linkProps={
|
|
139
159
|
Object {
|
|
140
160
|
"href": "#",
|
|
@@ -147,7 +167,7 @@ exports[`<List> Snapshots and structure should render story 'KeyboardNavigation'
|
|
|
147
167
|
onMouseUp={[Function]}
|
|
148
168
|
size="regular"
|
|
149
169
|
>
|
|
150
|
-
Link item
|
|
170
|
+
Link item 4
|
|
151
171
|
</ListItem>
|
|
152
172
|
</ul>
|
|
153
173
|
`;
|