@charcoal-ui/react 2.0.0-alpha.9 → 2.0.0-rc.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 (83) hide show
  1. package/README.md +16 -0
  2. package/dist/components/Checkbox/index.d.ts +21 -0
  3. package/dist/components/Checkbox/index.d.ts.map +1 -0
  4. package/dist/components/Checkbox/index.story.d.ts +16 -0
  5. package/dist/components/Checkbox/index.story.d.ts.map +1 -0
  6. package/dist/components/DropdownSelector/Listbox.d.ts +10 -0
  7. package/dist/components/DropdownSelector/Listbox.d.ts.map +1 -0
  8. package/dist/components/DropdownSelector/Popover.d.ts +10 -0
  9. package/dist/components/DropdownSelector/Popover.d.ts.map +1 -0
  10. package/dist/components/DropdownSelector/index.d.ts +32 -0
  11. package/dist/components/DropdownSelector/index.d.ts.map +1 -0
  12. package/dist/components/DropdownSelector/index.story.d.ts +22 -0
  13. package/dist/components/DropdownSelector/index.story.d.ts.map +1 -0
  14. package/dist/components/Icon/index.story.d.ts +1 -1
  15. package/dist/components/LoadingSpinner/index.d.ts +15 -0
  16. package/dist/components/LoadingSpinner/index.d.ts.map +1 -0
  17. package/dist/components/LoadingSpinner/index.story.d.ts +10 -0
  18. package/dist/components/LoadingSpinner/index.story.d.ts.map +1 -0
  19. package/dist/components/Modal/ModalPlumbing.d.ts +5 -0
  20. package/dist/components/Modal/ModalPlumbing.d.ts.map +1 -0
  21. package/dist/components/Modal/index.d.ts +16 -0
  22. package/dist/components/Modal/index.d.ts.map +1 -0
  23. package/dist/components/Modal/index.story.d.ts +33 -0
  24. package/dist/components/Modal/index.story.d.ts.map +1 -0
  25. package/dist/components/{Select → MultiSelect}/context.d.ts +2 -2
  26. package/dist/components/MultiSelect/context.d.ts.map +1 -0
  27. package/dist/components/MultiSelect/index.d.ts +24 -0
  28. package/dist/components/MultiSelect/index.d.ts.map +1 -0
  29. package/dist/components/{Select → MultiSelect}/index.story.d.ts +2 -2
  30. package/dist/components/MultiSelect/index.story.d.ts.map +1 -0
  31. package/dist/components/{Select → MultiSelect}/index.test.d.ts +0 -0
  32. package/dist/components/MultiSelect/index.test.d.ts.map +1 -0
  33. package/dist/components/SegmentedControl/RadioGroupContext.d.ts +9 -0
  34. package/dist/components/SegmentedControl/RadioGroupContext.d.ts.map +1 -0
  35. package/dist/components/SegmentedControl/index.d.ts +20 -0
  36. package/dist/components/SegmentedControl/index.d.ts.map +1 -0
  37. package/dist/components/SegmentedControl/index.story.d.ts +11 -0
  38. package/dist/components/SegmentedControl/index.story.d.ts.map +1 -0
  39. package/dist/components/TextField/index.d.ts +6 -3
  40. package/dist/components/TextField/index.d.ts.map +1 -1
  41. package/dist/components/TextField/index.story.d.ts +1 -0
  42. package/dist/components/TextField/index.story.d.ts.map +1 -1
  43. package/dist/core/SSRProvider.d.ts +2 -0
  44. package/dist/core/SSRProvider.d.ts.map +1 -0
  45. package/dist/index.cjs +22686 -1
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.ts +8 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.modern.js +21612 -45
  50. package/dist/index.modern.js.map +1 -1
  51. package/dist/index.module.js +22641 -1
  52. package/dist/index.module.js.map +1 -1
  53. package/package.json +15 -8
  54. package/src/components/Checkbox/index.story.tsx +64 -0
  55. package/src/components/Checkbox/index.tsx +122 -0
  56. package/src/components/DropdownSelector/Listbox.tsx +127 -0
  57. package/src/components/DropdownSelector/Popover.tsx +46 -0
  58. package/src/components/DropdownSelector/index.story.tsx +134 -0
  59. package/src/components/DropdownSelector/index.tsx +214 -0
  60. package/src/components/FieldLabel/index.tsx +1 -1
  61. package/src/components/LoadingSpinner/index.story.tsx +52 -0
  62. package/src/components/LoadingSpinner/index.tsx +87 -0
  63. package/src/components/Modal/ModalPlumbing.tsx +47 -0
  64. package/src/components/Modal/index.story.tsx +195 -0
  65. package/src/components/Modal/index.tsx +226 -0
  66. package/src/components/{Select → MultiSelect}/context.ts +3 -3
  67. package/src/components/{Select → MultiSelect}/index.story.tsx +16 -12
  68. package/src/components/{Select → MultiSelect}/index.test.tsx +13 -13
  69. package/src/components/{Select → MultiSelect}/index.tsx +24 -21
  70. package/src/components/SegmentedControl/RadioGroupContext.tsx +22 -0
  71. package/src/components/SegmentedControl/index.story.tsx +36 -0
  72. package/src/components/SegmentedControl/index.tsx +157 -0
  73. package/src/components/TextField/index.story.tsx +31 -16
  74. package/src/components/TextField/index.tsx +53 -34
  75. package/src/components/a11y.test.tsx +11 -0
  76. package/src/core/SSRProvider.tsx +1 -0
  77. package/src/index.ts +22 -5
  78. package/src/styled.ts +1 -1
  79. package/dist/components/Select/context.d.ts.map +0 -1
  80. package/dist/components/Select/index.d.ts +0 -24
  81. package/dist/components/Select/index.d.ts.map +0 -1
  82. package/dist/components/Select/index.story.d.ts.map +0 -1
  83. package/dist/components/Select/index.test.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@charcoal-ui/react",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-rc.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -13,7 +13,7 @@
