@lumx/react 3.1.5 → 3.2.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.
- package/_internal/types.d.ts +16 -5
- package/index.d.ts +45 -4
- package/index.js +632 -423
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/alert-dialog/AlertDialog.stories.tsx +96 -165
- package/src/components/alert-dialog/AlertDialog.test.tsx +15 -23
- package/src/components/avatar/Avatar.stories.tsx +91 -62
- package/src/components/avatar/Avatar.test.tsx +9 -24
- package/src/components/badge/Badge.stories.tsx +63 -38
- package/src/components/button/Button.stories.tsx +147 -139
- package/src/components/button/IconButton.stories.tsx +45 -0
- package/src/components/checkbox/Checkbox.stories.tsx +37 -30
- package/src/components/chip/Chip.stories.tsx +77 -15
- package/src/components/comment-block/CommentBlock.stories.tsx +90 -25
- package/src/components/comment-block/CommentBlock.test.tsx +12 -17
- package/src/components/date-picker/DatePickerField.stories.tsx +52 -83
- package/src/components/dialog/Dialog.stories.tsx +131 -293
- package/src/components/dialog/Dialog.test.tsx +0 -32
- package/src/components/dropdown/Dropdown.stories.tsx +1 -186
- package/src/components/flag/Flag.stories.tsx +33 -18
- package/src/components/flag/Flag.test.tsx +1 -8
- package/src/components/flex-box/FlexBox.stories.tsx +151 -238
- package/src/components/flex-box/FlexBox.test.tsx +9 -49
- package/src/components/generic-block/GenericBlock.stories.jsx +1 -1
- package/src/components/grid-column/GridColumn.stories.tsx +46 -0
- package/src/components/heading/Heading.stories.tsx +57 -95
- package/src/components/icon/Icon.stories.tsx +67 -70
- package/src/components/image-block/ImageBlock.stories.tsx +103 -47
- package/src/components/image-block/ImageBlock.test.tsx +12 -17
- package/src/components/inline-list/InlineList.stories.tsx +45 -29
- package/src/components/input-helper/InputHelper.stories.tsx +31 -25
- package/src/components/input-label/InputLabel.stories.tsx +33 -10
- package/src/components/lightbox/Lightbox.stories.tsx +39 -77
- package/src/components/lightbox/Lightbox.test.tsx +12 -17
- package/src/components/link/Link.stories.tsx +98 -128
- package/src/components/link-preview/LinkPreview.stories.tsx +48 -75
- package/src/components/list/List.stories.tsx +59 -84
- package/src/components/list/List.test.tsx +8 -17
- package/src/components/list/ListDivider.stories.tsx +9 -4
- package/src/components/list/ListDivider.test.tsx +12 -17
- package/src/components/list/ListItem.stories.tsx +97 -59
- package/src/components/list/ListItem.test.tsx +12 -17
- package/src/components/list/ListSubheader.stories.tsx +8 -5
- package/src/components/list/ListSubheader.test.tsx +12 -18
- package/src/components/message/Message.stories.tsx +51 -22
- package/src/components/mosaic/Mosaic.stories.tsx +78 -74
- package/src/components/mosaic/Mosaic.test.tsx +0 -31
- package/src/components/navigation/Navigation.stories.tsx +67 -0
- package/src/components/navigation/Navigation.test.tsx +58 -0
- package/src/components/navigation/Navigation.tsx +62 -0
- package/src/components/navigation/NavigationItem.test.tsx +37 -0
- package/src/components/navigation/NavigationItem.tsx +89 -0
- package/src/components/navigation/NavigationSection.test.tsx +126 -0
- package/src/components/navigation/NavigationSection.tsx +109 -0
- package/src/components/navigation/context.tsx +6 -0
- package/src/components/navigation/index.ts +1 -0
- package/src/components/notification/Notifications.stories.tsx +52 -47
- package/src/components/popover/Popover.stories.tsx +68 -201
- package/src/components/popover/Popover.tsx +7 -9
- package/src/components/popover-dialog/PopoverDialog.stories.tsx +26 -65
- package/src/components/post-block/PostBlock.test.tsx +12 -17
- package/src/components/progress/ProgressCircular.stories.tsx +24 -12
- package/src/components/progress/ProgressLinear.stories.tsx +6 -2
- package/src/components/radio-button/RadioButton.stories.tsx +35 -24
- package/src/components/select/Select.stories.tsx +19 -23
- package/src/components/select/SelectMultiple.stories.tsx +105 -2
- package/src/components/select/WithSelectContext.tsx +10 -4
- package/src/components/skeleton/SkeletonCircle.stories.tsx +37 -21
- package/src/components/skeleton/SkeletonCircle.test.tsx +12 -17
- package/src/components/skeleton/SkeletonRectangle.stories.tsx +74 -99
- package/src/components/skeleton/SkeletonRectangle.test.tsx +12 -17
- package/src/components/skeleton/SkeletonTypography.test.tsx +12 -17
- package/src/components/slider/Slider.stories.tsx +41 -25
- package/src/components/slider/Slider.test.tsx +12 -18
- package/src/components/slideshow/Slideshow.stories.tsx +31 -61
- package/src/components/slideshow/Slideshow.test.tsx +15 -23
- package/src/components/slideshow/SlideshowControls.stories.tsx +4 -6
- package/src/components/switch/Switch.stories.tsx +35 -32
- package/src/components/table/Table.test.tsx +12 -17
- package/src/components/tabs/Tabs.stories.tsx +4 -3
- package/src/components/text/Text.stories.tsx +130 -0
- package/src/components/text-field/TextField.stories.tsx +114 -148
- package/src/components/thumbnail/Thumbnail.stories.tsx +106 -255
- package/src/components/thumbnail/Thumbnail.test.tsx +12 -35
- package/src/components/tooltip/Tooltip.stories.tsx +51 -136
- package/src/components/user-block/UserBlock.stories.tsx +67 -56
- package/src/components/user-block/UserBlock.test.tsx +1 -5
- package/src/hooks/useFocusTrap.ts +2 -2
- package/src/index.ts +1 -0
- package/src/stories/controls/color.ts +6 -0
- package/src/stories/controls/element.ts +6 -0
- package/src/stories/controls/focusPoint.ts +1 -0
- package/src/stories/controls/icons.ts +6 -0
- package/src/stories/{knobs → controls}/image.ts +6 -16
- package/src/stories/controls/selectArgType.ts +4 -0
- package/src/stories/controls/theme.ts +3 -0
- package/src/stories/controls/typography.ts +5 -0
- package/src/stories/controls/withUndefined.ts +1 -0
- package/src/stories/decorators/withChromaticForceScreenSize.tsx +8 -0
- package/src/stories/decorators/withCombinations.tsx +99 -0
- package/src/stories/decorators/withNestedProps.tsx +23 -0
- package/src/stories/{withResizableBox.tsx → decorators/withResizableBox.tsx} +6 -10
- package/src/stories/decorators/withValueOnChange.tsx +18 -0
- package/src/stories/decorators/withWrapper.tsx +19 -0
- package/src/stories/utils/CustomLink.tsx +8 -2
- package/src/stories/{knobs → utils}/lorem.ts +9 -9
- package/src/testing/utils/commonTestsSuiteRTL.ts +2 -3
- package/src/testing/utils/index.ts +0 -2
- package/src/untypped-modules.d.ts +0 -2
- package/src/utils/MaterialThemeSwitcher/MaterialThemeSwitcher.tsx +1 -1
- package/src/utils/ThemeContext.ts +4 -0
- package/src/utils/forwardRefPolymorphic.ts +9 -0
- package/src/utils/type.ts +28 -4
- package/src/components/alert-dialog/__snapshots__/AlertDialog.test.tsx.snap +0 -558
- package/src/components/avatar/__snapshots__/Avatar.test.tsx.snap +0 -681
- package/src/components/comment-block/__snapshots__/CommentBlock.test.tsx.snap +0 -92
- package/src/components/dialog/__snapshots__/Dialog.test.tsx.snap +0 -1133
- package/src/components/expansion-panel/ExpansionPanel.stories.tsx +0 -65
- package/src/components/flag/__snapshots__/Flag.test.tsx.snap +0 -133
- package/src/components/flex-box/__snapshots__/FlexBox.test.tsx.snap +0 -492
- package/src/components/grid-column/GridColumn.stories.jsx +0 -56
- package/src/components/image-block/__snapshots__/ImageBlock.test.tsx.snap +0 -64
- package/src/components/lightbox/__snapshots__/Lightbox.test.tsx.snap +0 -194
- package/src/components/list/__snapshots__/List.test.tsx.snap +0 -360
- package/src/components/list/__snapshots__/ListDivider.test.tsx.snap +0 -7
- package/src/components/list/__snapshots__/ListItem.test.tsx.snap +0 -160
- package/src/components/list/__snapshots__/ListSubheader.test.tsx.snap +0 -9
- package/src/components/mosaic/__snapshots__/Mosaic.test.tsx.snap +0 -357
- package/src/components/post-block/__snapshots__/PostBlock.test.tsx.snap +0 -139
- package/src/components/skeleton/__snapshots__/SkeletonCircle.test.tsx.snap +0 -54
- package/src/components/skeleton/__snapshots__/SkeletonRectangle.test.tsx.snap +0 -177
- package/src/components/skeleton/__snapshots__/SkeletonTypography.test.tsx.snap +0 -174
- package/src/components/slider/__snapshots__/Slider.test.tsx.snap +0 -122
- package/src/components/slideshow/__snapshots__/Slideshow.test.tsx.snap +0 -157
- package/src/components/table/__snapshots__/Table.test.tsx.snap +0 -263
- package/src/components/text/Text.stories.jsx +0 -75
- package/src/components/thumbnail/__snapshots__/Thumbnail.test.tsx.snap +0 -130
- package/src/components/user-block/__snapshots__/UserBlock.test.tsx.snap +0 -362
- package/src/stories/chromaticForceScreenSize.tsx +0 -7
- package/src/stories/knobs/buttonKnob.ts +0 -9
- package/src/stories/knobs/emphasisKnob.ts +0 -8
- package/src/stories/knobs/enumKnob.ts +0 -14
- package/src/stories/knobs/focusKnob.ts +0 -3
- package/src/stories/knobs/sizeKnob.ts +0 -5
- package/src/stories/knobs/thumbnailsKnob.ts +0 -9
- package/src/testing/utils/itShouldRenderStories.tsx +0 -103
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { mount, shallow } from 'enzyme';
|
|
3
|
-
import 'jest-enzyme';
|
|
4
|
-
import { commonTestsSuite, itShouldRenderStories } from '@lumx/react/testing/utils';
|
|
5
2
|
|
|
3
|
+
import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
|
+
import { queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
6
|
import { PostBlock, PostBlockProps } from './PostBlock';
|
|
7
|
-
import * as stories from '../../stories/generated/PostBlock/Demos.stories';
|
|
8
7
|
|
|
9
8
|
const CLASSNAME = PostBlock.className as string;
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const renderer: any = shallowRendering ? shallow : mount;
|
|
16
|
-
const wrapper: any = renderer(<PostBlock {...(props as any)} />);
|
|
17
|
-
return { props, wrapper };
|
|
10
|
+
const setup = (props: Partial<PostBlockProps> = {}) => {
|
|
11
|
+
render(<PostBlock {...(props as any)} />);
|
|
12
|
+
const postBlock = queryByClassName(document.body, CLASSNAME);
|
|
13
|
+
return { props, postBlock };
|
|
18
14
|
};
|
|
19
15
|
|
|
20
16
|
describe(`<${PostBlock.displayName}>`, () => {
|
|
21
|
-
// 1. Test render via snapshot.
|
|
22
|
-
describe('Snapshots and structure', () => {
|
|
23
|
-
itShouldRenderStories(stories, PostBlock);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
17
|
// Common tests suite.
|
|
27
|
-
|
|
18
|
+
commonTestsSuiteRTL(setup, {
|
|
19
|
+
baseClassName: CLASSNAME,
|
|
20
|
+
forwardClassName: 'postBlock',
|
|
21
|
+
forwardAttributes: 'postBlock',
|
|
22
|
+
});
|
|
28
23
|
});
|
|
@@ -1,18 +1,30 @@
|
|
|
1
|
-
import { ProgressCircular } from '@lumx/react';
|
|
2
|
-
import
|
|
1
|
+
import { ProgressCircular, ProgressCircularSize, Size } from '@lumx/react';
|
|
2
|
+
import { getSelectArgType } from '@lumx/react/stories/controls/selectArgType';
|
|
3
|
+
import { withCombinations } from '@lumx/react/stories/decorators/withCombinations';
|
|
4
|
+
|
|
5
|
+
const sizes: Array<ProgressCircularSize> = [Size.xxs, Size.xs, Size.s, Size.m];
|
|
3
6
|
|
|
4
7
|
export default {
|
|
5
8
|
title: 'LumX components/progress/ProgressCircular',
|
|
9
|
+
component: ProgressCircular,
|
|
10
|
+
args: ProgressCircular.defaultProps,
|
|
11
|
+
argTypes: {
|
|
12
|
+
size: getSelectArgType<ProgressCircularSize>(sizes),
|
|
13
|
+
},
|
|
6
14
|
};
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Default progress circular
|
|
18
|
+
*/
|
|
19
|
+
export const Default = {};
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
/**
|
|
22
|
+
* All sizes
|
|
23
|
+
*/
|
|
24
|
+
export const AllSizes = {
|
|
25
|
+
decorators: [
|
|
26
|
+
withCombinations({
|
|
27
|
+
combinations: { cols: { key: 'size', options: sizes } },
|
|
28
|
+
}),
|
|
29
|
+
],
|
|
30
|
+
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { ProgressLinear } from '@lumx/react';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
|
|
4
3
|
export default {
|
|
5
4
|
title: 'LumX components/progress/ProgressLinear',
|
|
5
|
+
component: ProgressLinear,
|
|
6
|
+
args: ProgressLinear.defaultProps,
|
|
6
7
|
};
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Default progress linear
|
|
11
|
+
*/
|
|
12
|
+
export const Default = {};
|
|
@@ -1,28 +1,39 @@
|
|
|
1
1
|
import { RadioButton } from '@lumx/react';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import React from 'react';
|
|
2
|
+
import { withValueOnChange } from '@lumx/react/stories/decorators/withValueOnChange';
|
|
3
|
+
import { loremIpsum } from '@lumx/react/stories/utils/lorem';
|
|
5
4
|
|
|
6
|
-
export default {
|
|
5
|
+
export default {
|
|
6
|
+
title: 'LumX components/radio-button/Radio button',
|
|
7
|
+
component: RadioButton,
|
|
8
|
+
args: {
|
|
9
|
+
...RadioButton.defaultProps,
|
|
10
|
+
name: 'radiobutton-html-name',
|
|
11
|
+
value: 'radiobutton-html-value',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
onChange: { action: true },
|
|
15
|
+
name: { control: false },
|
|
16
|
+
value: { control: false },
|
|
17
|
+
},
|
|
18
|
+
decorators: [
|
|
19
|
+
withValueOnChange({
|
|
20
|
+
valueProp: 'isChecked',
|
|
21
|
+
valueTransform: (value) => value === 'radiobutton-html-value',
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
};
|
|
7
25
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
name="test1"
|
|
13
|
-
theme={theme}
|
|
14
|
-
value="lorem"
|
|
15
|
-
onChange={noop}
|
|
16
|
-
/>
|
|
17
|
-
);
|
|
26
|
+
/**
|
|
27
|
+
* Default radio button
|
|
28
|
+
*/
|
|
29
|
+
export const Default = {};
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
31
|
+
/**
|
|
32
|
+
* With label and helper
|
|
33
|
+
*/
|
|
34
|
+
export const LabelAndHelper = {
|
|
35
|
+
args: {
|
|
36
|
+
label: 'Radio button label',
|
|
37
|
+
helper: loremIpsum('tiny'),
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { mdiBullhornOutline } from '@lumx/icons/';
|
|
2
2
|
import { List, ListItem, Select, Size, TextField } from '@lumx/react';
|
|
3
3
|
import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
|
|
4
|
-
import { text } from '@storybook/addon-knobs';
|
|
5
4
|
import noop from 'lodash/noop';
|
|
6
5
|
import range from 'lodash/range';
|
|
7
6
|
import React, { SyntheticEvent, useState } from 'react';
|
|
8
7
|
import { SelectVariant } from './constants';
|
|
9
8
|
|
|
10
|
-
export default {
|
|
9
|
+
export default {
|
|
10
|
+
title: 'LumX components/select/Select',
|
|
11
|
+
component: Select,
|
|
12
|
+
};
|
|
11
13
|
|
|
12
14
|
const CHOICES = ['First item', 'Second item', 'Third item'];
|
|
13
15
|
|
|
@@ -112,8 +114,8 @@ export const DisabledSelect = ({ theme }: any) => {
|
|
|
112
114
|
<Select
|
|
113
115
|
isOpen={false}
|
|
114
116
|
value=""
|
|
115
|
-
label=
|
|
116
|
-
placeholder=
|
|
117
|
+
label="My select"
|
|
118
|
+
placeholder="Placeholder"
|
|
117
119
|
theme={theme}
|
|
118
120
|
onInputClick={noop}
|
|
119
121
|
onDropdownClose={noop}
|
|
@@ -204,13 +206,7 @@ export const SelectWithAnotherField = ({ theme }: any) => {
|
|
|
204
206
|
|
|
205
207
|
return (
|
|
206
208
|
<>
|
|
207
|
-
<TextField
|
|
208
|
-
value={text('Value', 'myvalue')}
|
|
209
|
-
label={text('Label', 'I am the label')}
|
|
210
|
-
placeholder={text('Placeholder', 'ex: A value')}
|
|
211
|
-
theme={theme}
|
|
212
|
-
onChange={noop}
|
|
213
|
-
/>
|
|
209
|
+
<TextField value="myvalue" label="I am the label" placeholder="ex: A value" theme={theme} onChange={noop} />
|
|
214
210
|
<Select
|
|
215
211
|
style={{ width: '100%' }}
|
|
216
212
|
isOpen={isOpen}
|
|
@@ -255,8 +251,8 @@ export const SelectWithNoData = ({ theme }: any) => {
|
|
|
255
251
|
<Select
|
|
256
252
|
isOpen={isOpen}
|
|
257
253
|
value=""
|
|
258
|
-
label=
|
|
259
|
-
placeholder=
|
|
254
|
+
label="My select"
|
|
255
|
+
placeholder="Placeholder"
|
|
260
256
|
theme={theme}
|
|
261
257
|
onInputClick={toggleSelect}
|
|
262
258
|
onDropdownClose={closeSelect}
|
|
@@ -277,10 +273,10 @@ export const SelectWithHelper = ({ theme }: any) => {
|
|
|
277
273
|
<Select
|
|
278
274
|
isOpen={isOpen}
|
|
279
275
|
value=""
|
|
280
|
-
label=
|
|
281
|
-
placeholder=
|
|
276
|
+
label="Country"
|
|
277
|
+
placeholder="Your country"
|
|
282
278
|
theme={theme}
|
|
283
|
-
helper=
|
|
279
|
+
helper="This is used in analytics"
|
|
284
280
|
onInputClick={toggleSelect}
|
|
285
281
|
onDropdownClose={closeSelect}
|
|
286
282
|
>
|
|
@@ -302,14 +298,14 @@ export const SelectWithError = ({ theme }: any) => {
|
|
|
302
298
|
<Select
|
|
303
299
|
isOpen={isOpen}
|
|
304
300
|
value=""
|
|
305
|
-
label=
|
|
306
|
-
placeholder=
|
|
301
|
+
label="Country"
|
|
302
|
+
placeholder="Your country"
|
|
307
303
|
theme={theme}
|
|
308
|
-
helper=
|
|
304
|
+
helper="This is used in analytics"
|
|
309
305
|
onInputClick={toggleSelect}
|
|
310
306
|
onDropdownClose={closeSelect}
|
|
311
307
|
hasError
|
|
312
|
-
error=
|
|
308
|
+
error="Please select something :)"
|
|
313
309
|
>
|
|
314
310
|
<List theme={theme} isClickable>
|
|
315
311
|
{CHOICES.map((choice) => (
|
|
@@ -329,10 +325,10 @@ export const SelectSuccess = ({ theme }: any) => {
|
|
|
329
325
|
<Select
|
|
330
326
|
isOpen={isOpen}
|
|
331
327
|
value=""
|
|
332
|
-
label=
|
|
333
|
-
placeholder=
|
|
328
|
+
label="Country"
|
|
329
|
+
placeholder="Your country"
|
|
334
330
|
theme={theme}
|
|
335
|
-
helper=
|
|
331
|
+
helper="This is used in analytics"
|
|
336
332
|
onInputClick={toggleSelect}
|
|
337
333
|
onDropdownClose={closeSelect}
|
|
338
334
|
isValid
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
/* istanbul ignore file */
|
|
2
2
|
import { mdiTram } from '@lumx/icons/';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Chip,
|
|
5
|
+
Dialog,
|
|
6
|
+
List,
|
|
7
|
+
ListDivider,
|
|
8
|
+
ListItem,
|
|
9
|
+
ListSubheader,
|
|
10
|
+
SelectMultiple,
|
|
11
|
+
Size,
|
|
12
|
+
TextField,
|
|
13
|
+
Toolbar,
|
|
14
|
+
} from '@lumx/react';
|
|
4
15
|
import { useBooleanState } from '@lumx/react/hooks/useBooleanState';
|
|
5
16
|
import noop from 'lodash/noop';
|
|
6
|
-
import React, { MouseEventHandler, SyntheticEvent, useState } from 'react';
|
|
17
|
+
import React, { MouseEventHandler, SyntheticEvent, useRef, useState } from 'react';
|
|
7
18
|
import { SelectVariant } from './constants';
|
|
8
19
|
|
|
9
20
|
export default { title: 'LumX components/select/Select Multiple' };
|
|
@@ -225,3 +236,95 @@ export const ChipsCustomSelectMultiple = ({ theme }: any) => {
|
|
|
225
236
|
</SelectMultiple>
|
|
226
237
|
);
|
|
227
238
|
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Test select focus trap (focus is contained inside the dialog then inside the select dropdown)
|
|
242
|
+
*/
|
|
243
|
+
export const SelectWithinADialog = ({ theme }: any) => {
|
|
244
|
+
const searchFieldRef = useRef(null);
|
|
245
|
+
|
|
246
|
+
const [searchText, setSearchText] = useState<string>();
|
|
247
|
+
const [values, setValues] = useState<string[]>([]);
|
|
248
|
+
const [isOpen, closeSelect, , toggleSelect] = useBooleanState(false);
|
|
249
|
+
|
|
250
|
+
const clearSelected = (event: SyntheticEvent, value: string) => {
|
|
251
|
+
event.stopPropagation();
|
|
252
|
+
setValues(value ? values.filter((val) => val !== value) : []);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const selectItem = (item: string) => () => {
|
|
256
|
+
if (values.includes(item)) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
closeSelect();
|
|
261
|
+
setValues([...values, item]);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const filteredChoices =
|
|
265
|
+
searchText && searchText.length > 0 ? CHOICES.filter((choice) => choice.includes(searchText)) : CHOICES;
|
|
266
|
+
|
|
267
|
+
return (
|
|
268
|
+
<>
|
|
269
|
+
<Dialog isOpen>
|
|
270
|
+
<header>
|
|
271
|
+
<Toolbar label={<span className="lumx-typography-title">Dialog header</span>} />
|
|
272
|
+
</header>
|
|
273
|
+
<div className="lumx-spacing-padding-horizontal-huge lumx-spacing-padding-bottom-huge">
|
|
274
|
+
{/* Testing hidden input do not count in th focus trap*/}
|
|
275
|
+
<input hidden type="file" />
|
|
276
|
+
<input type="hidden" />
|
|
277
|
+
|
|
278
|
+
<div className="lumx-spacing-margin-bottom-huge">The select should capture the focus on open.</div>
|
|
279
|
+
|
|
280
|
+
<SelectMultiple
|
|
281
|
+
isOpen={isOpen}
|
|
282
|
+
value={values}
|
|
283
|
+
onClear={clearSelected}
|
|
284
|
+
clearButtonProps={{ label: 'Clear' }}
|
|
285
|
+
label={LABEL}
|
|
286
|
+
placeholder={PLACEHOLDER}
|
|
287
|
+
theme={theme}
|
|
288
|
+
onInputClick={toggleSelect}
|
|
289
|
+
onDropdownClose={closeSelect}
|
|
290
|
+
icon={mdiTram}
|
|
291
|
+
focusElement={searchFieldRef}
|
|
292
|
+
>
|
|
293
|
+
<List isClickable>
|
|
294
|
+
<>
|
|
295
|
+
<ListSubheader>
|
|
296
|
+
<TextField
|
|
297
|
+
clearButtonProps={{ label: 'Clear' }}
|
|
298
|
+
placeholder="Search"
|
|
299
|
+
role="searchbox"
|
|
300
|
+
inputRef={searchFieldRef}
|
|
301
|
+
onChange={setSearchText}
|
|
302
|
+
value={searchText}
|
|
303
|
+
/>
|
|
304
|
+
</ListSubheader>
|
|
305
|
+
<ListDivider role="presentation" />
|
|
306
|
+
</>
|
|
307
|
+
|
|
308
|
+
{filteredChoices.length > 0
|
|
309
|
+
? filteredChoices.map((choice) => (
|
|
310
|
+
<ListItem
|
|
311
|
+
isSelected={values.includes(choice)}
|
|
312
|
+
key={choice}
|
|
313
|
+
onItemSelected={selectItem(choice)}
|
|
314
|
+
size={Size.tiny}
|
|
315
|
+
>
|
|
316
|
+
{choice}
|
|
317
|
+
</ListItem>
|
|
318
|
+
))
|
|
319
|
+
: [
|
|
320
|
+
<ListItem key={0} size={Size.tiny}>
|
|
321
|
+
No data
|
|
322
|
+
</ListItem>,
|
|
323
|
+
]}
|
|
324
|
+
</List>
|
|
325
|
+
</SelectMultiple>
|
|
326
|
+
</div>
|
|
327
|
+
</Dialog>
|
|
328
|
+
</>
|
|
329
|
+
);
|
|
330
|
+
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import React, { Ref, useCallback, useMemo, useRef } from 'react';
|
|
2
|
-
|
|
3
1
|
import classNames from 'classnames';
|
|
2
|
+
import React, { Ref, useCallback, useMemo, useRef } from 'react';
|
|
4
3
|
import { uid } from 'uid';
|
|
5
4
|
|
|
5
|
+
import { Placement } from '@lumx/react';
|
|
6
6
|
import { Kind, Theme } from '@lumx/react/components';
|
|
7
7
|
import { Dropdown } from '@lumx/react/components/dropdown/Dropdown';
|
|
8
8
|
import { InputHelper } from '@lumx/react/components/input-helper/InputHelper';
|
|
9
|
+
import { useFocusTrap } from '@lumx/react/hooks/useFocusTrap';
|
|
10
|
+
import { useListenFocus } from '@lumx/react/hooks/useListenFocus';
|
|
9
11
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
10
12
|
import { mergeRefs } from '@lumx/react/utils/mergeRefs';
|
|
11
|
-
import { useListenFocus } from '@lumx/react/hooks/useListenFocus';
|
|
12
|
-
import { Placement } from '@lumx/react';
|
|
13
13
|
|
|
14
14
|
import { CoreSelectProps, SelectVariant } from './constants';
|
|
15
15
|
|
|
@@ -30,6 +30,7 @@ export const WithSelectContext = (
|
|
|
30
30
|
{
|
|
31
31
|
children,
|
|
32
32
|
className,
|
|
33
|
+
focusElement,
|
|
33
34
|
isMultiple,
|
|
34
35
|
closeOnClick = !isMultiple,
|
|
35
36
|
disabled,
|
|
@@ -58,6 +59,7 @@ export const WithSelectContext = (
|
|
|
58
59
|
const selectId = useMemo(() => id || `select-${uid()}`, [id]);
|
|
59
60
|
const anchorRef = useRef<HTMLElement>(null);
|
|
60
61
|
const selectRef = useRef<HTMLDivElement>(null);
|
|
62
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
61
63
|
const isFocus = useListenFocus(anchorRef);
|
|
62
64
|
|
|
63
65
|
const handleKeyboardNav = useCallback(
|
|
@@ -77,6 +79,9 @@ export const WithSelectContext = (
|
|
|
77
79
|
anchorRef?.current?.blur();
|
|
78
80
|
};
|
|
79
81
|
|
|
82
|
+
// Handle focus trap.
|
|
83
|
+
useFocusTrap(isOpen && dropdownRef.current, focusElement?.current);
|
|
84
|
+
|
|
80
85
|
return (
|
|
81
86
|
<div
|
|
82
87
|
ref={mergeRefs(ref, selectRef)}
|
|
@@ -125,6 +130,7 @@ export const WithSelectContext = (
|
|
|
125
130
|
placement={Placement.BOTTOM_START}
|
|
126
131
|
onClose={onClose}
|
|
127
132
|
onInfiniteScroll={onInfiniteScroll}
|
|
133
|
+
ref={dropdownRef}
|
|
128
134
|
>
|
|
129
135
|
{children}
|
|
130
136
|
</Dropdown>
|
|
@@ -1,25 +1,41 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Size, SkeletonCircle, SkeletonCircleProps } from '@lumx/react';
|
|
2
|
+
import { getSelectArgType } from '@lumx/react/stories/controls/selectArgType';
|
|
3
|
+
import { ALL_COLORS, colorArgType } from '@lumx/react/stories/controls/color';
|
|
4
|
+
import { withCombinations } from '@lumx/react/stories/decorators/withCombinations';
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
const sizes: SkeletonCircleProps['size'][] = [Size.xxs, Size.xs, Size.s, Size.m, Size.l, Size.xl, Size.xxl];
|
|
4
7
|
|
|
5
|
-
export default {
|
|
8
|
+
export default {
|
|
9
|
+
title: 'LumX components/skeleton/Skeleton Circle',
|
|
10
|
+
component: SkeletonCircle,
|
|
11
|
+
args: SkeletonCircle.defaultProps,
|
|
12
|
+
argTypes: {
|
|
13
|
+
size: getSelectArgType(sizes),
|
|
14
|
+
color: colorArgType,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
6
17
|
|
|
7
|
-
|
|
8
|
-
|
|
18
|
+
/**
|
|
19
|
+
* All sizes
|
|
20
|
+
*/
|
|
21
|
+
export const AllSize = {
|
|
22
|
+
argTypes: { size: { control: false } },
|
|
23
|
+
decorators: [
|
|
24
|
+
withCombinations({
|
|
25
|
+
combinations: { cols: { key: 'size', options: sizes } },
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
};
|
|
9
29
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
))}
|
|
23
|
-
</FlexBox>
|
|
24
|
-
</>
|
|
25
|
-
);
|
|
30
|
+
/**
|
|
31
|
+
* All colors
|
|
32
|
+
*/
|
|
33
|
+
export const AllColor = {
|
|
34
|
+
args: { size: Size.m },
|
|
35
|
+
argTypes: { color: { control: false } },
|
|
36
|
+
decorators: [
|
|
37
|
+
withCombinations({
|
|
38
|
+
combinations: { cols: { key: 'color', options: ALL_COLORS } },
|
|
39
|
+
}),
|
|
40
|
+
],
|
|
41
|
+
};
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { mount, shallow } from 'enzyme';
|
|
3
|
-
import 'jest-enzyme';
|
|
4
|
-
import { commonTestsSuite, itShouldRenderStories } from '@lumx/react/testing/utils';
|
|
5
2
|
|
|
3
|
+
import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
|
+
import { queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
6
|
import { SkeletonCircle, SkeletonCircleProps } from './SkeletonCircle';
|
|
7
|
-
import * as stories from './SkeletonCircle.stories';
|
|
8
7
|
|
|
9
8
|
const CLASSNAME = SkeletonCircle.className as string;
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const renderer: any = shallowRendering ? shallow : mount;
|
|
16
|
-
const wrapper: any = renderer(<SkeletonCircle {...(props as any)} />);
|
|
17
|
-
return { props, wrapper };
|
|
10
|
+
const setup = (props: Partial<SkeletonCircleProps> = {}) => {
|
|
11
|
+
render(<SkeletonCircle {...(props as any)} />);
|
|
12
|
+
const skeletonCircle = queryByClassName(document.body, CLASSNAME);
|
|
13
|
+
return { props, skeletonCircle };
|
|
18
14
|
};
|
|
19
15
|
|
|
20
16
|
describe(`<${SkeletonCircle.displayName}>`, () => {
|
|
21
|
-
// 1. Test render via snapshot.
|
|
22
|
-
describe('Snapshots and structure', () => {
|
|
23
|
-
itShouldRenderStories(stories, SkeletonCircle);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
17
|
// Common tests suite.
|
|
27
|
-
|
|
18
|
+
commonTestsSuiteRTL(setup, {
|
|
19
|
+
baseClassName: CLASSNAME,
|
|
20
|
+
forwardClassName: 'skeletonCircle',
|
|
21
|
+
forwardAttributes: 'skeletonCircle',
|
|
22
|
+
});
|
|
28
23
|
});
|