@charcoal-ui/react 3.0.0-beta.2 → 3.0.0-beta.4
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 +19 -1
- package/dist/_lib/compat.d.ts.map +1 -1
- package/dist/_lib/index.d.ts +7 -0
- package/dist/_lib/index.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 +2 -1
- package/dist/components/Checkbox/index.d.ts.map +1 -1
- package/dist/components/Checkbox/index.story.d.ts +2 -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 +9 -8
- package/dist/components/LoadingSpinner/index.d.ts.map +1 -1
- package/dist/components/LoadingSpinner/index.story.d.ts +1 -2
- package/dist/components/LoadingSpinner/index.story.d.ts.map +1 -1
- package/dist/components/Modal/ModalPlumbing.d.ts.map +1 -1
- package/dist/components/Modal/index.d.ts +18 -27
- package/dist/components/Modal/index.d.ts.map +1 -1
- package/dist/components/Modal/index.story.d.ts +12 -2
- 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 +18 -6
- package/dist/components/MultiSelect/index.d.ts.map +1 -1
- package/dist/components/MultiSelect/index.story.d.ts +21 -16
- package/dist/components/MultiSelect/index.story.d.ts.map +1 -1
- package/dist/components/Radio/index.d.ts +13 -6
- package/dist/components/Radio/index.d.ts.map +1 -1
- package/dist/components/Radio/index.story.d.ts +11 -8
- 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 +2 -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 +3 -2
- package/dist/components/Switch/index.d.ts.map +1 -1
- package/dist/components/Switch/index.story.d.ts +1 -2
- package/dist/components/Switch/index.story.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 +21 -0
- package/dist/components/TextArea/index.d.ts.map +1 -0
- package/dist/components/TextField/TextField.story.d.ts +28 -0
- package/dist/components/TextField/TextField.story.d.ts.map +1 -0
- package/dist/components/TextField/index.d.ts +8 -30
- package/dist/components/TextField/index.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 +1064 -771
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +1028 -750
- package/dist/index.esm.js.map +1 -1
- package/dist/styled.d.ts +13 -13
- package/package.json +7 -7
- package/src/_lib/compat.ts +20 -1
- package/src/_lib/index.ts +23 -0
- 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 +1 -1
- package/src/components/Checkbox/index.tsx +4 -2
- 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 +31 -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 +42 -0
- package/src/components/DropdownSelector/MenuList/MenuListContext.ts +17 -0
- package/src/components/DropdownSelector/MenuList/index.story.tsx +51 -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 +19 -60
- package/src/components/DropdownSelector/utils/findPreviewRecursive.tsx +39 -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 +8 -2
- package/src/components/LoadingSpinner/index.tsx +44 -29
- package/src/components/Modal/ModalPlumbing.tsx +0 -1
- package/src/components/Modal/index.story.tsx +0 -1
- package/src/components/Modal/index.tsx +19 -12
- package/src/components/MultiSelect/context.ts +2 -2
- package/src/components/MultiSelect/index.story.tsx +26 -27
- package/src/components/MultiSelect/index.test.tsx +5 -23
- package/src/components/MultiSelect/index.tsx +83 -78
- package/src/components/Radio/index.story.tsx +7 -9
- package/src/components/Radio/index.test.tsx +3 -4
- package/src/components/Radio/index.tsx +24 -23
- package/src/components/SegmentedControl/RadioGroupContext.tsx +2 -1
- package/src/components/SegmentedControl/index.story.tsx +0 -1
- package/src/components/SegmentedControl/index.tsx +16 -5
- package/src/components/Switch/index.story.tsx +1 -1
- package/src/components/Switch/index.tsx +38 -32
- package/src/components/TagItem/index.story.tsx +0 -1
- package/src/components/TagItem/index.tsx +1 -6
- package/src/components/TextArea/TextArea.story.tsx +61 -0
- package/src/components/TextArea/index.tsx +246 -0
- package/src/components/TextField/{index.story.tsx → TextField.story.tsx} +6 -29
- package/src/components/TextField/index.tsx +148 -378
- 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 -6
- package/dist/components/DropdownSelector/OptionItem.d.ts +0 -7
- package/dist/components/DropdownSelector/OptionItem.d.ts.map +0 -1
- package/dist/components/DropdownSelector/utils/focusIfHTMLLIElement.d.ts +0 -6
- package/dist/components/DropdownSelector/utils/focusIfHTMLLIElement.d.ts.map +0 -1
- package/dist/components/DropdownSelector/utils/handleFocusByKeyBoard.d.ts +0 -6
- package/dist/components/DropdownSelector/utils/handleFocusByKeyBoard.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
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { RefObject, useRef } from 'react'
|
|
2
|
+
import { ReactNode } from 'react'
|
|
3
|
+
import { DismissButton, Overlay, usePopover } from '@react-aria/overlays'
|
|
4
|
+
import styled from 'styled-components'
|
|
5
|
+
import { theme } from '../../../styled'
|
|
6
|
+
|
|
7
|
+
export type PopoverProps = {
|
|
8
|
+
isOpen: boolean
|
|
9
|
+
onClose: () => void
|
|
10
|
+
children: ReactNode
|
|
11
|
+
triggerRef: RefObject<Element>
|
|
12
|
+
popoverRef?: RefObject<HTMLDivElement>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const _empty = () => null
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 画面の全面に動的に開くことができるコンテナ要素
|
|
19
|
+
* 外の要素をクリックしたり、内部からフォーカスを移動した場合に自動的に閉じる
|
|
20
|
+
*
|
|
21
|
+
* triggerRefの付近に画面内に収まるように表示される
|
|
22
|
+
*/
|
|
23
|
+
export default function Popover(props: PopoverProps) {
|
|
24
|
+
const defaultPopoverRef = useRef<HTMLDivElement>(null)
|
|
25
|
+
const finalPopoverRef =
|
|
26
|
+
props.popoverRef === undefined ? defaultPopoverRef : props.popoverRef
|
|
27
|
+
const { popoverProps, underlayProps } = usePopover(
|
|
28
|
+
{
|
|
29
|
+
triggerRef: props.triggerRef,
|
|
30
|
+
popoverRef: finalPopoverRef,
|
|
31
|
+
containerPadding: 16,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
close: props.onClose,
|
|
35
|
+
isOpen: props.isOpen,
|
|
36
|
+
// never used
|
|
37
|
+
open: _empty,
|
|
38
|
+
setOpen: _empty,
|
|
39
|
+
toggle: _empty,
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if (!props.isOpen) return null
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Overlay portalContainer={document.body}>
|
|
47
|
+
<div {...underlayProps} style={{ position: 'fixed', inset: 0 }} />
|
|
48
|
+
<DropdownPopoverDiv {...popoverProps} ref={finalPopoverRef}>
|
|
49
|
+
<DismissButton onDismiss={() => props.onClose()} />
|
|
50
|
+
{props.children}
|
|
51
|
+
<DismissButton onDismiss={() => props.onClose()} />
|
|
52
|
+
</DropdownPopoverDiv>
|
|
53
|
+
</Overlay>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const DropdownPopoverDiv = styled.div`
|
|
58
|
+
margin: 4px 0;
|
|
59
|
+
list-style: none;
|
|
60
|
+
overflow: auto;
|
|
61
|
+
max-height: inherit;
|
|
62
|
+
|
|
63
|
+
${theme((o) => [
|
|
64
|
+
o.bg.background1,
|
|
65
|
+
o.border.default,
|
|
66
|
+
o.borderRadius(8),
|
|
67
|
+
o.padding.vertical(8),
|
|
68
|
+
])}
|
|
69
|
+
`
|
|
@@ -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,25 +56,22 @@ export default function DropdownSelector(props: DropdownSelectorProps) {
|
|
|
79
56
|
</DropdownButtonText>
|
|
80
57
|
<DropdownButtonIcon name="16/Menu" />
|
|
81
58
|
</DropdownButton>
|
|
82
|
-
{
|
|
59
|
+
{isOpen && (
|
|
83
60
|
<DropdownPopover
|
|
84
|
-
|
|
61
|
+
isOpen={isOpen}
|
|
62
|
+
onClose={() => setIsOpen(false)}
|
|
85
63
|
triggerRef={triggerRef}
|
|
86
64
|
value={props.value}
|
|
87
65
|
>
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
>
|
|
98
|
-
{props.children}
|
|
99
|
-
</DropdownSelectorContext.Provider>
|
|
100
|
-
</ListboxRoot>
|
|
66
|
+
<MenuList
|
|
67
|
+
value={props.value}
|
|
68
|
+
onChange={(v) => {
|
|
69
|
+
props.onChange(v)
|
|
70
|
+
setIsOpen(false)
|
|
71
|
+
}}
|
|
72
|
+
>
|
|
73
|
+
{props.children}
|
|
74
|
+
</MenuList>
|
|
101
75
|
</DropdownPopover>
|
|
102
76
|
)}
|
|
103
77
|
{props.assistiveText !== undefined && (
|
|
@@ -109,21 +83,6 @@ export default function DropdownSelector(props: DropdownSelectorProps) {
|
|
|
109
83
|
)
|
|
110
84
|
}
|
|
111
85
|
|
|
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
86
|
const DropdownSelectorRoot = styled.div`
|
|
128
87
|
display: inline-block;
|
|
129
88
|
width: 100%;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* DropdownSelectorの選択中の要素をレンダリングするため、
|
|
6
|
+
* 選択中のMenuItemを再帰的に探索しReactNodeを返す。
|
|
7
|
+
*
|
|
8
|
+
* @param children
|
|
9
|
+
* @param value
|
|
10
|
+
* @param values
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export function findPreviewRecursive(
|
|
14
|
+
children: ReactNode,
|
|
15
|
+
value: string
|
|
16
|
+
): ReactNode | undefined {
|
|
17
|
+
const childArray = React.Children.toArray(children)
|
|
18
|
+
for (let i = 0; i < childArray.length; i++) {
|
|
19
|
+
const child = childArray[i]
|
|
20
|
+
if (React.isValidElement(child)) {
|
|
21
|
+
if ('value' in child.props) {
|
|
22
|
+
const childValue = (child.props as { value: string }).value
|
|
23
|
+
if (childValue === value && 'children' in child.props) {
|
|
24
|
+
const children = (child.props as { children: ReactNode }).children
|
|
25
|
+
return children
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if ('children' in child.props) {
|
|
29
|
+
const children = findPreviewRecursive(
|
|
30
|
+
(child.props as { children: ReactNode }).children,
|
|
31
|
+
value
|
|
32
|
+
)
|
|
33
|
+
if (children !== undefined) {
|
|
34
|
+
return children
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -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
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
text,
|
|
6
6
|
withKnobs,
|
|
7
7
|
} from '@storybook/addon-knobs'
|
|
8
|
-
import
|
|
8
|
+
import { useRef } from 'react'
|
|
9
9
|
import LoadingSpinner, {
|
|
10
10
|
LoadingSpinnerIcon,
|
|
11
11
|
LoadingSpinnerIconHandler,
|
|
@@ -21,9 +21,15 @@ export function Basic() {
|
|
|
21
21
|
const size = number('size', 48)
|
|
22
22
|
const padding = number('padding', 16)
|
|
23
23
|
const transparent = boolean('transparent', false)
|
|
24
|
+
const className = text('className', 'basic')
|
|
24
25
|
|
|
25
26
|
return (
|
|
26
|
-
<LoadingSpinner
|
|
27
|
+
<LoadingSpinner
|
|
28
|
+
size={size}
|
|
29
|
+
padding={padding}
|
|
30
|
+
transparent={transparent}
|
|
31
|
+
className={className}
|
|
32
|
+
/>
|
|
27
33
|
)
|
|
28
34
|
}
|
|
29
35
|
|
|
@@ -1,19 +1,35 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forwardRef, useImperativeHandle, useRef, memo } from 'react'
|
|
2
2
|
import styled, { keyframes } from 'styled-components'
|
|
3
3
|
import { theme } from '../../styled'
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
size
|
|
7
|
-
padding
|
|
8
|
-
transparent
|
|
9
|
-
|
|
10
|
-
return (
|
|
11
|
-
<LoadingSpinnerRoot size={size} padding={padding} transparent={transparent}>
|
|
12
|
-
<LoadingSpinnerIcon />
|
|
13
|
-
</LoadingSpinnerRoot>
|
|
14
|
-
)
|
|
5
|
+
export type LoadingSpinnerProps = {
|
|
6
|
+
readonly size?: number
|
|
7
|
+
readonly padding?: number
|
|
8
|
+
readonly transparent?: boolean
|
|
9
|
+
readonly className?: string
|
|
15
10
|
}
|
|
16
11
|
|
|
12
|
+
const LoadingSpinner = forwardRef<HTMLDivElement, LoadingSpinnerProps>(
|
|
13
|
+
function LoadingSpinnerInner(
|
|
14
|
+
{ size = 48, padding = 16, transparent = false, className },
|
|
15
|
+
ref
|
|
16
|
+
) {
|
|
17
|
+
return (
|
|
18
|
+
<LoadingSpinnerRoot
|
|
19
|
+
size={size}
|
|
20
|
+
padding={padding}
|
|
21
|
+
transparent={transparent}
|
|
22
|
+
className={className}
|
|
23
|
+
ref={ref}
|
|
24
|
+
>
|
|
25
|
+
<LoadingSpinnerIcon />
|
|
26
|
+
</LoadingSpinnerRoot>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
export default memo(LoadingSpinner)
|
|
32
|
+
|
|
17
33
|
const LoadingSpinnerRoot = styled.div.attrs({ role: 'progressbar' })<{
|
|
18
34
|
size: number
|
|
19
35
|
padding: number
|
|
@@ -67,23 +83,22 @@ export interface LoadingSpinnerIconHandler {
|
|
|
67
83
|
restart(): void
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
export const LoadingSpinnerIcon =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
>(function LoadingSpinnerIcon({ once = false }, ref) {
|
|
74
|
-
const iconRef = useRef<HTMLDivElement>(null)
|
|
86
|
+
export const LoadingSpinnerIcon = forwardRef<LoadingSpinnerIconHandler, Props>(
|
|
87
|
+
function LoadingSpinnerIcon({ once = false }, ref) {
|
|
88
|
+
const iconRef = useRef<HTMLDivElement>(null)
|
|
75
89
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
useImperativeHandle(ref, () => ({
|
|
91
|
+
restart: () => {
|
|
92
|
+
if (!iconRef.current) {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
iconRef.current.dataset.resetAnimation = 'true'
|
|
96
|
+
// Force reflow hack!
|
|
97
|
+
void iconRef.current.offsetWidth
|
|
98
|
+
delete iconRef.current.dataset.resetAnimation
|
|
99
|
+
},
|
|
100
|
+
}))
|
|
87
101
|
|
|
88
|
-
|
|
89
|
-
}
|
|
102
|
+
return <Icon ref={iconRef} once={once} />
|
|
103
|
+
}
|
|
104
|
+
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useContext, forwardRef, memo } from 'react'
|
|
2
|
+
import * as React from 'react'
|
|
2
3
|
import {
|
|
3
4
|
AriaModalOverlayProps,
|
|
4
5
|
Overlay,
|
|
@@ -17,6 +18,7 @@ import { useMedia } from '@charcoal-ui/styled'
|
|
|
17
18
|
import { animated, useTransition, easings } from 'react-spring'
|
|
18
19
|
import Button, { ButtonProps } from '../Button'
|
|
19
20
|
import IconButton from '../IconButton'
|
|
21
|
+
import { useObjectRef } from '@react-aria/utils'
|
|
20
22
|
|
|
21
23
|
type BottomSheet = boolean | 'full'
|
|
22
24
|
type Size = 'S' | 'M' | 'L'
|
|
@@ -30,6 +32,7 @@ export type ModalProps = AriaModalOverlayProps &
|
|
|
30
32
|
bottomSheet?: BottomSheet
|
|
31
33
|
isOpen: boolean
|
|
32
34
|
onClose: () => void
|
|
35
|
+
className?: string
|
|
33
36
|
|
|
34
37
|
/**
|
|
35
38
|
* https://github.com/adobe/react-spectrum/issues/3787
|
|
@@ -55,31 +58,32 @@ const DEFAULT_Z_INDEX = 10
|
|
|
55
58
|
*
|
|
56
59
|
* <OverlayProvider>
|
|
57
60
|
* <App>
|
|
58
|
-
* <Modal isOpen={state.isOpen} onClose={() => state.close()} isDismissable>
|
|
61
|
+
* <Modal title="Title" isOpen={state.isOpen} onClose={() => state.close()} isDismissable>
|
|
59
62
|
* <ModalHeader />
|
|
60
|
-
* <ModalBody
|
|
61
|
-
*
|
|
63
|
+
* <ModalBody>
|
|
64
|
+
* ...
|
|
65
|
+
* <ModalButtons>...</ModalButtons>
|
|
66
|
+
* </ModalBody>
|
|
62
67
|
* </Modal>
|
|
63
68
|
* </App>
|
|
64
69
|
* </OverlayProvider>
|
|
65
70
|
* ```
|
|
66
71
|
*/
|
|
67
|
-
|
|
68
|
-
children,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
...props
|
|
72
|
-
}: ModalProps) {
|
|
72
|
+
const Modal = forwardRef<HTMLDivElement, ModalProps>(function ModalInner(
|
|
73
|
+
{ children, zIndex = DEFAULT_Z_INDEX, portalContainer, ...props },
|
|
74
|
+
external
|
|
75
|
+
) {
|
|
73
76
|
const {
|
|
74
77
|
title,
|
|
75
78
|
size = 'M',
|
|
76
79
|
bottomSheet = false,
|
|
77
80
|
isDismissable,
|
|
78
81
|
onClose,
|
|
82
|
+
className,
|
|
79
83
|
isOpen = false,
|
|
80
84
|
} = props
|
|
81
85
|
|
|
82
|
-
const ref =
|
|
86
|
+
const ref = useObjectRef<HTMLDivElement>(external)
|
|
83
87
|
const { overlayProps, underlayProps } = useOverlay(props, ref)
|
|
84
88
|
|
|
85
89
|
const { modalProps } = useModalOverlay(
|
|
@@ -145,6 +149,7 @@ export default function Modal({
|
|
|
145
149
|
style={transitionEnabled ? { transform } : {}}
|
|
146
150
|
size={size}
|
|
147
151
|
bottomSheet={bottomSheet}
|
|
152
|
+
className={className}
|
|
148
153
|
>
|
|
149
154
|
<ModalContext.Provider
|
|
150
155
|
value={{ titleProps, title, close: onClose, showDismiss }}
|
|
@@ -165,7 +170,9 @@ export default function Modal({
|
|
|
165
170
|
</Overlay>
|
|
166
171
|
)
|
|
167
172
|
)
|
|
168
|
-
}
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
export default memo(Modal)
|
|
169
176
|
|
|
170
177
|
const ModalContext = React.createContext<{
|
|
171
178
|
titleProps: React.HTMLAttributes<HTMLElement>
|
|
@@ -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 />` ?'
|