@charcoal-ui/react 3.7.0 → 3.9.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/dist/components/Button/StyledButton.d.ts +1 -0
- package/dist/components/Button/StyledButton.d.ts.map +1 -1
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.story.d.ts +16 -32
- package/dist/components/Button/index.story.d.ts.map +1 -1
- package/dist/components/Checkbox/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/ListItem/index.story.d.ts +7 -7
- package/dist/components/DropdownSelector/ListItem/index.story.d.ts.map +1 -1
- package/dist/components/DropdownSelector/MenuList/index.story.d.ts +6 -9
- package/dist/components/DropdownSelector/MenuList/index.story.d.ts.map +1 -1
- package/dist/components/DropdownSelector/Popover/index.story.d.ts +3 -7
- package/dist/components/DropdownSelector/Popover/index.story.d.ts.map +1 -1
- package/dist/components/DropdownSelector/index.d.ts.map +1 -1
- package/dist/components/DropdownSelector/index.story.d.ts +9 -12
- package/dist/components/DropdownSelector/index.story.d.ts.map +1 -1
- package/dist/components/Icon/index.story.d.ts +4 -26
- package/dist/components/Icon/index.story.d.ts.map +1 -1
- package/dist/components/IconButton/index.d.ts +1 -0
- package/dist/components/IconButton/index.d.ts.map +1 -1
- package/dist/components/IconButton/index.story.d.ts +6 -25
- package/dist/components/IconButton/index.story.d.ts.map +1 -1
- package/dist/components/LoadingSpinner/LoadingSpinnerIcon.story.d.ts +8 -0
- package/dist/components/LoadingSpinner/LoadingSpinnerIcon.story.d.ts.map +1 -0
- package/dist/components/LoadingSpinner/index.d.ts +2 -2
- package/dist/components/LoadingSpinner/index.d.ts.map +1 -1
- package/dist/components/LoadingSpinner/index.story.d.ts +4 -7
- package/dist/components/LoadingSpinner/index.story.d.ts.map +1 -1
- package/dist/components/Modal/index.d.ts.map +1 -1
- package/dist/components/Modal/index.story.d.ts +16 -41
- package/dist/components/Modal/index.story.d.ts.map +1 -1
- package/dist/components/Modal/useCustomModalOverlay.d.ts +12 -0
- package/dist/components/Modal/useCustomModalOverlay.d.ts.map +1 -0
- package/dist/components/MultiSelect/index.d.ts.map +1 -1
- package/dist/components/Radio/index.d.ts +0 -2
- package/dist/components/Radio/index.d.ts.map +1 -1
- package/dist/components/Radio/index.story.d.ts +12 -23
- package/dist/components/Radio/index.story.d.ts.map +1 -1
- package/dist/components/SegmentedControl/index.story.d.ts +5 -8
- package/dist/components/SegmentedControl/index.story.d.ts.map +1 -1
- package/dist/components/Switch/index.d.ts.map +1 -1
- package/dist/components/Switch/index.story.d.ts +7 -12
- package/dist/components/Switch/index.story.d.ts.map +1 -1
- package/dist/components/TagItem/index.d.ts.map +1 -1
- package/dist/components/TagItem/index.story.d.ts +14 -24
- package/dist/components/TagItem/index.story.d.ts.map +1 -1
- package/dist/components/TextArea/TextArea.story.d.ts +7 -25
- package/dist/components/TextArea/TextArea.story.d.ts.map +1 -1
- package/dist/components/TextArea/index.d.ts.map +1 -1
- package/dist/components/TextField/TextField.story.d.ts +14 -20
- package/dist/components/TextField/TextField.story.d.ts.map +1 -1
- package/dist/components/TextField/index.d.ts.map +1 -1
- package/dist/index.cjs.js +1006 -2240
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1001 -2241
- package/dist/index.esm.js.map +1 -1
- package/dist/styled.d.ts +4 -4
- package/package.json +7 -6
- package/src/components/Button/StyledButton.tsx +19 -14
- package/src/components/Button/__snapshots__/index.story.storyshot +314 -118
- package/src/components/Button/index.story.tsx +141 -138
- package/src/components/Button/index.tsx +3 -0
- package/src/components/Checkbox/__snapshots__/index.story.storyshot +55 -42
- package/src/components/Checkbox/index.tsx +15 -17
- package/src/components/Clickable/__snapshots__/index.story.storyshot +2 -2
- package/src/components/DropdownSelector/ListItem/__snapshots__/index.story.storyshot +42 -37
- package/src/components/DropdownSelector/ListItem/index.story.tsx +8 -4
- package/src/components/DropdownSelector/MenuList/__snapshots__/index.story.storyshot +38 -38
- package/src/components/DropdownSelector/MenuList/index.story.tsx +33 -27
- package/src/components/DropdownSelector/Popover/__snapshots__/index.story.storyshot +11 -5
- package/src/components/DropdownSelector/Popover/index.story.tsx +6 -6
- package/src/components/DropdownSelector/__snapshots__/index.story.storyshot +148 -47
- package/src/components/DropdownSelector/index.story.tsx +207 -204
- package/src/components/DropdownSelector/index.tsx +17 -10
- package/src/components/Icon/__snapshots__/index.story.storyshot +1 -1
- package/src/components/Icon/index.story.tsx +8 -12
- package/src/components/IconButton/__snapshots__/index.story.storyshot +135 -13
- package/src/components/IconButton/index.story.tsx +30 -23
- package/src/components/IconButton/index.tsx +35 -20
- package/src/components/LoadingSpinner/LoadingSpinnerIcon.story.tsx +12 -0
- package/src/components/LoadingSpinner/__snapshots__/LoadingSpinnerIcon.story.storyshot +28 -0
- package/src/components/LoadingSpinner/__snapshots__/index.story.storyshot +1 -35
- package/src/components/LoadingSpinner/index.story.tsx +11 -54
- package/src/components/LoadingSpinner/index.tsx +1 -1
- package/src/components/Modal/__snapshots__/index.story.storyshot +224 -171
- package/src/components/Modal/index.story.tsx +139 -133
- package/src/components/Modal/index.tsx +15 -20
- package/src/components/Modal/useCustomModalOverlay.tsx +42 -0
- package/src/components/MultiSelect/__snapshots__/index.story.storyshot +56 -4
- package/src/components/MultiSelect/index.tsx +3 -0
- package/src/components/Radio/__snapshots__/index.story.storyshot +1001 -121
- package/src/components/Radio/index.story.tsx +128 -63
- package/src/components/Radio/index.tsx +15 -17
- package/src/components/SegmentedControl/__snapshots__/index.story.storyshot +2 -2
- package/src/components/SegmentedControl/index.story.tsx +24 -29
- package/src/components/Switch/__snapshots__/index.story.storyshot +184 -26
- package/src/components/Switch/index.story.tsx +72 -48
- package/src/components/Switch/index.tsx +2 -7
- package/src/components/TagItem/__snapshots__/index.story.storyshot +72 -33
- package/src/components/TagItem/index.story.tsx +154 -159
- package/src/components/TagItem/index.tsx +2 -6
- package/src/components/TextArea/TextArea.story.tsx +29 -32
- package/src/components/TextArea/__snapshots__/TextArea.story.storyshot +127 -73
- package/src/components/TextArea/index.tsx +22 -14
- package/src/components/TextField/TextField.story.tsx +85 -64
- package/src/components/TextField/__snapshots__/TextField.story.storyshot +479 -167
- package/src/components/TextField/index.tsx +22 -21
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Story } from '../../_lib/compat'
|
|
2
1
|
import Modal, { ModalDismissButton, ModalProps } from '.'
|
|
3
2
|
import { OverlayProvider } from '@react-aria/overlays'
|
|
4
3
|
import { useOverlayTriggerState } from 'react-stately'
|
|
@@ -14,6 +13,7 @@ import { theme } from '../../styled'
|
|
|
14
13
|
import TextField from '../TextField'
|
|
15
14
|
import DropdownSelector from '../DropdownSelector'
|
|
16
15
|
import DropdownMenuItem from '../DropdownSelector/DropdownMenuItem'
|
|
16
|
+
import { Meta, StoryObj } from '@storybook/react'
|
|
17
17
|
|
|
18
18
|
export default {
|
|
19
19
|
title: 'Modal',
|
|
@@ -27,6 +27,7 @@ export default {
|
|
|
27
27
|
control: {
|
|
28
28
|
type: 'inline-radio',
|
|
29
29
|
},
|
|
30
|
+
defaultValue: 'M',
|
|
30
31
|
},
|
|
31
32
|
bottomSheet: {
|
|
32
33
|
options: ['full', 'true', 'false'],
|
|
@@ -34,26 +35,26 @@ export default {
|
|
|
34
35
|
control: {
|
|
35
36
|
type: 'inline-radio',
|
|
36
37
|
},
|
|
38
|
+
defaultValue: false,
|
|
37
39
|
},
|
|
38
40
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
41
|
+
render: function Render(args) {
|
|
42
|
+
const state = useOverlayTriggerState({})
|
|
43
|
+
return (
|
|
44
|
+
// Application must be wrapped in an OverlayProvider so that it can be
|
|
45
|
+
// hidden from screen readers when a modal opens.
|
|
46
|
+
<OverlayProvider>
|
|
47
|
+
<Button onClick={() => state.open()}>Open Modal</Button>
|
|
48
|
+
<M
|
|
49
|
+
{...args}
|
|
50
|
+
isDismissable
|
|
51
|
+
isOpen={state.isOpen}
|
|
52
|
+
onClose={() => state.close()}
|
|
53
|
+
/>
|
|
54
|
+
</OverlayProvider>
|
|
55
|
+
)
|
|
56
|
+
},
|
|
57
|
+
} as Meta<typeof Modal>
|
|
57
58
|
|
|
58
59
|
const M = (props: ModalProps) => {
|
|
59
60
|
return (
|
|
@@ -114,127 +115,132 @@ const StyledModalText = styled(ModalAlign)`
|
|
|
114
115
|
${theme((o) => [o.font.text2, o.typography(14)])}
|
|
115
116
|
`
|
|
116
117
|
|
|
117
|
-
export const Default:
|
|
118
|
+
export const Default: StoryObj<typeof Modal> = {}
|
|
118
119
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
export const FullBottomSheet: StoryObj<typeof Modal> = {
|
|
121
|
+
args: {
|
|
122
|
+
bottomSheet: 'full',
|
|
123
|
+
},
|
|
124
|
+
render: function Render(args) {
|
|
125
|
+
const state = useOverlayTriggerState({})
|
|
126
|
+
return (
|
|
127
|
+
// Application must be wrapped in an OverlayProvider so that it can be
|
|
128
|
+
// hidden from screen readers when a modal opens.
|
|
129
|
+
<OverlayProvider>
|
|
130
|
+
<Button onClick={() => state.open()}>Open Modal</Button>
|
|
126
131
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
</
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
</
|
|
165
|
-
</
|
|
166
|
-
</
|
|
167
|
-
</
|
|
168
|
-
|
|
169
|
-
|
|
132
|
+
<Modal
|
|
133
|
+
{...args}
|
|
134
|
+
isDismissable
|
|
135
|
+
isOpen={state.isOpen}
|
|
136
|
+
onClose={() => state.close()}
|
|
137
|
+
>
|
|
138
|
+
<ModalHeader />
|
|
139
|
+
<ModalBody>
|
|
140
|
+
<ModalVStack>
|
|
141
|
+
<StyledModalText>
|
|
142
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod
|
|
143
|
+
placeat tenetur, necessitatibus laudantium cumque exercitationem
|
|
144
|
+
provident. Quaerat iure enim, eveniet dolores earum odio quo
|
|
145
|
+
possimus fugiat aspernatur, numquam, commodi repellat.
|
|
146
|
+
</StyledModalText>
|
|
147
|
+
<ModalAlign>
|
|
148
|
+
<TextField
|
|
149
|
+
showLabel
|
|
150
|
+
label="Name"
|
|
151
|
+
placeholder="Nagisa"
|
|
152
|
+
></TextField>
|
|
153
|
+
</ModalAlign>
|
|
154
|
+
<ModalAlign>
|
|
155
|
+
<TextField
|
|
156
|
+
showLabel
|
|
157
|
+
label="Country"
|
|
158
|
+
placeholder="Tokyo"
|
|
159
|
+
></TextField>
|
|
160
|
+
</ModalAlign>
|
|
161
|
+
</ModalVStack>
|
|
162
|
+
<ModalButtons>
|
|
163
|
+
<Button variant="Primary" onClick={() => state.close()} fullWidth>
|
|
164
|
+
Apply
|
|
165
|
+
</Button>
|
|
166
|
+
<Button onClick={() => state.close()} fullWidth>
|
|
167
|
+
Cancel
|
|
168
|
+
</Button>
|
|
169
|
+
</ModalButtons>
|
|
170
|
+
</ModalBody>
|
|
171
|
+
</Modal>
|
|
172
|
+
</OverlayProvider>
|
|
173
|
+
)
|
|
174
|
+
},
|
|
170
175
|
}
|
|
171
176
|
|
|
172
|
-
export const
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
<Button onClick={() => state.open()}>Open Modal</Button>
|
|
177
|
+
export const BottomSheet: StoryObj<typeof Modal> = {
|
|
178
|
+
render: function Render(args) {
|
|
179
|
+
const state = useOverlayTriggerState({})
|
|
180
|
+
return (
|
|
181
|
+
// Application must be wrapped in an OverlayProvider so that it can be
|
|
182
|
+
// hidden from screen readers when a modal opens.
|
|
183
|
+
<OverlayProvider>
|
|
184
|
+
<Button onClick={() => state.open()}>Open Modal</Button>
|
|
181
185
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
186
|
+
<Modal
|
|
187
|
+
{...args}
|
|
188
|
+
isOpen={state.isOpen}
|
|
189
|
+
onClose={() => state.close()}
|
|
190
|
+
bottomSheet
|
|
191
|
+
isDismissable
|
|
192
|
+
>
|
|
193
|
+
<ModalHeader />
|
|
194
|
+
<ModalBody>
|
|
195
|
+
<ModalVStack>
|
|
196
|
+
<StyledModalText>
|
|
197
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod
|
|
198
|
+
placeat tenetur, necessitatibus laudantium cumque exercitationem
|
|
199
|
+
provident. Quaerat iure enim, eveniet dolores earum odio quo
|
|
200
|
+
possimus fugiat aspernatur, numquam, commodi repellat.
|
|
201
|
+
</StyledModalText>
|
|
202
|
+
</ModalVStack>
|
|
203
|
+
<ModalButtons>
|
|
204
|
+
<Button variant="Danger" onClick={() => state.close()} fullWidth>
|
|
205
|
+
削除する
|
|
206
|
+
</Button>
|
|
207
|
+
<ModalDismissButton>キャンセル</ModalDismissButton>
|
|
208
|
+
</ModalButtons>
|
|
209
|
+
</ModalBody>
|
|
210
|
+
</Modal>
|
|
211
|
+
</OverlayProvider>
|
|
212
|
+
)
|
|
213
|
+
},
|
|
209
214
|
}
|
|
210
215
|
|
|
211
|
-
export const
|
|
216
|
+
export const NotDismmissableStory: StoryObj<typeof Modal> = {
|
|
217
|
+
render: function Render(args) {
|
|
218
|
+
const state = useOverlayTriggerState({})
|
|
219
|
+
return (
|
|
220
|
+
<OverlayProvider>
|
|
221
|
+
<Button onClick={() => state.open()}>Open Modal</Button>
|
|
212
222
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
</
|
|
229
|
-
</
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
</ModalButtons>
|
|
235
|
-
</ModalBody>
|
|
236
|
-
</Modal>
|
|
237
|
-
</OverlayProvider>
|
|
238
|
-
)
|
|
223
|
+
<Modal {...args} isOpen={state.isOpen} onClose={() => state.close()}>
|
|
224
|
+
<ModalHeader />
|
|
225
|
+
<ModalBody>
|
|
226
|
+
<ModalVStack>
|
|
227
|
+
<StyledModalText>
|
|
228
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod
|
|
229
|
+
placeat tenetur, necessitatibus laudantium cumque exercitationem
|
|
230
|
+
provident. Quaerat iure enim, eveniet dolores earum odio quo
|
|
231
|
+
possimus fugiat aspernatur, numquam, commodi repellat.
|
|
232
|
+
</StyledModalText>
|
|
233
|
+
</ModalVStack>
|
|
234
|
+
<ModalButtons>
|
|
235
|
+
<Button variant="Primary" onClick={() => state.close()} fullWidth>
|
|
236
|
+
OK
|
|
237
|
+
</Button>
|
|
238
|
+
</ModalButtons>
|
|
239
|
+
</ModalBody>
|
|
240
|
+
</Modal>
|
|
241
|
+
</OverlayProvider>
|
|
242
|
+
)
|
|
243
|
+
},
|
|
239
244
|
}
|
|
245
|
+
|
|
240
246
|
export { InternalScrollStory as InternalScroll } from './__stories__/InternalScrollStory'
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { useContext, forwardRef, memo } from 'react'
|
|
2
2
|
import * as React from 'react'
|
|
3
|
-
import {
|
|
4
|
-
AriaModalOverlayProps,
|
|
5
|
-
Overlay,
|
|
6
|
-
useModalOverlay,
|
|
7
|
-
} from '@react-aria/overlays'
|
|
3
|
+
import { AriaModalOverlayProps, Overlay } from '@react-aria/overlays'
|
|
8
4
|
import styled, { css, useTheme } from 'styled-components'
|
|
9
5
|
import { AriaDialogProps } from '@react-types/dialog'
|
|
10
6
|
import { maxWidth } from '@charcoal-ui/utils'
|
|
@@ -15,6 +11,7 @@ import IconButton from '../IconButton'
|
|
|
15
11
|
import { useObjectRef } from '@react-aria/utils'
|
|
16
12
|
import { Dialog } from './Dialog'
|
|
17
13
|
import { ModalBackgroundContext } from './ModalBackgroundContext'
|
|
14
|
+
import { useCharcoalModalOverlay } from './useCustomModalOverlay'
|
|
18
15
|
|
|
19
16
|
export type BottomSheet = boolean | 'full'
|
|
20
17
|
export type Size = 'S' | 'M' | 'L'
|
|
@@ -81,27 +78,15 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(function ModalInner(
|
|
|
81
78
|
|
|
82
79
|
const ref = useObjectRef<HTMLDivElement>(external)
|
|
83
80
|
|
|
84
|
-
const { modalProps, underlayProps } =
|
|
81
|
+
const { modalProps, underlayProps } = useCharcoalModalOverlay(
|
|
85
82
|
{
|
|
86
83
|
...props,
|
|
87
84
|
isKeyboardDismissDisabled:
|
|
88
85
|
isDismissable === undefined || isDismissable === false,
|
|
89
86
|
},
|
|
90
|
-
|
|
91
87
|
{
|
|
92
|
-
|
|
93
|
-
isOpen
|
|
94
|
-
// these props are not used actually.
|
|
95
|
-
// https://github.com/adobe/react-spectrum/blob/df14e3fb129b94b310f0397a701b83f006b51dfe/packages/%40react-aria/overlays/src/useModalOverlay.ts
|
|
96
|
-
open: () => {
|
|
97
|
-
// nope
|
|
98
|
-
},
|
|
99
|
-
setOpen: () => {
|
|
100
|
-
// nope
|
|
101
|
-
},
|
|
102
|
-
toggle: () => {
|
|
103
|
-
// nope
|
|
104
|
-
},
|
|
88
|
+
onClose,
|
|
89
|
+
isOpen,
|
|
105
90
|
},
|
|
106
91
|
ref
|
|
107
92
|
)
|
|
@@ -136,6 +121,15 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(function ModalInner(
|
|
|
136
121
|
|
|
137
122
|
const bgRef = React.useRef<HTMLElement>(null)
|
|
138
123
|
|
|
124
|
+
const handleClick = React.useCallback(
|
|
125
|
+
(e: MouseEvent) => {
|
|
126
|
+
if (e.currentTarget === e.target) {
|
|
127
|
+
onClose()
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
[onClose]
|
|
131
|
+
)
|
|
132
|
+
|
|
139
133
|
return transition(
|
|
140
134
|
({ backgroundColor, overflow, transform }, item) =>
|
|
141
135
|
item && (
|
|
@@ -146,6 +140,7 @@ const Modal = forwardRef<HTMLDivElement, ModalProps>(function ModalInner(
|
|
|
146
140
|
{...underlayProps}
|
|
147
141
|
style={transitionEnabled ? { backgroundColor, overflow } : {}}
|
|
148
142
|
$bottomSheet={bottomSheet}
|
|
143
|
+
onClick={handleClick}
|
|
149
144
|
>
|
|
150
145
|
<ModalBackgroundContext.Provider value={bgRef.current}>
|
|
151
146
|
<Dialog
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
AriaModalOverlayProps,
|
|
4
|
+
ModalOverlayAria,
|
|
5
|
+
ariaHideOutside,
|
|
6
|
+
useOverlay,
|
|
7
|
+
useOverlayFocusContain,
|
|
8
|
+
} from '@react-aria/overlays'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* We want to enable scrolling on the modal background,
|
|
12
|
+
* but `useModalOverlay` (specifically, `useOverlay` within it) detects pointer events on the scrollbar.
|
|
13
|
+
* Therefore, to prevent this issue, we need to override `shouldCloseOnInteractOutside` in `useModalOverlay`.
|
|
14
|
+
*/
|
|
15
|
+
export function useCharcoalModalOverlay(
|
|
16
|
+
props: AriaModalOverlayProps,
|
|
17
|
+
state: { isOpen: boolean; onClose: () => void },
|
|
18
|
+
ref: React.RefObject<HTMLElement>
|
|
19
|
+
): ModalOverlayAria {
|
|
20
|
+
const { overlayProps, underlayProps } = useOverlay(
|
|
21
|
+
{
|
|
22
|
+
...props,
|
|
23
|
+
isOpen: state.isOpen,
|
|
24
|
+
onClose: state.onClose,
|
|
25
|
+
shouldCloseOnInteractOutside: () => false,
|
|
26
|
+
},
|
|
27
|
+
ref
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
useOverlayFocusContain()
|
|
31
|
+
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
if (state.isOpen && ref.current) {
|
|
34
|
+
return ariaHideOutside([ref.current])
|
|
35
|
+
}
|
|
36
|
+
}, [state.isOpen, ref])
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
modalProps: overlayProps,
|
|
40
|
+
underlayProps,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`
|
|
3
|
+
exports[`Storybook Tests MultiSelect Default 1`] = `
|
|
4
4
|
.c1 {
|
|
5
5
|
display: grid;
|
|
6
6
|
grid-template-columns: auto 1fr;
|
|
@@ -88,6 +88,19 @@ exports[`Storyshots MultiSelect Default 1`] = `
|
|
|
88
88
|
background-color: var(--charcoal-text3-press);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
.c2[type='checkbox']:focus {
|
|
92
|
+
outline: none;
|
|
93
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.c2[type='checkbox']:focus:not(:focus-visible) {
|
|
97
|
+
box-shadow: none;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.c2[type='checkbox']:focus-visible {
|
|
101
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
102
|
+
}
|
|
103
|
+
|
|
91
104
|
.c3 {
|
|
92
105
|
position: absolute;
|
|
93
106
|
top: -2px;
|
|
@@ -251,7 +264,7 @@ exports[`Storyshots MultiSelect Default 1`] = `
|
|
|
251
264
|
</div>
|
|
252
265
|
`;
|
|
253
266
|
|
|
254
|
-
exports[`
|
|
267
|
+
exports[`Storybook Tests MultiSelect Invalid 1`] = `
|
|
255
268
|
.c1 {
|
|
256
269
|
display: grid;
|
|
257
270
|
grid-template-columns: auto 1fr;
|
|
@@ -339,6 +352,19 @@ exports[`Storyshots MultiSelect Invalid 1`] = `
|
|
|
339
352
|
background-color: var(--charcoal-text3-press);
|
|
340
353
|
}
|
|
341
354
|
|
|
355
|
+
.c2[type='checkbox']:focus {
|
|
356
|
+
outline: none;
|
|
357
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.c2[type='checkbox']:focus:not(:focus-visible) {
|
|
361
|
+
box-shadow: none;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.c2[type='checkbox']:focus-visible {
|
|
365
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
366
|
+
}
|
|
367
|
+
|
|
342
368
|
.c2[type='checkbox']:not(:disabled):not([aria-disabled]),
|
|
343
369
|
.c2[type='checkbox'][aria-disabled='false'] {
|
|
344
370
|
box-shadow: 0 0 0 4px rgba(255,43,0,0.32);
|
|
@@ -507,7 +533,7 @@ exports[`Storyshots MultiSelect Invalid 1`] = `
|
|
|
507
533
|
</div>
|
|
508
534
|
`;
|
|
509
535
|
|
|
510
|
-
exports[`
|
|
536
|
+
exports[`Storybook Tests MultiSelect Overlay 1`] = `
|
|
511
537
|
.c1 {
|
|
512
538
|
display: grid;
|
|
513
539
|
grid-template-columns: auto 1fr;
|
|
@@ -596,6 +622,19 @@ exports[`Storyshots MultiSelect Overlay 1`] = `
|
|
|
596
622
|
background-color: var(--charcoal-text3-press);
|
|
597
623
|
}
|
|
598
624
|
|
|
625
|
+
.c2[type='checkbox']:focus {
|
|
626
|
+
outline: none;
|
|
627
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.c2[type='checkbox']:focus:not(:focus-visible) {
|
|
631
|
+
box-shadow: none;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.c2[type='checkbox']:focus-visible {
|
|
635
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
636
|
+
}
|
|
637
|
+
|
|
599
638
|
.c3 {
|
|
600
639
|
position: absolute;
|
|
601
640
|
top: -2px;
|
|
@@ -762,7 +801,7 @@ exports[`Storyshots MultiSelect Overlay 1`] = `
|
|
|
762
801
|
</div>
|
|
763
802
|
`;
|
|
764
803
|
|
|
765
|
-
exports[`
|
|
804
|
+
exports[`Storybook Tests MultiSelect Playground 1`] = `
|
|
766
805
|
.c1 {
|
|
767
806
|
display: grid;
|
|
768
807
|
grid-template-columns: auto 1fr;
|
|
@@ -850,6 +889,19 @@ exports[`Storyshots MultiSelect Playground 1`] = `
|
|
|
850
889
|
background-color: var(--charcoal-text3-press);
|
|
851
890
|
}
|
|
852
891
|
|
|
892
|
+
.c2[type='checkbox']:focus {
|
|
893
|
+
outline: none;
|
|
894
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
.c2[type='checkbox']:focus:not(:focus-visible) {
|
|
898
|
+
box-shadow: none;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
.c2[type='checkbox']:focus-visible {
|
|
902
|
+
box-shadow: 0 0 0 4px rgba(0,150,250,0.32);
|
|
903
|
+
}
|
|
904
|
+
|
|
853
905
|
.c3 {
|
|
854
906
|
position: absolute;
|
|
855
907
|
top: -2px;
|
|
@@ -5,6 +5,7 @@ import warning from 'warning'
|
|
|
5
5
|
import { px } from '@charcoal-ui/utils'
|
|
6
6
|
|
|
7
7
|
import { MultiSelectGroupContext } from './context'
|
|
8
|
+
import { focusVisibleFocusRingCss } from '@charcoal-ui/styled'
|
|
8
9
|
|
|
9
10
|
export type MultiSelectProps = React.PropsWithChildren<{
|
|
10
11
|
value: string
|
|
@@ -168,6 +169,8 @@ const MultiSelectInput = styled.input.attrs({ type: 'checkbox' })<{
|
|
|
168
169
|
}
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
${focusVisibleFocusRingCss}
|
|
173
|
+
|
|
171
174
|
${({ invalid, overlay }) =>
|
|
172
175
|
invalid &&
|
|
173
176
|
!overlay &&
|