@proyecto-viviana/solidaria-components 0.1.3 → 0.2.2
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/Color.d.ts +6 -2
- package/dist/Color.d.ts.map +1 -1
- package/dist/ComboBox.d.ts +3 -3
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/GridList.d.ts +2 -2
- package/dist/GridList.d.ts.map +1 -1
- package/dist/ListBox.d.ts +5 -5
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/Menu.d.ts +3 -3
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Select.d.ts +3 -3
- package/dist/Select.d.ts.map +1 -1
- package/dist/Table.d.ts +2 -2
- package/dist/Table.d.ts.map +1 -1
- package/dist/Tabs.d.ts +1 -1
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +2 -2
- package/dist/index.jsx +9056 -0
- package/dist/index.jsx.map +7 -0
- package/dist/index.ssr.js +15 -15
- package/dist/index.ssr.js.map +2 -2
- package/package.json +8 -10
- package/src/Autocomplete.tsx +0 -174
- package/src/Breadcrumbs.tsx +0 -264
- package/src/Button.tsx +0 -238
- package/src/Calendar.tsx +0 -471
- package/src/Checkbox.tsx +0 -387
- package/src/Color.tsx +0 -1370
- package/src/ComboBox.tsx +0 -824
- package/src/DateField.tsx +0 -337
- package/src/DatePicker.tsx +0 -367
- package/src/Dialog.tsx +0 -262
- package/src/Disclosure.tsx +0 -439
- package/src/GridList.tsx +0 -511
- package/src/Landmark.tsx +0 -203
- package/src/Link.tsx +0 -201
- package/src/ListBox.tsx +0 -346
- package/src/Menu.tsx +0 -544
- package/src/Meter.tsx +0 -157
- package/src/Modal.tsx +0 -433
- package/src/NumberField.tsx +0 -542
- package/src/Popover.tsx +0 -540
- package/src/ProgressBar.tsx +0 -162
- package/src/RadioGroup.tsx +0 -356
- package/src/RangeCalendar.tsx +0 -462
- package/src/SearchField.tsx +0 -479
- package/src/Select.tsx +0 -734
- package/src/Separator.tsx +0 -130
- package/src/Slider.tsx +0 -500
- package/src/Switch.tsx +0 -213
- package/src/Table.tsx +0 -857
- package/src/Tabs.tsx +0 -552
- package/src/TagGroup.tsx +0 -421
- package/src/TextField.tsx +0 -271
- package/src/TimeField.tsx +0 -455
- package/src/Toast.tsx +0 -503
- package/src/Toolbar.tsx +0 -160
- package/src/Tooltip.tsx +0 -423
- package/src/Tree.tsx +0 -551
- package/src/VisuallyHidden.tsx +0 -60
- package/src/contexts.ts +0 -74
- package/src/index.ts +0 -620
- package/src/utils.tsx +0 -329
package/src/Modal.tsx
DELETED
|
@@ -1,433 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Modal and ModalOverlay components for solidaria-components
|
|
3
|
-
*
|
|
4
|
-
* Headless modal components with overlay, focus trapping, and dismissal handling.
|
|
5
|
-
* Port of react-aria-components Modal.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
type JSX,
|
|
10
|
-
createContext,
|
|
11
|
-
createMemo,
|
|
12
|
-
createSignal,
|
|
13
|
-
createEffect,
|
|
14
|
-
onCleanup,
|
|
15
|
-
splitProps,
|
|
16
|
-
Show,
|
|
17
|
-
useContext,
|
|
18
|
-
} from 'solid-js'
|
|
19
|
-
import { Portal, isServer } from 'solid-js/web'
|
|
20
|
-
import {
|
|
21
|
-
createInteractOutside,
|
|
22
|
-
ariaHideOutside,
|
|
23
|
-
FocusScope,
|
|
24
|
-
} from '@proyecto-viviana/solidaria'
|
|
25
|
-
import {
|
|
26
|
-
type RenderChildren,
|
|
27
|
-
type ClassNameOrFunction,
|
|
28
|
-
type StyleOrFunction,
|
|
29
|
-
useRenderProps,
|
|
30
|
-
filterDOMProps,
|
|
31
|
-
dataAttr,
|
|
32
|
-
} from './utils'
|
|
33
|
-
import {
|
|
34
|
-
DialogTriggerContext,
|
|
35
|
-
OverlayTriggerStateContext,
|
|
36
|
-
type OverlayTriggerState,
|
|
37
|
-
} from './contexts'
|
|
38
|
-
|
|
39
|
-
// ============================================
|
|
40
|
-
// INTERNAL CONTEXT
|
|
41
|
-
// ============================================
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Internal context to signal that Modal is wrapped in ModalOverlay.
|
|
45
|
-
* When present, Modal should not create its own Portal.
|
|
46
|
-
*/
|
|
47
|
-
interface InternalModalContextValue {
|
|
48
|
-
isDismissable?: boolean
|
|
49
|
-
isKeyboardDismissDisabled?: boolean
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const InternalModalContext = createContext<InternalModalContextValue | null>(null)
|
|
53
|
-
|
|
54
|
-
// ============================================
|
|
55
|
-
// TYPES
|
|
56
|
-
// ============================================
|
|
57
|
-
|
|
58
|
-
export interface ModalRenderProps {
|
|
59
|
-
/** Whether the modal is currently entering (for animations). */
|
|
60
|
-
isEntering: boolean
|
|
61
|
-
/** Whether the modal is currently exiting (for animations). */
|
|
62
|
-
isExiting: boolean
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface ModalOverlayProps {
|
|
66
|
-
/** The children of the component - can be JSX or render function. */
|
|
67
|
-
children?: RenderChildren<ModalRenderProps>
|
|
68
|
-
/** The CSS className for the element. */
|
|
69
|
-
class?: ClassNameOrFunction<ModalRenderProps>
|
|
70
|
-
/** The inline style for the element. */
|
|
71
|
-
style?: StyleOrFunction<ModalRenderProps>
|
|
72
|
-
/** Whether the modal is open (controlled). */
|
|
73
|
-
isOpen?: boolean
|
|
74
|
-
/** Whether the modal opens by default (uncontrolled). */
|
|
75
|
-
defaultOpen?: boolean
|
|
76
|
-
/** Handler called when the modal's open state changes. */
|
|
77
|
-
onOpenChange?: (isOpen: boolean) => void
|
|
78
|
-
/** Whether clicking outside the modal closes it. */
|
|
79
|
-
isDismissable?: boolean
|
|
80
|
-
/** Whether pressing Escape closes the modal. */
|
|
81
|
-
isKeyboardDismissDisabled?: boolean
|
|
82
|
-
/** Whether the modal is entering (for animations). */
|
|
83
|
-
isEntering?: boolean
|
|
84
|
-
/** Whether the modal is exiting (for animations). */
|
|
85
|
-
isExiting?: boolean
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface ModalProps extends ModalOverlayProps {}
|
|
89
|
-
|
|
90
|
-
// Re-export from contexts for backwards compatibility
|
|
91
|
-
export { OverlayTriggerStateContext, type OverlayTriggerState } from './contexts'
|
|
92
|
-
export { useOverlayTriggerState } from './contexts'
|
|
93
|
-
|
|
94
|
-
// ============================================
|
|
95
|
-
// MODAL OVERLAY COMPONENT
|
|
96
|
-
// ============================================
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* ModalOverlay is the backdrop/underlay behind a modal.
|
|
100
|
-
* It handles click-outside dismissal and provides styling hooks.
|
|
101
|
-
*/
|
|
102
|
-
export function ModalOverlay(props: ModalOverlayProps): JSX.Element {
|
|
103
|
-
if (isServer) {
|
|
104
|
-
return <>{props.children}</>
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// IMPORTANT: Don't destructure or access props.children early!
|
|
108
|
-
// In SolidJS, children are lazily evaluated. Accessing them before
|
|
109
|
-
// the context provider renders causes them to evaluate outside the context.
|
|
110
|
-
// See: https://github.com/solidjs/solid/issues/182
|
|
111
|
-
const [local, rest] = splitProps(props, [
|
|
112
|
-
'class',
|
|
113
|
-
'style',
|
|
114
|
-
'isOpen',
|
|
115
|
-
'defaultOpen',
|
|
116
|
-
'onOpenChange',
|
|
117
|
-
'isDismissable',
|
|
118
|
-
'isKeyboardDismissDisabled',
|
|
119
|
-
'isEntering',
|
|
120
|
-
'isExiting',
|
|
121
|
-
])
|
|
122
|
-
|
|
123
|
-
// Get state from DialogTrigger context if available
|
|
124
|
-
const dialogTriggerContext = useContext(DialogTriggerContext)
|
|
125
|
-
|
|
126
|
-
// Internal state for uncontrolled mode
|
|
127
|
-
const [internalOpen, setInternalOpen] = createSignal(local.defaultOpen ?? false)
|
|
128
|
-
|
|
129
|
-
// Determine if open (controlled > DialogTrigger context > uncontrolled)
|
|
130
|
-
const isOpen = (): boolean => {
|
|
131
|
-
if (local.isOpen !== undefined) return local.isOpen
|
|
132
|
-
if (dialogTriggerContext) return dialogTriggerContext.state.isOpen()
|
|
133
|
-
return internalOpen()
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const close = () => {
|
|
137
|
-
if (local.isOpen !== undefined) {
|
|
138
|
-
local.onOpenChange?.(false)
|
|
139
|
-
} else if (dialogTriggerContext) {
|
|
140
|
-
dialogTriggerContext.state.close()
|
|
141
|
-
local.onOpenChange?.(false)
|
|
142
|
-
} else {
|
|
143
|
-
setInternalOpen(false)
|
|
144
|
-
local.onOpenChange?.(false)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const open = () => {
|
|
149
|
-
if (local.isOpen !== undefined) {
|
|
150
|
-
local.onOpenChange?.(true)
|
|
151
|
-
} else if (dialogTriggerContext) {
|
|
152
|
-
dialogTriggerContext.state.open()
|
|
153
|
-
local.onOpenChange?.(true)
|
|
154
|
-
} else {
|
|
155
|
-
setInternalOpen(true)
|
|
156
|
-
local.onOpenChange?.(true)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const toggle = () => {
|
|
161
|
-
if (isOpen()) {
|
|
162
|
-
close()
|
|
163
|
-
} else {
|
|
164
|
-
open()
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Create overlay trigger state for context
|
|
169
|
-
const state: OverlayTriggerState = {
|
|
170
|
-
get isOpen() { return isOpen() },
|
|
171
|
-
open,
|
|
172
|
-
close,
|
|
173
|
-
toggle,
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Render props values
|
|
177
|
-
const renderValues = createMemo<ModalRenderProps>(() => ({
|
|
178
|
-
isEntering: local.isEntering ?? false,
|
|
179
|
-
isExiting: local.isExiting ?? false,
|
|
180
|
-
}))
|
|
181
|
-
|
|
182
|
-
// Resolve render props - don't pass children, we'll render props.children directly
|
|
183
|
-
const renderProps = useRenderProps(
|
|
184
|
-
{
|
|
185
|
-
class: local.class,
|
|
186
|
-
style: local.style,
|
|
187
|
-
defaultClassName: 'solidaria-ModalOverlay',
|
|
188
|
-
},
|
|
189
|
-
renderValues
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
// Filter DOM props
|
|
193
|
-
const domProps = createMemo(() => filterDOMProps(rest as Record<string, unknown>, { global: true }))
|
|
194
|
-
|
|
195
|
-
// Internal context value to signal Modal that it's wrapped
|
|
196
|
-
const internalModalContext: InternalModalContextValue = {
|
|
197
|
-
isDismissable: local.isDismissable,
|
|
198
|
-
isKeyboardDismissDisabled: local.isKeyboardDismissDisabled,
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Resolve children - handle both static JSX and render functions
|
|
202
|
-
// IMPORTANT: We access props.children directly (not local.children) to preserve
|
|
203
|
-
// lazy evaluation inside context providers
|
|
204
|
-
const resolveChildren = () => {
|
|
205
|
-
const children = props.children
|
|
206
|
-
if (typeof children === 'function') {
|
|
207
|
-
return (children as (props: ModalRenderProps) => JSX.Element)(renderValues())
|
|
208
|
-
}
|
|
209
|
-
return children
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return (
|
|
213
|
-
<Show when={isOpen() || local.isExiting}>
|
|
214
|
-
<Portal>
|
|
215
|
-
<OverlayTriggerStateContext.Provider value={state}>
|
|
216
|
-
<InternalModalContext.Provider value={internalModalContext}>
|
|
217
|
-
<div
|
|
218
|
-
{...domProps()}
|
|
219
|
-
class={renderProps.class()}
|
|
220
|
-
style={renderProps.style()}
|
|
221
|
-
data-entering={dataAttr(local.isEntering)}
|
|
222
|
-
data-exiting={dataAttr(local.isExiting)}
|
|
223
|
-
>
|
|
224
|
-
{resolveChildren()}
|
|
225
|
-
</div>
|
|
226
|
-
</InternalModalContext.Provider>
|
|
227
|
-
</OverlayTriggerStateContext.Provider>
|
|
228
|
-
</Portal>
|
|
229
|
-
</Show>
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// ============================================
|
|
234
|
-
// MODAL COMPONENT
|
|
235
|
-
// ============================================
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Modal is a dialog container that manages focus trapping, scroll prevention,
|
|
239
|
-
* aria-hiding of content outside, and dismissal.
|
|
240
|
-
*
|
|
241
|
-
* Usage patterns:
|
|
242
|
-
* 1. Standalone: `<Modal isOpen>...</Modal>` - Creates its own overlay
|
|
243
|
-
* 2. With custom overlay: `<ModalOverlay><Modal>...</Modal></ModalOverlay>`
|
|
244
|
-
*
|
|
245
|
-
* Note: Due to SolidJS's eager JSX evaluation, we cannot detect at render time
|
|
246
|
-
* whether Modal is wrapped in ModalOverlay. So standalone Modal always creates
|
|
247
|
-
* an overlay, and wrapped Modal renders directly (relying on InternalModalContext).
|
|
248
|
-
*/
|
|
249
|
-
export function Modal(props: ModalProps): JSX.Element {
|
|
250
|
-
// Check for InternalModalContext which signals we're inside a rendered ModalOverlay
|
|
251
|
-
// This works because ModalContent is rendered INSIDE ModalOverlay's Show/Portal
|
|
252
|
-
return <ModalContentWithAutoOverlay {...props} />
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Helper component that handles the overlay detection.
|
|
257
|
-
* By being a separate component, we can use Show to defer rendering until
|
|
258
|
-
* the parent context is available.
|
|
259
|
-
*/
|
|
260
|
-
function ModalContentWithAutoOverlay(props: ModalProps): JSX.Element {
|
|
261
|
-
const [overlayProps, modalProps] = splitProps(props, [
|
|
262
|
-
'isOpen',
|
|
263
|
-
'defaultOpen',
|
|
264
|
-
'onOpenChange',
|
|
265
|
-
'isDismissable',
|
|
266
|
-
'isKeyboardDismissDisabled',
|
|
267
|
-
'isEntering',
|
|
268
|
-
'isExiting',
|
|
269
|
-
])
|
|
270
|
-
|
|
271
|
-
// Check for InternalModalContext - if present, we're inside a ModalOverlay
|
|
272
|
-
const internalContext = useContext(InternalModalContext)
|
|
273
|
-
|
|
274
|
-
// If wrapped in ModalOverlay, just render the content
|
|
275
|
-
if (internalContext) {
|
|
276
|
-
return (
|
|
277
|
-
<ModalContent {...modalProps} internalContext={internalContext}>
|
|
278
|
-
{props.children}
|
|
279
|
-
</ModalContent>
|
|
280
|
-
)
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// For standalone usage, wrap in ModalOverlay
|
|
284
|
-
const standaloneContext: InternalModalContextValue = {
|
|
285
|
-
isDismissable: overlayProps.isDismissable,
|
|
286
|
-
isKeyboardDismissDisabled: overlayProps.isKeyboardDismissDisabled,
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return (
|
|
290
|
-
<ModalOverlay {...overlayProps}>
|
|
291
|
-
<ModalContent {...modalProps} internalContext={standaloneContext}>
|
|
292
|
-
{props.children}
|
|
293
|
-
</ModalContent>
|
|
294
|
-
</ModalOverlay>
|
|
295
|
-
)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Internal component that renders the actual modal content.
|
|
300
|
-
* Used by both standalone Modal and Modal wrapped in ModalOverlay.
|
|
301
|
-
*/
|
|
302
|
-
function ModalContent(props: ModalProps & { internalContext: InternalModalContextValue }): JSX.Element {
|
|
303
|
-
if (isServer) {
|
|
304
|
-
return <>{props.children}</>
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const [local, rest] = splitProps(props, [
|
|
308
|
-
'children',
|
|
309
|
-
'class',
|
|
310
|
-
'style',
|
|
311
|
-
'isOpen',
|
|
312
|
-
'defaultOpen',
|
|
313
|
-
'onOpenChange',
|
|
314
|
-
'isDismissable',
|
|
315
|
-
'isKeyboardDismissDisabled',
|
|
316
|
-
'isEntering',
|
|
317
|
-
'isExiting',
|
|
318
|
-
'internalContext',
|
|
319
|
-
])
|
|
320
|
-
|
|
321
|
-
let modalRef!: HTMLDivElement
|
|
322
|
-
|
|
323
|
-
// Get state from parent OverlayTriggerStateContext (provided by ModalOverlay)
|
|
324
|
-
const parentState = useContext(OverlayTriggerStateContext)
|
|
325
|
-
|
|
326
|
-
// Get dismissable settings from internal context (set by ModalOverlay)
|
|
327
|
-
const isDismissable = () => local.internalContext?.isDismissable ?? local.isDismissable
|
|
328
|
-
const isKeyboardDismissDisabled = () => local.internalContext?.isKeyboardDismissDisabled ?? local.isKeyboardDismissDisabled
|
|
329
|
-
|
|
330
|
-
// Determine if open from parent state
|
|
331
|
-
const isOpen = (): boolean => {
|
|
332
|
-
if (local.isOpen !== undefined) return local.isOpen
|
|
333
|
-
return parentState?.isOpen ?? false
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const close = () => {
|
|
337
|
-
if (local.isOpen !== undefined) {
|
|
338
|
-
local.onOpenChange?.(false)
|
|
339
|
-
} else {
|
|
340
|
-
parentState?.close()
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Prevent scroll when modal is open
|
|
345
|
-
createEffect(() => {
|
|
346
|
-
if (!isOpen()) return
|
|
347
|
-
|
|
348
|
-
// Set overflow hidden on html element
|
|
349
|
-
const html = document.documentElement
|
|
350
|
-
const prevOverflow = html.style.overflow
|
|
351
|
-
html.style.overflow = 'hidden'
|
|
352
|
-
|
|
353
|
-
onCleanup(() => {
|
|
354
|
-
html.style.overflow = prevOverflow
|
|
355
|
-
})
|
|
356
|
-
})
|
|
357
|
-
|
|
358
|
-
// Click outside to close (if dismissable)
|
|
359
|
-
createEffect(() => {
|
|
360
|
-
if (!isOpen() || !isDismissable()) return
|
|
361
|
-
|
|
362
|
-
createInteractOutside({
|
|
363
|
-
ref: () => modalRef ?? null,
|
|
364
|
-
onInteractOutside: () => {
|
|
365
|
-
close()
|
|
366
|
-
},
|
|
367
|
-
isDisabled: false,
|
|
368
|
-
})
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
// Escape key to close
|
|
372
|
-
createEffect(() => {
|
|
373
|
-
if (!isOpen() || isKeyboardDismissDisabled()) return
|
|
374
|
-
|
|
375
|
-
const handleKeyDown = (e: KeyboardEvent) => {
|
|
376
|
-
if (e.key === 'Escape') {
|
|
377
|
-
e.preventDefault()
|
|
378
|
-
e.stopPropagation()
|
|
379
|
-
close()
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
document.addEventListener('keydown', handleKeyDown, true)
|
|
384
|
-
onCleanup(() => {
|
|
385
|
-
document.removeEventListener('keydown', handleKeyDown, true)
|
|
386
|
-
})
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
// Aria-hide outside content
|
|
390
|
-
createEffect(() => {
|
|
391
|
-
if (!isOpen() || !modalRef) return
|
|
392
|
-
|
|
393
|
-
const cleanup = ariaHideOutside([modalRef])
|
|
394
|
-
onCleanup(cleanup)
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
// Render props values
|
|
398
|
-
const renderValues = createMemo<ModalRenderProps>(() => ({
|
|
399
|
-
isEntering: local.isEntering ?? false,
|
|
400
|
-
isExiting: local.isExiting ?? false,
|
|
401
|
-
}))
|
|
402
|
-
|
|
403
|
-
// Resolve render props
|
|
404
|
-
const renderProps = useRenderProps(
|
|
405
|
-
{
|
|
406
|
-
children: props.children,
|
|
407
|
-
class: local.class,
|
|
408
|
-
style: local.style,
|
|
409
|
-
defaultClassName: 'solidaria-Modal',
|
|
410
|
-
},
|
|
411
|
-
renderValues
|
|
412
|
-
)
|
|
413
|
-
|
|
414
|
-
// Filter DOM props
|
|
415
|
-
const domProps = createMemo(() => filterDOMProps(rest as Record<string, unknown>, { global: true }))
|
|
416
|
-
|
|
417
|
-
return (
|
|
418
|
-
<FocusScope contain restoreFocus autoFocus>
|
|
419
|
-
<div
|
|
420
|
-
{...domProps()}
|
|
421
|
-
ref={modalRef}
|
|
422
|
-
class={renderProps.class()}
|
|
423
|
-
style={renderProps.style()}
|
|
424
|
-
data-entering={dataAttr(local.isEntering)}
|
|
425
|
-
data-exiting={dataAttr(local.isExiting)}
|
|
426
|
-
>
|
|
427
|
-
{renderProps.renderChildren()}
|
|
428
|
-
</div>
|
|
429
|
-
</FocusScope>
|
|
430
|
-
)
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
export default Modal
|