13
13
  "types": "./dist/index.d.ts",
14
14
  "sideEffects": false,
15
15
  "scripts": {
16
- "build": "microbundle -f modern,esm,cjs --tsconfig tsconfig.build.json --jsx React.createElement --jsxFragment React.Fragment",
16
+ "build": "microbundle --compress=false -f modern,esm,cjs --tsconfig tsconfig.build.json --jsx React.createElement --jsxFragment React.Fragment",
17
17
  "typecheck": "tsc --noEmit --project tsconfig.build.json",
18
18
  "clean": "rimraf dist"
19
19
  },
@@ -48,16 +48,23 @@
48
48
  "typescript": "^4.5.5"
49
49
  },
50
50
  "dependencies": {
51
- "@charcoal-ui/icons": "^1.1.0-alpha.3",
52
- "@charcoal-ui/styled": "^1.0.1-alpha.5",
53
- "@charcoal-ui/theme": "^2.0.0-alpha.3",
54
- "@charcoal-ui/utils": "^1.0.1-alpha.0",
51
+ "@charcoal-ui/icons": "^2.0.0-rc.0",
52
+ "@charcoal-ui/styled": "^2.0.0-rc.0",
53
+ "@charcoal-ui/theme": "^2.0.0-rc.0",
54
+ "@charcoal-ui/utils": "^2.0.0-rc.0",
55
+ "@react-aria/button": "^3.6.2",
55
56
  "@react-aria/checkbox": "^3.2.3",
57
+ "@react-aria/dialog": "^3.2.1",
58
+ "@react-aria/focus": "^3.6.1",
59
+ "@react-aria/overlays": "^3.9.1",
60
+ "@react-aria/radio": "^3.4.0",
61
+ "@react-aria/select": "^3.8.2",
62
+ "@react-aria/ssr": "^3.3.0",
56
63
  "@react-aria/switch": "^3.1.3",
57
64
  "@react-aria/textfield": "^3.5.0",
58
65
  "@react-aria/visually-hidden": "^3.2.3",
59
66
  "polished": "^4.1.4",
60
- "react-stately": "^3.11.0",
67
+ "react-stately": "^3.19.0",
61
68
  "warning": "^4.0.3"
62
69
  },
63
70
  "peerDependencies": {
@@ -76,5 +83,5 @@
76
83
  "url": "https://github.com/pixiv/charcoal.git",
77
84
  "directory": "packages/react"
78
85
  },
