@charcoal-ui/react 3.0.0-beta.1 → 3.0.0-beta.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/dist/_lib/compat.d.ts +1 -1
- package/dist/_lib/compat.d.ts.map +1 -1
- package/dist/components/Button/index.d.ts +1 -2
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.story.d.ts +1 -2
- package/dist/components/Button/index.story.d.ts.map +1 -1
- package/dist/components/Button/index.test.d.ts +4 -0
- package/dist/components/Button/index.test.d.ts.map +1 -0
- package/dist/components/Checkbox/index.d.ts +1 -1
- package/dist/components/Checkbox/index.d.ts.map +1 -1
- package/dist/components/Checkbox/index.story.d.ts +1 -2
- package/dist/components/Checkbox/index.story.d.ts.map +1 -1
- package/dist/components/Clickable/index.d.ts +1 -1
- package/dist/components/Clickable/index.d.ts.map +1 -1
- package/dist/components/Clickable/index.story.d.ts +1 -2
- package/dist/components/Clickable/index.story.d.ts.map +1 -1
- package/dist/components/DropdownSelector/Divider.d.ts +3 -0
- package/dist/components/DropdownSelector/Divider.d.ts.map +1 -1
- package/dist/components/DropdownSelector/DropdownMenuItem.d.ts +7 -0
- package/dist/components/DropdownSelector/DropdownMenuItem.d.ts.map +1 -0
- package/dist/components/DropdownSelector/DropdownPopover.d.ts +8 -8
- package/dist/components/DropdownSelector/DropdownPopover.d.ts.map +1 -1
- package/dist/components/DropdownSelector/ListItem/index.d.ts +18 -0
- package/dist/components/DropdownSelector/ListItem/index.d.ts.map +1 -0
- package/dist/components/DropdownSelector/ListItem/index.story.d.ts +9 -0
- package/dist/components/DropdownSelector/ListItem/index.story.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuItem/index.d.ts +11 -0
- package/dist/components/DropdownSelector/MenuItem/index.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.d.ts +9 -0
- package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.d.ts +10 -0
- package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuItemGroup/index.d.ts +14 -0
- package/dist/components/DropdownSelector/MenuItemGroup/index.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuList/MenuListContext.d.ts +10 -0
- package/dist/components/DropdownSelector/MenuList/MenuListContext.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuList/index.d.ts +18 -0
- package/dist/components/DropdownSelector/MenuList/index.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuList/index.story.d.ts +11 -0
- package/dist/components/DropdownSelector/MenuList/index.story.d.ts.map +1 -0
- package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.d.ts +11 -0
- package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.d.ts.map +1 -0
- package/dist/components/DropdownSelector/Popover/index.d.ts +17 -0
- package/dist/components/DropdownSelector/Popover/index.d.ts.map +1 -0
- package/dist/components/DropdownSelector/Popover/index.story.d.ts +9 -0
- package/dist/components/DropdownSelector/Popover/index.story.d.ts.map +1 -0
- package/dist/components/DropdownSelector/index.d.ts +3 -10
- package/dist/components/DropdownSelector/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/index.story.d.ts +4 -4
- package/dist/components/DropdownSelector/index.story.d.ts.map +1 -1
- package/dist/components/DropdownSelector/utils/findPreviewRecursive.d.ts +12 -0
- package/dist/components/DropdownSelector/utils/findPreviewRecursive.d.ts.map +1 -0
- package/dist/components/FieldLabel/index.d.ts +1 -1
- package/dist/components/FieldLabel/index.d.ts.map +1 -1
- package/dist/components/Icon/index.d.ts +1 -1
- package/dist/components/Icon/index.d.ts.map +1 -1
- package/dist/components/Icon/index.story.d.ts +2 -3
- package/dist/components/Icon/index.story.d.ts.map +1 -1
- package/dist/components/IconButton/index.d.ts +1 -2
- package/dist/components/IconButton/index.d.ts.map +1 -1
- package/dist/components/IconButton/index.story.d.ts +1 -2
- package/dist/components/IconButton/index.story.d.ts.map +1 -1
- package/dist/components/LoadingSpinner/index.d.ts +1 -2
- package/dist/components/LoadingSpinner/index.d.ts.map +1 -1
- package/dist/components/Modal/ModalPlumbing.d.ts.map +1 -1
- package/dist/components/Modal/index.d.ts +6 -3
- package/dist/components/Modal/index.d.ts.map +1 -1
- package/dist/components/Modal/index.story.d.ts.map +1 -1
- package/dist/components/MultiSelect/context.d.ts +1 -1
- package/dist/components/MultiSelect/context.d.ts.map +1 -1
- package/dist/components/MultiSelect/index.d.ts +5 -6
- package/dist/components/MultiSelect/index.d.ts.map +1 -1
- package/dist/components/MultiSelect/index.story.d.ts +7 -14
- package/dist/components/MultiSelect/index.story.d.ts.map +1 -1
- package/dist/components/Radio/index.d.ts +1 -1
- package/dist/components/Radio/index.d.ts.map +1 -1
- package/dist/components/Radio/index.story.d.ts +1 -2
- package/dist/components/Radio/index.story.d.ts.map +1 -1
- package/dist/components/SegmentedControl/RadioGroupContext.d.ts +1 -1
- package/dist/components/SegmentedControl/RadioGroupContext.d.ts.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +1 -1
- package/dist/components/SegmentedControl/index.d.ts.map +1 -1
- package/dist/components/SegmentedControl/index.story.d.ts +1 -2
- package/dist/components/SegmentedControl/index.story.d.ts.map +1 -1
- package/dist/components/Switch/index.d.ts +1 -1
- package/dist/components/Switch/index.d.ts.map +1 -1
- package/dist/components/TagItem/index.d.ts +3 -3
- package/dist/components/TagItem/index.d.ts.map +1 -1
- package/dist/components/TagItem/index.story.d.ts +2 -3
- package/dist/components/TagItem/index.story.d.ts.map +1 -1
- package/dist/components/TextArea/TextArea.story.d.ts +28 -0
- package/dist/components/TextArea/TextArea.story.d.ts.map +1 -0
- package/dist/components/TextArea/index.d.ts +28 -0
- package/dist/components/TextArea/index.d.ts.map +1 -0
- package/dist/components/TextField/TextField.story.d.ts +29 -0
- package/dist/components/TextField/TextField.story.d.ts.map +1 -0
- package/dist/components/TextField/index.d.ts +2 -1
- package/dist/components/TextField/index.d.ts.map +1 -1
- package/dist/components/TextField/index.story.d.ts +4 -5
- package/dist/components/TextField/index.story.d.ts.map +1 -1
- package/dist/core/CharcoalProvider.d.ts +1 -1
- package/dist/core/CharcoalProvider.d.ts.map +1 -1
- package/dist/core/ComponentAbstraction.d.ts +1 -1
- package/dist/core/ComponentAbstraction.d.ts.map +1 -1
- package/dist/index.cjs.js +794 -518
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +739 -477
- package/dist/index.esm.js.map +1 -1
- package/dist/styled.d.ts +13 -13
- package/dist/types/CustomJSXElement.d.ts +3 -0
- package/dist/types/CustomJSXElement.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/_lib/compat.ts +1 -1
- package/src/components/Button/__snapshots__/index.test.tsx.snap +385 -0
- package/src/components/Button/index.story.tsx +1 -1
- package/src/components/Button/index.test.tsx +24 -0
- package/src/components/Button/index.tsx +2 -2
- package/src/components/Checkbox/index.story.tsx +0 -1
- package/src/components/Checkbox/index.tsx +2 -1
- package/src/components/Clickable/index.story.tsx +0 -1
- package/src/components/Clickable/index.tsx +1 -1
- package/src/components/DropdownSelector/Divider.tsx +3 -0
- package/src/components/DropdownSelector/DropdownMenuItem.tsx +40 -0
- package/src/components/DropdownSelector/DropdownPopover.tsx +21 -42
- package/src/components/DropdownSelector/ListItem/index.story.tsx +51 -0
- package/src/components/DropdownSelector/ListItem/index.tsx +58 -0
- package/src/components/DropdownSelector/MenuItem/index.tsx +32 -0
- package/src/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.tsx +43 -0
- package/src/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.tsx +55 -0
- package/src/components/DropdownSelector/MenuItemGroup/index.tsx +43 -0
- package/src/components/DropdownSelector/MenuList/MenuListContext.ts +17 -0
- package/src/components/DropdownSelector/MenuList/index.story.tsx +52 -0
- package/src/components/DropdownSelector/MenuList/index.tsx +51 -0
- package/src/components/DropdownSelector/MenuList/internals/getValuesRecursive.tsx +35 -0
- package/src/components/DropdownSelector/Popover/index.story.tsx +65 -0
- package/src/components/DropdownSelector/Popover/index.tsx +69 -0
- package/src/components/DropdownSelector/index.story.tsx +56 -21
- package/src/components/DropdownSelector/index.tsx +21 -64
- package/src/components/DropdownSelector/utils/findPreviewRecursive.tsx +38 -0
- package/src/components/FieldLabel/index.tsx +1 -1
- package/src/components/Icon/index.story.tsx +0 -1
- package/src/components/Icon/index.tsx +1 -1
- package/src/components/IconButton/index.story.tsx +0 -1
- package/src/components/IconButton/index.tsx +2 -2
- package/src/components/LoadingSpinner/index.story.tsx +1 -1
- package/src/components/LoadingSpinner/index.tsx +19 -19
- package/src/components/Modal/ModalPlumbing.tsx +0 -1
- package/src/components/Modal/index.story.tsx +0 -1
- package/src/components/Modal/index.tsx +81 -62
- package/src/components/MultiSelect/context.ts +2 -2
- package/src/components/MultiSelect/index.story.tsx +16 -29
- package/src/components/MultiSelect/index.test.tsx +5 -23
- package/src/components/MultiSelect/index.tsx +19 -24
- package/src/components/Radio/index.story.tsx +0 -1
- package/src/components/Radio/index.test.tsx +0 -1
- package/src/components/Radio/index.tsx +4 -1
- package/src/components/SegmentedControl/RadioGroupContext.tsx +2 -1
- package/src/components/SegmentedControl/index.story.tsx +2 -1
- package/src/components/SegmentedControl/index.tsx +11 -4
- package/src/components/Switch/index.story.tsx +1 -1
- package/src/components/Switch/index.tsx +2 -1
- package/src/components/TagItem/index.story.tsx +0 -1
- package/src/components/TagItem/index.tsx +1 -6
- package/src/components/TextField/index.story.tsx +0 -1
- package/src/components/TextField/index.tsx +3 -7
- package/src/components/a11y.test.tsx +0 -1
- package/src/core/CharcoalProvider.tsx +1 -1
- package/src/core/ComponentAbstraction.tsx +2 -1
- package/src/index.ts +8 -5
- package/dist/components/DropdownSelector/OptionLi.d.ts +0 -11
- package/dist/components/DropdownSelector/OptionLi.d.ts.map +0 -1
- package/src/components/DropdownSelector/OptionItem.tsx +0 -85
- package/src/components/DropdownSelector/utils/focusIfHTMLLIElement.tsx +0 -12
- package/src/components/DropdownSelector/utils/handleFocusByKeyBoard.tsx +0 -20
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from 'react'
|
|
2
2
|
import DropdownSelector, { DropdownSelectorProps } from '.'
|
|
3
3
|
import { Story } from '../../_lib/compat'
|
|
4
|
-
import {
|
|
4
|
+
import { Divider } from './Divider'
|
|
5
|
+
import MenuItemGroup from './MenuItemGroup'
|
|
6
|
+
import DropdownMenuItem from './DropdownMenuItem'
|
|
5
7
|
|
|
6
8
|
export default {
|
|
7
9
|
title: 'DropdownSelector',
|
|
8
10
|
component: DropdownSelector,
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
type Props = Omit<
|
|
12
|
-
DropdownSelectorProps,
|
|
13
|
-
'subLabel' | 'children' | 'onOpenChange'
|
|
14
|
-
>
|
|
15
|
-
|
|
16
13
|
const baseProps: DropdownSelectorProps = {
|
|
17
14
|
label: 'Label',
|
|
18
15
|
value: '',
|
|
@@ -20,9 +17,12 @@ const baseProps: DropdownSelectorProps = {
|
|
|
20
17
|
onChange: () => {
|
|
21
18
|
//
|
|
22
19
|
},
|
|
20
|
+
children: <DropdownMenuItem value="item" />,
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
export const Playground: Story<
|
|
23
|
+
export const Playground: Story<DropdownSelectorProps> = (
|
|
24
|
+
props: DropdownSelectorProps
|
|
25
|
+
) => {
|
|
26
26
|
const [selected, setSelected] = useState('50')
|
|
27
27
|
return (
|
|
28
28
|
<div style={{ width: 288 }}>
|
|
@@ -36,9 +36,9 @@ export const Playground: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
36
36
|
>
|
|
37
37
|
{[...(Array(100) as undefined[])].map((_, i) => {
|
|
38
38
|
return (
|
|
39
|
-
<
|
|
39
|
+
<DropdownMenuItem key={i} value={i.toString()}>
|
|
40
40
|
{i}
|
|
41
|
-
</
|
|
41
|
+
</DropdownMenuItem>
|
|
42
42
|
)
|
|
43
43
|
})}
|
|
44
44
|
</DropdownSelector>
|
|
@@ -48,7 +48,9 @@ export const Playground: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
48
48
|
|
|
49
49
|
Playground.args = { ...baseProps }
|
|
50
50
|
|
|
51
|
-
export const Basic: Story<
|
|
51
|
+
export const Basic: Story<DropdownSelectorProps> = (
|
|
52
|
+
props: DropdownSelectorProps
|
|
53
|
+
) => {
|
|
52
54
|
const [selected, setSelected] = useState('')
|
|
53
55
|
return (
|
|
54
56
|
<div style={{ width: 288 }}>
|
|
@@ -60,9 +62,9 @@ export const Basic: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
60
62
|
value={selected}
|
|
61
63
|
label="label"
|
|
62
64
|
>
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
<
|
|
65
|
+
<DropdownMenuItem value={'10'}>Apple</DropdownMenuItem>
|
|
66
|
+
<DropdownMenuItem value={'20'}>Banana</DropdownMenuItem>
|
|
67
|
+
<DropdownMenuItem value={'30'}>Orange</DropdownMenuItem>
|
|
66
68
|
</DropdownSelector>
|
|
67
69
|
</div>
|
|
68
70
|
)
|
|
@@ -70,7 +72,9 @@ export const Basic: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
70
72
|
|
|
71
73
|
Basic.args = { ...baseProps }
|
|
72
74
|
|
|
73
|
-
export const CustomChildren: Story<
|
|
75
|
+
export const CustomChildren: Story<DropdownSelectorProps> = (
|
|
76
|
+
props: DropdownSelectorProps
|
|
77
|
+
) => {
|
|
74
78
|
const [selected, setSelected] = useState('10')
|
|
75
79
|
return (
|
|
76
80
|
<div style={{ width: 288 }}>
|
|
@@ -82,7 +86,7 @@ export const CustomChildren: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
82
86
|
value={selected}
|
|
83
87
|
label="label"
|
|
84
88
|
>
|
|
85
|
-
<
|
|
89
|
+
<DropdownMenuItem value={'10'}>
|
|
86
90
|
<div
|
|
87
91
|
style={{
|
|
88
92
|
color: 'pink',
|
|
@@ -91,8 +95,8 @@ export const CustomChildren: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
91
95
|
>
|
|
92
96
|
Apple
|
|
93
97
|
</div>
|
|
94
|
-
</
|
|
95
|
-
<
|
|
98
|
+
</DropdownMenuItem>
|
|
99
|
+
<DropdownMenuItem value={'20'}>
|
|
96
100
|
<div
|
|
97
101
|
style={{
|
|
98
102
|
color: 'yellowgreen',
|
|
@@ -101,8 +105,8 @@ export const CustomChildren: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
101
105
|
>
|
|
102
106
|
Banana
|
|
103
107
|
</div>
|
|
104
|
-
</
|
|
105
|
-
<
|
|
108
|
+
</DropdownMenuItem>
|
|
109
|
+
<DropdownMenuItem value={'30'}>
|
|
106
110
|
<div
|
|
107
111
|
style={{
|
|
108
112
|
color: 'orange',
|
|
@@ -111,10 +115,41 @@ export const CustomChildren: Story<Props> = (props: DropdownSelectorProps) => {
|
|
|
111
115
|
>
|
|
112
116
|
Orange
|
|
113
117
|
</div>
|
|
114
|
-
</
|
|
118
|
+
</DropdownMenuItem>
|
|
115
119
|
</DropdownSelector>
|
|
116
120
|
</div>
|
|
117
121
|
)
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
CustomChildren.args = { ...baseProps }
|
|
125
|
+
|
|
126
|
+
export const SectionList: Story<DropdownSelectorProps> = (
|
|
127
|
+
props: DropdownSelectorProps
|
|
128
|
+
) => {
|
|
129
|
+
const [selected, setSelected] = useState('10')
|
|
130
|
+
return (
|
|
131
|
+
<div style={{ width: 288 }}>
|
|
132
|
+
<DropdownSelector
|
|
133
|
+
{...props}
|
|
134
|
+
onChange={(value) => {
|
|
135
|
+
setSelected(value)
|
|
136
|
+
}}
|
|
137
|
+
value={selected}
|
|
138
|
+
label="label"
|
|
139
|
+
>
|
|
140
|
+
<MenuItemGroup text="fruits">
|
|
141
|
+
<DropdownMenuItem value={'10'}>Apple</DropdownMenuItem>
|
|
142
|
+
<DropdownMenuItem value={'20'}>Banana</DropdownMenuItem>
|
|
143
|
+
<DropdownMenuItem value={'30'}>Orange</DropdownMenuItem>
|
|
144
|
+
</MenuItemGroup>
|
|
145
|
+
<Divider />
|
|
146
|
+
<MenuItemGroup text="vehicle">
|
|
147
|
+
<DropdownMenuItem value={'40'}>bicycle</DropdownMenuItem>
|
|
148
|
+
<DropdownMenuItem value={'50'}>car</DropdownMenuItem>
|
|
149
|
+
<DropdownMenuItem value={'60'}>train</DropdownMenuItem>
|
|
150
|
+
</MenuItemGroup>
|
|
151
|
+
</DropdownSelector>
|
|
152
|
+
</div>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
SectionList.args = { ...baseProps }
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactNode, useState, useRef } from 'react'
|
|
2
2
|
import styled from 'styled-components'
|
|
3
|
-
import { useOverlayTriggerState } from 'react-stately'
|
|
4
3
|
import { disabledSelector } from '@charcoal-ui/utils'
|
|
5
4
|
import Icon from '../Icon'
|
|
6
5
|
import FieldLabel from '../FieldLabel'
|
|
7
6
|
import { theme } from '../../styled'
|
|
8
7
|
import { DropdownPopover } from './DropdownPopover'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
value: '',
|
|
12
|
-
setValue: (_v: string) => {
|
|
13
|
-
// empty
|
|
14
|
-
},
|
|
15
|
-
})
|
|
8
|
+
import { findPreviewRecursive } from './utils/findPreviewRecursive'
|
|
9
|
+
import MenuList, { MenuListChildren } from './MenuList'
|
|
16
10
|
|
|
17
11
|
export type DropdownSelectorProps = {
|
|
18
12
|
label: string
|
|
@@ -25,33 +19,16 @@ export type DropdownSelectorProps = {
|
|
|
25
19
|
required?: boolean
|
|
26
20
|
requiredText?: string
|
|
27
21
|
subLabel?: ReactNode
|
|
28
|
-
children
|
|
22
|
+
children: MenuListChildren
|
|
29
23
|
onChange: (value: string) => void
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
export type DropdownSelectorOption = {
|
|
33
|
-
label: string
|
|
34
|
-
id: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
26
|
const defaultRequiredText = '*必須'
|
|
38
27
|
|
|
39
28
|
export default function DropdownSelector(props: DropdownSelectorProps) {
|
|
40
29
|
const triggerRef = useRef<HTMLButtonElement>(null)
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
let preview: ReactNode | undefined
|
|
44
|
-
const childArray = React.Children.toArray(props.children)
|
|
45
|
-
for (let i = 0; i < childArray.length; i++) {
|
|
46
|
-
const child = childArray[i]
|
|
47
|
-
if (React.isValidElement(child) && 'value' in child.props) {
|
|
48
|
-
const find = (child.props as { value: string }).value === props.value
|
|
49
|
-
if (find && 'children' in child.props) {
|
|
50
|
-
preview = (child.props as { children: ReactNode }).children
|
|
51
|
-
break
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
30
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
31
|
+
const preview = findPreviewRecursive(props.children, props.value)
|
|
55
32
|
|
|
56
33
|
return (
|
|
57
34
|
<DropdownSelectorRoot aria-disabled={props.disabled}>
|
|
@@ -68,7 +45,7 @@ export default function DropdownSelector(props: DropdownSelectorProps) {
|
|
|
68
45
|
disabled={props.disabled}
|
|
69
46
|
onClick={() => {
|
|
70
47
|
if (props.disabled === true) return
|
|
71
|
-
|
|
48
|
+
setIsOpen(true)
|
|
72
49
|
}}
|
|
73
50
|
ref={triggerRef}
|
|
74
51
|
>
|
|
@@ -79,27 +56,22 @@ export default function DropdownSelector(props: DropdownSelectorProps) {
|
|
|
79
56
|
</DropdownButtonText>
|
|
80
57
|
<DropdownButtonIcon name="16/Menu" />
|
|
81
58
|
</DropdownButton>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
59
|
+
<DropdownPopover
|
|
60
|
+
isOpen={isOpen}
|
|
61
|
+
onClose={() => setIsOpen(false)}
|
|
62
|
+
triggerRef={triggerRef}
|
|
63
|
+
value={props.value}
|
|
64
|
+
>
|
|
65
|
+
<MenuList
|
|
86
66
|
value={props.value}
|
|
67
|
+
onChange={(v) => {
|
|
68
|
+
props.onChange(v)
|
|
69
|
+
setIsOpen(false)
|
|
70
|
+
}}
|
|
87
71
|
>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
value: props.value,
|
|
92
|
-
setValue: (v) => {
|
|
93
|
-
props.onChange(v)
|
|
94
|
-
state.close()
|
|
95
|
-
},
|
|
96
|
-
}}
|
|
97
|
-
>
|
|
98
|
-
{props.children}
|
|
99
|
-
</DropdownSelectorContext.Provider>
|
|
100
|
-
</ListboxRoot>
|
|
101
|
-
</DropdownPopover>
|
|
102
|
-
)}
|
|
72
|
+
{props.children}
|
|
73
|
+
</MenuList>
|
|
74
|
+
</DropdownPopover>
|
|
103
75
|
{props.assistiveText !== undefined && (
|
|
104
76
|
<AssertiveText invalid={props.invalid}>
|
|
105
77
|
{props.assistiveText}
|
|
@@ -109,21 +81,6 @@ export default function DropdownSelector(props: DropdownSelectorProps) {
|
|
|
109
81
|
)
|
|
110
82
|
}
|
|
111
83
|
|
|
112
|
-
const ListboxRoot = styled.ul`
|
|
113
|
-
padding-left: 0;
|
|
114
|
-
margin: 0;
|
|
115
|
-
box-sizing: border-box;
|
|
116
|
-
list-style: none;
|
|
117
|
-
overflow: auto;
|
|
118
|
-
max-height: inherit;
|
|
119
|
-
|
|
120
|
-
${theme((o) => [
|
|
121
|
-
o.bg.background1,
|
|
122
|
-
o.border.default,
|
|
123
|
-
o.borderRadius(8),
|
|
124
|
-
o.padding.vertical(8),
|
|
125
|
-
])}
|
|
126
|
-
`
|
|
127
84
|
const DropdownSelectorRoot = styled.div`
|
|
128
85
|
display: inline-block;
|
|
129
86
|
width: 100%;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DropdownSelectorの選択中の要素をレンダリングするため、
|
|
5
|
+
* 選択中のMenuItemを再帰的に探索しReactNodeを返す。
|
|
6
|
+
*
|
|
7
|
+
* @param children
|
|
8
|
+
* @param value
|
|
9
|
+
* @param values
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export function findPreviewRecursive(
|
|
13
|
+
children: ReactNode,
|
|
14
|
+
value: string
|
|
15
|
+
): ReactNode | undefined {
|
|
16
|
+
const childArray = React.Children.toArray(children)
|
|
17
|
+
for (let i = 0; i < childArray.length; i++) {
|
|
18
|
+
const child = childArray[i]
|
|
19
|
+
if (React.isValidElement(child)) {
|
|
20
|
+
if ('value' in child.props) {
|
|
21
|
+
const childValue = (child.props as { value: string }).value
|
|
22
|
+
if (childValue === value && 'children' in child.props) {
|
|
23
|
+
const children = (child.props as { children: ReactNode }).children
|
|
24
|
+
return children
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if ('children' in child.props) {
|
|
28
|
+
const children = findPreviewRecursive(
|
|
29
|
+
(child.props as { children: ReactNode }).children,
|
|
30
|
+
value
|
|
31
|
+
)
|
|
32
|
+
if (children !== undefined) {
|
|
33
|
+
return children
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forwardRef } from 'react'
|
|
2
2
|
import styled from 'styled-components'
|
|
3
3
|
import { theme } from '../../styled'
|
|
4
4
|
import Clickable, { ClickableElement, ClickableProps } from '../Clickable'
|
|
@@ -15,7 +15,7 @@ interface StyledProps {
|
|
|
15
15
|
|
|
16
16
|
export type IconButtonProps = StyledProps & ClickableProps
|
|
17
17
|
|
|
18
|
-
const IconButton =
|
|
18
|
+
const IconButton = forwardRef<ClickableElement, IconButtonProps>(
|
|
19
19
|
function IconButtonInner(
|
|
20
20
|
{ variant = 'Default', size = 'M', icon, ...rest }: IconButtonProps,
|
|
21
21
|
ref
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forwardRef, useImperativeHandle, useRef } from 'react'
|
|
2
2
|
import styled, { keyframes } from 'styled-components'
|
|
3
3
|
import { theme } from '../../styled'
|
|
4
4
|
|
|
@@ -19,6 +19,7 @@ const LoadingSpinnerRoot = styled.div.attrs({ role: 'progressbar' })<{
|
|
|
19
19
|
padding: number
|
|
20
20
|
transparent: boolean
|
|
21
21
|
}>`
|
|
22
|
+
box-sizing: content-box;
|
|
22
23
|
margin: auto;
|
|
23
24
|
padding: ${(props) => props.padding}px;
|
|
24
25
|
border-radius: 8px;
|
|
@@ -66,23 +67,22 @@ export interface LoadingSpinnerIconHandler {
|
|
|
66
67
|
restart(): void
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
export const LoadingSpinnerIcon =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
>(function LoadingSpinnerIcon({ once = false }, ref) {
|
|
73
|
-
const iconRef = useRef<HTMLDivElement>(null)
|
|
70
|
+
export const LoadingSpinnerIcon = forwardRef<LoadingSpinnerIconHandler, Props>(
|
|
71
|
+
function LoadingSpinnerIcon({ once = false }, ref) {
|
|
72
|
+
const iconRef = useRef<HTMLDivElement>(null)
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
useImperativeHandle(ref, () => ({
|
|
75
|
+
restart: () => {
|
|
76
|
+
if (!iconRef.current) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
iconRef.current.dataset.resetAnimation = 'true'
|
|
80
|
+
// Force reflow hack!
|
|
81
|
+
void iconRef.current.offsetWidth
|
|
82
|
+
delete iconRef.current.dataset.resetAnimation
|
|
83
|
+
},
|
|
84
|
+
}))
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
}
|
|
86
|
+
return <Icon ref={iconRef} once={once} />
|
|
87
|
+
}
|
|
88
|
+
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useContext, useRef } from 'react'
|
|
2
|
+
import * as React from 'react'
|
|
2
3
|
import {
|
|
3
4
|
AriaModalOverlayProps,
|
|
4
5
|
Overlay,
|
|
@@ -18,13 +19,16 @@ import { animated, useTransition, easings } from 'react-spring'
|
|
|
18
19
|
import Button, { ButtonProps } from '../Button'
|
|
19
20
|
import IconButton from '../IconButton'
|
|
20
21
|
|
|
22
|
+
type BottomSheet = boolean | 'full'
|
|
23
|
+
type Size = 'S' | 'M' | 'L'
|
|
24
|
+
|
|
21
25
|
export type ModalProps = AriaModalOverlayProps &
|
|
22
26
|
AriaDialogProps & {
|
|
23
27
|
children: React.ReactNode
|
|
24
28
|
zIndex?: number
|
|
25
29
|
title: string
|
|
26
|
-
size?:
|
|
27
|
-
bottomSheet?:
|
|
30
|
+
size?: Size
|
|
31
|
+
bottomSheet?: BottomSheet
|
|
28
32
|
isOpen: boolean
|
|
29
33
|
onClose: () => void
|
|
30
34
|
|
|
@@ -133,28 +137,30 @@ export default function Modal({
|
|
|
133
137
|
style={transitionEnabled ? { backgroundColor } : {}}
|
|
134
138
|
>
|
|
135
139
|
<FocusScope contain restoreFocus autoFocus>
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
<ModalContext.Provider
|
|
146
|
-
value={{ titleProps, title, close: onClose, showDismiss }}
|
|
140
|
+
<DialogContainer bottomSheet={bottomSheet} size={size}>
|
|
141
|
+
<ModalDialog
|
|
142
|
+
ref={ref}
|
|
143
|
+
{...overlayProps}
|
|
144
|
+
{...modalProps}
|
|
145
|
+
{...dialogProps}
|
|
146
|
+
style={transitionEnabled ? { transform } : {}}
|
|
147
|
+
size={size}
|
|
148
|
+
bottomSheet={bottomSheet}
|
|
147
149
|
>
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
150
|
+
<ModalContext.Provider
|
|
151
|
+
value={{ titleProps, title, close: onClose, showDismiss }}
|
|
152
|
+
>
|
|
153
|
+
{children}
|
|
154
|
+
{isDismissable === true && (
|
|
155
|
+
<ModalCrossButton
|
|
156
|
+
size="S"
|
|
157
|
+
icon="24/Close"
|
|
158
|
+
onClick={onClose}
|
|
159
|
+
/>
|
|
160
|
+
)}
|
|
161
|
+
</ModalContext.Provider>
|
|
162
|
+
</ModalDialog>
|
|
163
|
+
</DialogContainer>
|
|
158
164
|
</FocusScope>
|
|
159
165
|
</ModalBackground>
|
|
160
166
|
</Overlay>
|
|
@@ -176,6 +182,8 @@ const ModalContext = React.createContext<{
|
|
|
176
182
|
|
|
177
183
|
const ModalBackground = animated(styled.div<{ zIndex: number }>`
|
|
178
184
|
z-index: ${({ zIndex }) => zIndex};
|
|
185
|
+
overflow: scroll;
|
|
186
|
+
display: flex;
|
|
179
187
|
position: fixed;
|
|
180
188
|
top: 0;
|
|
181
189
|
left: 0;
|
|
@@ -185,50 +193,61 @@ const ModalBackground = animated(styled.div<{ zIndex: number }>`
|
|
|
185
193
|
${theme((o) => [o.bg.surface4])}
|
|
186
194
|
`)
|
|
187
195
|
|
|
196
|
+
const DialogContainer = styled.div<{ bottomSheet: BottomSheet; size: Size }>`
|
|
197
|
+
position: relative;
|
|
198
|
+
margin: auto;
|
|
199
|
+
padding: 24px 0;
|
|
200
|
+
width: ${(p) => {
|
|
201
|
+
switch (p.size) {
|
|
202
|
+
case 'S': {
|
|
203
|
+
return columnSystem(3, COLUMN_UNIT, GUTTER_UNIT) + GUTTER_UNIT * 2
|
|
204
|
+
}
|
|
205
|
+
case 'M': {
|
|
206
|
+
return columnSystem(4, COLUMN_UNIT, GUTTER_UNIT) + GUTTER_UNIT * 2
|
|
207
|
+
}
|
|
208
|
+
case 'L': {
|
|
209
|
+
return columnSystem(6, COLUMN_UNIT, GUTTER_UNIT) + GUTTER_UNIT * 2
|
|
210
|
+
}
|
|
211
|
+
default: {
|
|
212
|
+
return unreachable(p.size)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}}px;
|
|
216
|
+
|
|
217
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
218
|
+
width: calc(100% - 48px);
|
|
219
|
+
${(p) =>
|
|
220
|
+
p.bottomSheet !== false &&
|
|
221
|
+
css`
|
|
222
|
+
margin: 0;
|
|
223
|
+
padding: 0;
|
|
224
|
+
bottom: 0;
|
|
225
|
+
position: absolute;
|
|
226
|
+
width: 100%;
|
|
227
|
+
${p.bottomSheet === 'full' ? 'height: 100%' : ''};
|
|
228
|
+
`}
|
|
229
|
+
}
|
|
230
|
+
`
|
|
231
|
+
|
|
188
232
|
const ModalDialog = animated(styled.div<{
|
|
189
|
-
size:
|
|
190
|
-
bottomSheet:
|
|
233
|
+
size: Size
|
|
234
|
+
bottomSheet: BottomSheet
|
|
191
235
|
}>`
|
|
192
|
-
position:
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
transform: translate(-50%, -50%);
|
|
196
|
-
width: ${(p) =>
|
|
197
|
-
p.size === 'S'
|
|
198
|
-
? columnSystem(3, COLUMN_UNIT, GUTTER_UNIT) + GUTTER_UNIT * 2
|
|
199
|
-
: p.size === 'M'
|
|
200
|
-
? columnSystem(4, COLUMN_UNIT, GUTTER_UNIT) + GUTTER_UNIT * 2
|
|
201
|
-
: // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
202
|
-
p.size === 'L'
|
|
203
|
-
? columnSystem(6, COLUMN_UNIT, GUTTER_UNIT) + GUTTER_UNIT * 2
|
|
204
|
-
: unreachable(p.size)}px;
|
|
236
|
+
position: relative;
|
|
237
|
+
margin: auto;
|
|
238
|
+
padding: 24px 0;
|
|
205
239
|
|
|
206
240
|
${theme((o) => [o.bg.background1, o.borderRadius(24)])}
|
|
207
|
-
|
|
208
241
|
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
209
242
|
${(p) =>
|
|
210
|
-
p.bottomSheet
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
height: 100%;
|
|
219
|
-
`
|
|
220
|
-
: p.bottomSheet
|
|
221
|
-
? css`
|
|
222
|
-
top: auto;
|
|
223
|
-
bottom: 0;
|
|
224
|
-
left: 0;
|
|
225
|
-
transform: none;
|
|
226
|
-
border-radius: 0;
|
|
227
|
-
width: 100%;
|
|
228
|
-
`
|
|
229
|
-
: css`
|
|
230
|
-
width: calc(100% - 48px);
|
|
231
|
-
`}
|
|
243
|
+
p.bottomSheet !== false &&
|
|
244
|
+
css`
|
|
245
|
+
border-radius: 0;
|
|
246
|
+
${p.bottomSheet === 'full' &&
|
|
247
|
+
css`
|
|
248
|
+
height: 100%;
|
|
249
|
+
`}
|
|
250
|
+
`}
|
|
232
251
|
}
|
|
233
252
|
`)
|
|
234
253
|
|
|
@@ -5,7 +5,7 @@ type MultiSelectGroupContext = {
|
|
|
5
5
|
selected: string[]
|
|
6
6
|
disabled: boolean
|
|
7
7
|
readonly: boolean
|
|
8
|
-
|
|
8
|
+
invalid: boolean
|
|
9
9
|
onChange: ({ value, selected }: { value: string; selected: boolean }) => void
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@ export const MultiSelectGroupContext = createContext<MultiSelectGroupContext>({
|
|
|
14
14
|
selected: [],
|
|
15
15
|
disabled: false,
|
|
16
16
|
readonly: false,
|
|
17
|
-
|
|
17
|
+
invalid: false,
|
|
18
18
|
onChange() {
|
|
19
19
|
throw new Error(
|
|
20
20
|
'Cannot find `onChange()` handler. Perhaps you forgot to wrap it with `<MultiSelectGroup />` ?'
|