79
- "gitHead": "f1fcafd39b0d4c2aa970cd4fdbbc3a12147c94a4"
86
+ "gitHead": "01429610d6100445690d4ca8ce4b1d0fd57c00b2"
80
87
  }
@@ -0,0 +1,64 @@
1
+ import { action } from '@storybook/addon-actions'
2
+ import React from 'react'
3
+ import Checkbox from '.'
4
+ import { Story } from '../../_lib/compat'
5
+
6
+ export default {
7
+ title: 'Checkbox',
8
+ component: Checkbox,
9
+ }
10
+
11
+ type Props = {
12
+ checked: boolean
13
+ defaultChecked: boolean
14
+ disabled: boolean
15
+ readonly: boolean
16
+ }
17
+
18
+ export const Labelled: Story<Props> = (props) => {
19
+ return (
20
+ <div>
21
+ <Checkbox
22
+ {...props}
23
+ name="labelled"
24
+ label="label"
25
+ onBlur={action('blur')}
26
+ onClick={action('click')}
27
+ onChange={action('change')}
28
+ onFocus={action('focus')}
29
+ >
30
+ 同意する
31
+ </Checkbox>
32
+ </div>
33
+ )
34
+ }
35
+
36
+ Labelled.args = {
37
+ checked: false,
38
+ defaultChecked: false,
39
+ disabled: false,
40
+ readonly: false,
41
+ }
42
+
43
+ export const Unlabelled: Story<Props> = (props) => {
44
+ return (
45
+ <div>
46
+ <Checkbox
47
+ {...props}
48
+ name="unlabelled"
49
+ label="label"
50
+ onBlur={action('blur')}
51
+ onClick={action('click')}
52
+ onChange={action('change')}
53
+ onFocus={action('focus')}
54
+ />
55
+ </div>
56
+ )
57
+ }
58
+
59
+ Unlabelled.args = {
60
+ checked: false,
61
+ defaultChecked: false,
62
+ disabled: false,
63
+ readonly: false,
64
+ }
@@ -0,0 +1,122 @@
1
+ import React, { forwardRef, memo, useMemo } from 'react'
2
+ import styled, { css } from 'styled-components'
3
+ import { useCheckbox } from '@react-aria/checkbox'
4
+ import { useObjectRef } from '@react-aria/utils'
5
+ import { useToggleState } from 'react-stately'
6
+ import { disabledSelector, px } from '@charcoal-ui/utils'
7
+ import { theme } from '../../styled'
8
+
9
+ import type { AriaCheckboxProps } from '@react-types/checkbox'
10
+ import Icon from '../Icon'
11
+
12
+ type CheckboxLabelProps =
13
+ | {
14
+ children: React.ReactNode
15
+ }
16
+ | {
17
+ label: string
18
+ }
19
+
20
+ export type CheckboxProps = CheckboxLabelProps & {
21
+ readonly id?: string
22
+ readonly name?: string
23
+
24
+ readonly checked?: boolean
25
+ readonly defaultChecked?: boolean
26
+ readonly disabled?: boolean
27
+ readonly readonly?: boolean
28
+
29
+ readonly onClick?: () => void
30
+ readonly onChange?: (isSelected: boolean) => void
31
+ readonly onBlur?: () => void
32
+ readonly onFocus?: () => void
33
+ }
34
+
35
+ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
36
+ function CheckboxInner(props, ref) {
37
+ const ariaCheckboxProps = useMemo<AriaCheckboxProps>(
38
+ () => ({
39
+ ...props,
40
+ isSelected: props.checked,
41
+ defaultSelected: props.defaultChecked,
42
+ // children がいない場合は aria-label をつけないといけない
43
+ 'aria-label': 'children' in props ? undefined : props.label,
44
+ isDisabled: props.disabled,
45
+ }),
46
+ [props]
47
+ )
48
+ const state = useToggleState(ariaCheckboxProps)
49
+ const objectRef = useObjectRef(ref)
50
+
51
+ const { inputProps } = useCheckbox(ariaCheckboxProps, state, objectRef)
52
+ const isDisabled = (props.disabled ?? false) || (props.readonly ?? false)
53
+
54
+ return (
55
+ <InputRoot aria-disabled={isDisabled}>
56
+ <CheckboxInput type="checkbox" {...inputProps} />
57
+ <CheckboxInputOverlay aria-hidden={true} checked={inputProps.checked}>
58
+ <Icon name="24/Check" unsafeNonGuidelineScale={2 / 3} />
59
+ </CheckboxInputOverlay>
60
+
61
+ {'children' in props && <InputLabel>{props.children}</InputLabel>}
62
+ </InputRoot>
63
+ )
64
+ }
65
+ )
66
+
67
+ export default memo(Checkbox)
68
+
69
+ const hiddenCss = css`
70
+ visibility: hidden;
71
+ `
72
+
73
+ const InputRoot = styled.label`
74
+ position: relative;
75
+ display: flex;
76
+ align-items: center;
77
+ cursor: pointer;
78
+ ${disabledSelector} {
79
+ cursor: default;
80
+ }
81
+
82
+ gap: ${({ theme }) => px(theme.spacing[4])};
83
+ ${theme((o) => [o.disabled])}
84
+ `
85
+
86
+ const CheckboxInput = styled.input`
87
+ &[type='checkbox'] {
88
+ appearance: none;
89
+ display: block;
90
+ cursor: pointer;
91
+ margin: 0;
92
+ width: 20px;
93
+ height: 20px;
94
+
95
+ &:checked {
96
+ ${theme((o) => o.bg.brand.hover.press)}
97
+ }
98
+ &:not(:checked) {
99
+ border-width: 2px;
100
+ border-style: solid;
101
+ border-color: ${({ theme }) => theme.color.text4};
102
+ }
103
+ ${theme((o) => [o.outline.default.focus, o.borderRadius(4)])}
104
+ }
105
+ `
106
+ const CheckboxInputOverlay = styled.div<{ checked?: boolean }>`
107
+ position: absolute;
108
+ top: -2px;
109
+ left: -2px;
110
+ box-sizing: border-box;
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+
115
+ ${theme((o) => [o.width.px(24), o.height.px(24), o.font.text5])}
116
+
117
+ ${({ checked }) => checked !== true && hiddenCss};
118
+ `
119
+
120
+ const InputLabel = styled.div`
121
+ ${theme((o) => [o.typography(14)])}
122
+ `
@@ -0,0 +1,127 @@
1
+ import React, { memo, useRef, Fragment, useMemo } from 'react'
2
+ import styled, { css } from 'styled-components'
3
+ import { ListProps, ListState } from 'react-stately'
4
+ import { useListBox, useOption } from '@react-aria/listbox'
5
+ import { mergeProps } from '@react-aria/utils'
6
+ import { useFocusRing } from '@react-aria/focus'
7
+ import { px } from '@charcoal-ui/utils'
8
+ import Icon from '../Icon'
9
+ import { theme } from '../../styled'
10
+
11
+ import type { Node } from '@react-types/shared'
12
+
13
+ type ListMode = 'default' | 'separator'
14
+ export type ListboxProps<T> = Omit<ListProps<T>, 'children'> & {
15
+ state: ListState<T>
16
+ mode?: ListMode
17
+ }
18
+
19
+ const Listbox = <T,>({
20
+ state,
21
+ mode = 'default',
22
+ ...props
23
+ }: ListboxProps<T>) => {
24
+ const ref = useRef<HTMLUListElement>(null)
25
+
26
+ const { listBoxProps } = useListBox(props, state, ref)
27
+ const collection = useMemo(
28
+ () =>
29
+ [...state.collection].map((node, index, self) => ({
30
+ node,
31
+ first: index === 0,
32
+ last: index === self.length - 1,
33
+ })),
34
+ [state.collection]
35
+ )
36
+
37
+ return (
38
+ <ListboxRoot ref={ref} {...listBoxProps}>
39
+ {collection.map(({ node, last }) => (
40
+ <Fragment key={node.key}>
41
+ <Option item={node} state={state} mode={mode} />
42
+ {!last && mode === 'separator' && <Divider />}
43
+ </Fragment>
44
+ ))}
45
+ </ListboxRoot>
46
+ )
47
+ }
48
+ export default memo(Listbox)
49
+
50
+ const ListboxRoot = styled.ul`
51
+ padding-left: 0;
52
+ margin: 0;
53
+ box-sizing: border-box;
54
+ list-style: none;
55
+
56
+ ${theme((o) => [
57
+ o.bg.background1,
58
+ o.border.default,
59
+ o.borderRadius(8),
60
+ o.outline.default.focus,
61
+ ])}
62
+ `
63
+
64
+ const Divider = styled.div.attrs({ role: 'separator' })`
65
+ display: flex;
66
+ ${theme((o) => [o.padding.horizontal(8)])}
67
+
68
+ &:before {
69
+ content: '';
70
+ display: block;
71
+ width: 100%;
72
+ height: 1px;
73
+ background: #00000014;
74
+ }
75
+ `
76
+
77
+ type OptionProps<T> = {
78
+ item: Node<T>
79
+ state: ListState<T>
80
+ mode?: ListMode
81
+ }
82
+
83
+ const Option = <T,>({ item, state, mode }: OptionProps<T>) => {
84
+ const ref = useRef<HTMLLIElement>(null)
85
+
86
+ const { optionProps, isSelected } = useOption(item, state, ref)
87
+ const { focusProps } = useFocusRing()
88
+
89
+ return (
90
+ <OptionRoot {...mergeProps(optionProps, focusProps)} ref={ref} mode={mode}>
91
+ <OptionCheckIcon name="16/Check" isSelected={isSelected} />
92
+ <OptionText>{item.rendered}</OptionText>
93
+ </OptionRoot>
94
+ )
95
+ }
96
+
97
+ const OptionRoot = styled.li<{ mode?: ListMode }>`
98
+ display: flex;
99
+ align-items: center;
100
+ gap: ${({ theme }) => px(theme.spacing[4])};
101
+ height: 40px;
102
+ cursor: pointer;
103
+ outline: none;
104
+
105
+ ${({ mode }) =>
106
+ theme((o) => [
107
+ o.padding.horizontal(8),
108
+ mode === 'separator' && o.padding.vertical(4),
109
+ ])}
110
+
111
+ &:focus {
112
+ ${theme((o) => [o.bg.surface3])}
113
+ }
114
+ `
115
+ const OptionCheckIcon = styled(Icon)<{ isSelected: boolean }>`
116
+ visibility: hidden;
117
+
118
+ ${({ isSelected }) =>
119
+ isSelected &&
120
+ css`
121
+ visibility: visible;
122
+ `}
123
+ `
124
+ const OptionText = styled.span`
125
+ display: block;
126
+ ${theme((o) => [o.typography(14)])}
127
+ `
@@ -0,0 +1,46 @@
1
+ import { FocusScope } from '@react-aria/focus'
2
+ import { DismissButton, useOverlay } from '@react-aria/overlays'
3
+ import React, {
4
+ FC,
5
+ useRef,
6
+ useMemo,
7
+ PropsWithChildren,
8
+ memo,
9
+ CSSProperties,
10
+ } from 'react'
11
+ import { mergeProps } from '@react-aria/utils'
12
+
13
+ type Props = PropsWithChildren<{
14
+ open?: boolean
15
+ onClose?: () => void
16
+ style?: CSSProperties
17
+ className?: string
18
+ }>
19
+
20
+ const Popover: FC<Props> = ({ open, onClose, children, ...props }) => {
21
+ const ref = useRef<HTMLDivElement>(null)
22
+
23
+ const { overlayProps } = useOverlay(
24
+ useMemo(
25
+ () => ({
26
+ isOpen: open,
27
+ onClose,
28
+ shouldCloseOnBlur: true,
29
+ isDismissable: true,
30
+ }),
31
+ [onClose, open]
32
+ ),
33
+ ref
34
+ )
35
+
36
+ return (
37
+ <FocusScope restoreFocus>
38
+ <div {...mergeProps(overlayProps, props)} ref={ref}>
39
+ {children}
40
+ <DismissButton onDismiss={onClose} />
41
+ </div>
42
+ </FocusScope>
43
+ )
44
+ }
45
+
46
+ export default memo(Popover)
@@ -0,0 +1,134 @@
1
+ import { action } from '@storybook/addon-actions'
2
+ import React from 'react'
3
+ import DropdownSelector, {
4
+ DropdownSelectorItem,
5
+ DropdownSelectorProps,
6
+ } from '.'
7
+ import { Story } from '../../_lib/compat'
8
+ import Clickable from '../Clickable'
9
+
10
+ export default {
11
+ title: 'DropdownSelector',
12
+ component: DropdownSelector,
13
+ }
14
+
15
+ type Props = Omit<
16
+ DropdownSelectorProps,
17
+ 'subLabel' | 'children' | 'onOpenChange'
18
+ >
19
+ export const Default: Story<Props> = (props) => {
20
+ return (
21
+ <DropdownSelector
22
+ {...props}
23
+ placeholder={props.placeholder ?? 'Drop Down menu'}
24
+ onChange={action('change')}
25
+ onOpenChange={action('open')}
26
+ >
27
+ <DropdownSelectorItem key="k:1">選択肢1</DropdownSelectorItem>
28
+ <DropdownSelectorItem key="k:2">選択肢2</DropdownSelectorItem>
29
+ <DropdownSelectorItem key="k:3">選択肢3</DropdownSelectorItem>
30
+ </DropdownSelector>
31
+ )
32
+ }
33
+ Default.args = {
34
+ label: 'Label',
35
+ requiredText: '*必須',
36
+ required: false,
37
+ showLabel: false,
38
+ invalid: false,
39
+ disabled: false,
40
+ }
41
+
42
+ type HasLabelProps = {
43
+ disabled?: boolean
44
+ }
45
+ export const HasLabel: Story<HasLabelProps> = ({ disabled }) => {
46
+ const defaultProps: Omit<DropdownSelectorProps, 'children'> = {
47
+ required: true,
48
+ showLabel: true,
49
+ label: 'Label',
50
+ requiredText: '*必須',
51
+ subLabel: <Clickable onClick={action('label-click')}>Text Link</Clickable>,
52
+ assertiveText: 'Hint',
53
+ }
54
+ return (
55
+ <DropdownSelector
56
+ {...defaultProps}
57
+ disabled={disabled}
58
+ placeholder={'Drop Down menu'}
59
+ onChange={action('change')}
60
+ onOpenChange={action('open')}
61
+ >
62
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
63
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
64
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
65
+ </DropdownSelector>
66
+ )
67
+ }
68
+
69
+ HasLabel.args = {
70
+ disabled: false,
71
+ }
72
+
73
+ type WithSeparatorProps = {
74
+ mode: 'default' | 'separator'
75
+ }
76
+ export const WithSeparator: Story<WithSeparatorProps> = ({
77
+ mode,
78
+ ...props
79
+ }) => {
80
+ const defaultProps: Omit<DropdownSelectorProps, 'children'> = {
81
+ required: true,
82
+ showLabel: true,
83
+ label: 'Label',
84
+ requiredText: '*必須',
85
+ subLabel: <Clickable onClick={action('label-click')}>Text Link</Clickable>,
86
+ assertiveText: 'Hint',
87
+ }
88
+ return (
89
+ <DropdownSelector
90
+ {...defaultProps}
91
+ mode={mode}
92
+ placeholder={'Drop Down menu'}
93
+ onChange={action('change')}
94
+ onOpenChange={action('open')}
95
+ {...props}
96
+ >
97
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
98
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
99
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
100
+ </DropdownSelector>
101
+ )
102
+ }
103
+
104
+ WithSeparator.args = {
105
+ mode: 'separator',
106
+ }
107
+
108
+ type InvalidProps = {
109
+ disabled?: boolean
110
+ }
111
+ export const Invalid: Story<InvalidProps> = ({ disabled }) => {
112
+ const props: Omit<DropdownSelectorProps, 'children'> = {
113
+ label: '',
114
+ assertiveText: 'error message',
115
+ invalid: true,
116
+ }
117
+ return (
118
+ <DropdownSelector
119
+ {...props}
120
+ disabled={disabled}
121
+ placeholder={'Drop Down menu'}
122
+ onChange={action('change')}
123
+ onOpenChange={action('open')}
124
+ >
125
+ <DropdownSelectorItem key="1">選択肢1</DropdownSelectorItem>
126
+ <DropdownSelectorItem key="2">選択肢2</DropdownSelectorItem>
127
+ <DropdownSelectorItem key="3">選択肢3</DropdownSelectorItem>
128
+ </DropdownSelector>
129
+ )
130
+ }
131
+
132
+ Invalid.args = {
133
+ disabled: false,
134
+ }