@proyecto-viviana/ui 0.3.2 → 0.3.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/components.css +1077 -1077
- package/dist/index.js +236 -249
- package/dist/index.js.map +3 -3
- package/dist/index.ssr.js +78 -81
- package/dist/index.ssr.js.map +3 -3
- package/dist/radio/index.d.ts +12 -27
- package/dist/radio/index.d.ts.map +1 -1
- package/dist/test-utils/index.d.ts +2 -2
- package/dist/test-utils/index.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/alert/index.tsx +48 -0
- package/src/assets/favicon.png +0 -0
- package/src/assets/fire.gif +0 -0
- package/src/autocomplete/index.tsx +313 -0
- package/src/avatar/index.tsx +75 -0
- package/src/badge/index.tsx +43 -0
- package/src/breadcrumbs/index.tsx +207 -0
- package/src/button/Button.tsx +74 -0
- package/src/button/index.ts +2 -0
- package/src/button/types.ts +24 -0
- package/src/calendar/DateField.tsx +200 -0
- package/src/calendar/DatePicker.tsx +298 -0
- package/src/calendar/RangeCalendar.tsx +236 -0
- package/src/calendar/TimeField.tsx +196 -0
- package/src/calendar/index.tsx +223 -0
- package/src/checkbox/index.tsx +257 -0
- package/src/color/index.tsx +687 -0
- package/src/combobox/index.tsx +383 -0
- package/src/components.css +1077 -0
- package/src/custom/calendar-card/index.tsx +66 -0
- package/src/custom/chip/index.tsx +46 -0
- package/src/custom/conversation/index.tsx +105 -0
- package/src/custom/event-card/index.tsx +132 -0
- package/src/custom/header/index.tsx +33 -0
- package/src/custom/lateral-nav/index.tsx +88 -0
- package/src/custom/logo/index.tsx +58 -0
- package/src/custom/nav-header/index.tsx +42 -0
- package/src/custom/page-layout/index.tsx +29 -0
- package/src/custom/profile-card/index.tsx +64 -0
- package/src/custom/project-card/index.tsx +59 -0
- package/src/custom/timeline-item/index.tsx +105 -0
- package/src/dialog/Dialog.tsx +260 -0
- package/src/dialog/index.tsx +3 -0
- package/src/disclosure/index.tsx +307 -0
- package/src/gridlist/index.tsx +403 -0
- package/src/icon/icons/GitHubIcon.tsx +20 -0
- package/src/icon/index.tsx +48 -0
- package/src/index.ts +322 -0
- package/src/landmark/index.tsx +231 -0
- package/src/link/index.tsx +130 -0
- package/src/listbox/index.tsx +231 -0
- package/src/menu/index.tsx +297 -0
- package/src/meter/index.tsx +163 -0
- package/src/numberfield/index.tsx +482 -0
- package/src/popover/index.tsx +260 -0
- package/src/progress-bar/index.tsx +169 -0
- package/src/radio/index.tsx +173 -0
- package/src/searchfield/index.tsx +453 -0
- package/src/select/index.tsx +349 -0
- package/src/separator/index.tsx +141 -0
- package/src/slider/index.tsx +382 -0
- package/src/styles.css +450 -0
- package/src/switch/ToggleSwitch.tsx +112 -0
- package/src/switch/index.tsx +90 -0
- package/src/table/index.tsx +531 -0
- package/src/tabs/index.tsx +273 -0
- package/src/tag-group/index.tsx +240 -0
- package/src/test-utils/index.ts +40 -0
- package/src/textfield/index.tsx +211 -0
- package/src/theme.css +101 -0
- package/src/toast/index.tsx +324 -0
- package/src/toolbar/index.tsx +108 -0
- package/src/tooltip/index.tsx +197 -0
- package/src/tree/index.tsx +494 -0
- package/dist/index.jsx +0 -6658
- package/dist/index.jsx.map +0 -7
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComboBox component for proyecto-viviana-ui
|
|
3
|
+
*
|
|
4
|
+
* Styled combobox component built on top of solidaria-components.
|
|
5
|
+
* Inspired by Spectrum 2's ComboBox component patterns.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { type JSX, splitProps, createContext, useContext, Show } from 'solid-js'
|
|
9
|
+
import {
|
|
10
|
+
ComboBox as HeadlessComboBox,
|
|
11
|
+
ComboBoxInput as HeadlessComboBoxInput,
|
|
12
|
+
ComboBoxButton as HeadlessComboBoxButton,
|
|
13
|
+
ComboBoxListBox as HeadlessComboBoxListBox,
|
|
14
|
+
ComboBoxOption as HeadlessComboBoxOption,
|
|
15
|
+
defaultContainsFilter,
|
|
16
|
+
type ComboBoxProps as HeadlessComboBoxProps,
|
|
17
|
+
type ComboBoxInputProps as HeadlessComboBoxInputProps,
|
|
18
|
+
type ComboBoxButtonProps as HeadlessComboBoxButtonProps,
|
|
19
|
+
type ComboBoxListBoxProps as HeadlessComboBoxListBoxProps,
|
|
20
|
+
type ComboBoxOptionProps as HeadlessComboBoxOptionProps,
|
|
21
|
+
type ComboBoxRenderProps,
|
|
22
|
+
type ComboBoxInputRenderProps,
|
|
23
|
+
type ComboBoxButtonRenderProps,
|
|
24
|
+
type ComboBoxListBoxRenderProps,
|
|
25
|
+
type ComboBoxOptionRenderProps,
|
|
26
|
+
} from '@proyecto-viviana/solidaria-components'
|
|
27
|
+
import type { Key, FilterFn, MenuTriggerAction } from '@proyecto-viviana/solid-stately'
|
|
28
|
+
|
|
29
|
+
// ============================================
|
|
30
|
+
// SIZE CONTEXT
|
|
31
|
+
// ============================================
|
|
32
|
+
|
|
33
|
+
export type ComboBoxSize = 'sm' | 'md' | 'lg'
|
|
34
|
+
|
|
35
|
+
const ComboBoxSizeContext = createContext<ComboBoxSize>('md')
|
|
36
|
+
|
|
37
|
+
// ============================================
|
|
38
|
+
// TYPES
|
|
39
|
+
// ============================================
|
|
40
|
+
|
|
41
|
+
export interface ComboBoxProps<T> extends Omit<HeadlessComboBoxProps<T>, 'class' | 'style'> {
|
|
42
|
+
/** The size of the combobox. */
|
|
43
|
+
size?: ComboBoxSize
|
|
44
|
+
/** Additional CSS class name. */
|
|
45
|
+
class?: string
|
|
46
|
+
/** Label for the combobox. */
|
|
47
|
+
label?: string
|
|
48
|
+
/** Description for the combobox. */
|
|
49
|
+
description?: string
|
|
50
|
+
/** Error message when invalid. */
|
|
51
|
+
errorMessage?: string
|
|
52
|
+
/** Whether the combobox is invalid. */
|
|
53
|
+
isInvalid?: boolean
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ComboBoxInputProps extends Omit<HeadlessComboBoxInputProps, 'class' | 'style'> {
|
|
57
|
+
/** Additional CSS class name. */
|
|
58
|
+
class?: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface ComboBoxButtonProps extends Omit<HeadlessComboBoxButtonProps, 'class' | 'style'> {
|
|
62
|
+
/** Additional CSS class name. */
|
|
63
|
+
class?: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ComboBoxListBoxProps<T> extends Omit<HeadlessComboBoxListBoxProps<T>, 'class' | 'style'> {
|
|
67
|
+
/** Additional CSS class name. */
|
|
68
|
+
class?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface ComboBoxOptionProps<T> extends Omit<HeadlessComboBoxOptionProps<T>, 'class' | 'style'> {
|
|
72
|
+
/** Additional CSS class name. */
|
|
73
|
+
class?: string
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ============================================
|
|
77
|
+
// STYLES
|
|
78
|
+
// ============================================
|
|
79
|
+
|
|
80
|
+
const sizeStyles = {
|
|
81
|
+
sm: {
|
|
82
|
+
wrapper: 'h-8',
|
|
83
|
+
input: 'h-8 text-sm pl-3 pr-8',
|
|
84
|
+
button: 'h-8 w-8',
|
|
85
|
+
label: 'text-sm',
|
|
86
|
+
option: 'text-sm py-1.5 px-3',
|
|
87
|
+
icon: 'h-4 w-4',
|
|
88
|
+
},
|
|
89
|
+
md: {
|
|
90
|
+
wrapper: 'h-10',
|
|
91
|
+
input: 'h-10 text-base pl-4 pr-10',
|
|
92
|
+
button: 'h-10 w-10',
|
|
93
|
+
label: 'text-base',
|
|
94
|
+
option: 'text-base py-2 px-4',
|
|
95
|
+
icon: 'h-5 w-5',
|
|
96
|
+
},
|
|
97
|
+
lg: {
|
|
98
|
+
wrapper: 'h-12',
|
|
99
|
+
input: 'h-12 text-lg pl-5 pr-12',
|
|
100
|
+
button: 'h-12 w-12',
|
|
101
|
+
label: 'text-lg',
|
|
102
|
+
option: 'text-lg py-2.5 px-5',
|
|
103
|
+
icon: 'h-6 w-6',
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================
|
|
108
|
+
// COMBOBOX COMPONENT
|
|
109
|
+
// ============================================
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A combobox combines a text input with a listbox, allowing users to filter a list of options.
|
|
113
|
+
*
|
|
114
|
+
* Built on solidaria-components ComboBox for full accessibility support.
|
|
115
|
+
*/
|
|
116
|
+
export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
117
|
+
const [local, headlessProps] = splitProps(props, [
|
|
118
|
+
'size',
|
|
119
|
+
'class',
|
|
120
|
+
'label',
|
|
121
|
+
'description',
|
|
122
|
+
'errorMessage',
|
|
123
|
+
'isInvalid',
|
|
124
|
+
])
|
|
125
|
+
|
|
126
|
+
const size = local.size ?? 'md'
|
|
127
|
+
const customClass = local.class ?? ''
|
|
128
|
+
|
|
129
|
+
const getClassName = (renderProps: ComboBoxRenderProps): string => {
|
|
130
|
+
const base = 'relative inline-flex flex-col gap-1.5'
|
|
131
|
+
const disabledClass = renderProps.isDisabled ? 'opacity-50' : ''
|
|
132
|
+
return [base, disabledClass, customClass].filter(Boolean).join(' ')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<ComboBoxSizeContext.Provider value={size}>
|
|
137
|
+
<HeadlessComboBox
|
|
138
|
+
{...headlessProps}
|
|
139
|
+
class={getClassName}
|
|
140
|
+
>
|
|
141
|
+
<Show when={local.label}>
|
|
142
|
+
<label class={`text-primary-200 font-medium ${sizeStyles[size].label}`}>
|
|
143
|
+
{local.label}
|
|
144
|
+
</label>
|
|
145
|
+
</Show>
|
|
146
|
+
{props.children}
|
|
147
|
+
<Show when={local.description && !local.isInvalid}>
|
|
148
|
+
<span class="text-primary-400 text-sm">{local.description}</span>
|
|
149
|
+
</Show>
|
|
150
|
+
<Show when={local.errorMessage && local.isInvalid}>
|
|
151
|
+
<span class="text-danger-400 text-sm">{local.errorMessage}</span>
|
|
152
|
+
</Show>
|
|
153
|
+
</HeadlessComboBox>
|
|
154
|
+
</ComboBoxSizeContext.Provider>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ============================================
|
|
159
|
+
// COMBOBOX INPUT GROUP COMPONENT
|
|
160
|
+
// ============================================
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A wrapper for the input and button that provides proper styling.
|
|
164
|
+
*/
|
|
165
|
+
export function ComboBoxInputGroup(props: { children: JSX.Element; class?: string }): JSX.Element {
|
|
166
|
+
const size = useContext(ComboBoxSizeContext)
|
|
167
|
+
const styles = () => sizeStyles[size]
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<div class={`relative flex items-center ${styles().wrapper} ${props.class ?? ''}`}>
|
|
171
|
+
{props.children}
|
|
172
|
+
</div>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ============================================
|
|
177
|
+
// COMBOBOX INPUT COMPONENT
|
|
178
|
+
// ============================================
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* The text input for a combobox.
|
|
182
|
+
*/
|
|
183
|
+
export function ComboBoxInput(props: ComboBoxInputProps): JSX.Element {
|
|
184
|
+
const [local, headlessProps] = splitProps(props, ['class'])
|
|
185
|
+
const size = useContext(ComboBoxSizeContext)
|
|
186
|
+
const styles = () => sizeStyles[size]
|
|
187
|
+
const customClass = local.class ?? ''
|
|
188
|
+
|
|
189
|
+
const getClassName = (renderProps: ComboBoxInputRenderProps): string => {
|
|
190
|
+
const base = 'w-full rounded-lg border-2 transition-all duration-200 outline-none'
|
|
191
|
+
const sizeClass = styles().input
|
|
192
|
+
|
|
193
|
+
let colorClass: string
|
|
194
|
+
if (renderProps.isDisabled) {
|
|
195
|
+
colorClass = 'border-bg-300 bg-bg-200 text-primary-500 cursor-not-allowed'
|
|
196
|
+
} else if (renderProps.isOpen) {
|
|
197
|
+
colorClass = 'border-accent bg-bg-300 text-primary-100'
|
|
198
|
+
} else if (renderProps.isHovered) {
|
|
199
|
+
colorClass = 'border-accent-300 bg-bg-300 text-primary-100'
|
|
200
|
+
} else {
|
|
201
|
+
colorClass = 'border-primary-600 bg-bg-400 text-primary-200'
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const focusClass = renderProps.isFocusVisible
|
|
205
|
+
? 'ring-2 ring-accent-300 ring-offset-2 ring-offset-bg-400'
|
|
206
|
+
: ''
|
|
207
|
+
|
|
208
|
+
return [base, sizeClass, colorClass, focusClass, customClass].filter(Boolean).join(' ')
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<HeadlessComboBoxInput
|
|
213
|
+
{...headlessProps}
|
|
214
|
+
class={getClassName}
|
|
215
|
+
/>
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ============================================
|
|
220
|
+
// COMBOBOX BUTTON COMPONENT
|
|
221
|
+
// ============================================
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* The trigger button for a combobox.
|
|
225
|
+
* SSR-compatible - renders children or chevron icon directly without render props.
|
|
226
|
+
*/
|
|
227
|
+
export function ComboBoxButton(props: ComboBoxButtonProps): JSX.Element {
|
|
228
|
+
const [local, headlessProps] = splitProps(props, ['class'])
|
|
229
|
+
const size = useContext(ComboBoxSizeContext)
|
|
230
|
+
const sizeStyle = sizeStyles[size]
|
|
231
|
+
const customClass = local.class ?? ''
|
|
232
|
+
|
|
233
|
+
const getClassName = (renderProps: ComboBoxButtonRenderProps): string => {
|
|
234
|
+
const base = 'absolute right-0 top-0 flex items-center justify-center transition-all duration-200 rounded-r-lg'
|
|
235
|
+
const sizeClass = sizeStyle.button
|
|
236
|
+
|
|
237
|
+
let colorClass: string
|
|
238
|
+
if (renderProps.isDisabled) {
|
|
239
|
+
colorClass = 'text-primary-500 cursor-not-allowed'
|
|
240
|
+
} else if (renderProps.isOpen) {
|
|
241
|
+
colorClass = 'text-accent'
|
|
242
|
+
} else if (renderProps.isHovered) {
|
|
243
|
+
colorClass = 'text-accent-300 cursor-pointer'
|
|
244
|
+
} else {
|
|
245
|
+
colorClass = 'text-primary-400 cursor-pointer hover:text-primary-200'
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return [base, sizeClass, colorClass, customClass].filter(Boolean).join(' ')
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<HeadlessComboBoxButton
|
|
253
|
+
{...headlessProps}
|
|
254
|
+
class={getClassName}
|
|
255
|
+
>
|
|
256
|
+
{props.children || <ChevronIcon class={`${sizeStyle.icon} transition-transform duration-200 data-open:rotate-180`} />}
|
|
257
|
+
</HeadlessComboBoxButton>
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ============================================
|
|
262
|
+
// COMBOBOX LISTBOX COMPONENT
|
|
263
|
+
// ============================================
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* The listbox popup for a combobox.
|
|
267
|
+
*/
|
|
268
|
+
export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element {
|
|
269
|
+
const [local, headlessProps] = splitProps(props, ['class'])
|
|
270
|
+
const customClass = local.class ?? ''
|
|
271
|
+
|
|
272
|
+
const getClassName = (_renderProps: ComboBoxListBoxRenderProps): string => {
|
|
273
|
+
const base = 'absolute z-50 mt-1 w-full rounded-lg border-2 border-primary-600 bg-bg-400 py-1 shadow-lg max-h-60 overflow-auto'
|
|
274
|
+
return [base, customClass].filter(Boolean).join(' ')
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
<HeadlessComboBoxListBox
|
|
279
|
+
{...headlessProps}
|
|
280
|
+
class={getClassName}
|
|
281
|
+
children={props.children}
|
|
282
|
+
/>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ============================================
|
|
287
|
+
// COMBOBOX OPTION COMPONENT
|
|
288
|
+
// ============================================
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* An option in a combobox listbox.
|
|
292
|
+
* SSR-compatible - renders check icon and content directly without render props.
|
|
293
|
+
*/
|
|
294
|
+
export function ComboBoxOption<T>(props: ComboBoxOptionProps<T>): JSX.Element {
|
|
295
|
+
const [local, headlessProps] = splitProps(props, ['class'])
|
|
296
|
+
const size = useContext(ComboBoxSizeContext)
|
|
297
|
+
const sizeStyle = sizeStyles[size]
|
|
298
|
+
const customClass = local.class ?? ''
|
|
299
|
+
|
|
300
|
+
const getClassName = (renderProps: ComboBoxOptionRenderProps): string => {
|
|
301
|
+
const base = 'flex items-center gap-2 cursor-pointer transition-colors duration-150'
|
|
302
|
+
const sizeClass = sizeStyle.option
|
|
303
|
+
|
|
304
|
+
let colorClass: string
|
|
305
|
+
if (renderProps.isDisabled) {
|
|
306
|
+
colorClass = 'text-primary-500 cursor-not-allowed'
|
|
307
|
+
} else if (renderProps.isSelected) {
|
|
308
|
+
colorClass = 'bg-accent/20 text-accent'
|
|
309
|
+
} else if (renderProps.isFocused || renderProps.isHovered) {
|
|
310
|
+
colorClass = 'bg-bg-300 text-primary-100'
|
|
311
|
+
} else {
|
|
312
|
+
colorClass = 'text-primary-200'
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const focusClass = renderProps.isFocusVisible
|
|
316
|
+
? 'ring-2 ring-inset ring-accent-300'
|
|
317
|
+
: ''
|
|
318
|
+
|
|
319
|
+
return [base, sizeClass, colorClass, focusClass, customClass].filter(Boolean).join(' ')
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Compute padding for non-selected items to align with check icon
|
|
323
|
+
const iconPadding: Record<ComboBoxSize, string> = {
|
|
324
|
+
sm: 'pl-6', // h-4 icon + gap
|
|
325
|
+
md: 'pl-7', // h-5 icon + gap
|
|
326
|
+
lg: 'pl-8', // h-6 icon + gap
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
<HeadlessComboBoxOption
|
|
331
|
+
{...headlessProps}
|
|
332
|
+
class={getClassName}
|
|
333
|
+
>
|
|
334
|
+
<CheckIcon class={`${sizeStyle.icon} text-accent shrink-0 hidden data-selected:block`} />
|
|
335
|
+
<span class={`flex-1 data-selected:pl-0 ${iconPadding[size]}`}>
|
|
336
|
+
{props.children as JSX.Element}
|
|
337
|
+
</span>
|
|
338
|
+
</HeadlessComboBoxOption>
|
|
339
|
+
)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// ============================================
|
|
343
|
+
// ICONS
|
|
344
|
+
// ============================================
|
|
345
|
+
|
|
346
|
+
function ChevronIcon(props: { class?: string }): JSX.Element {
|
|
347
|
+
return (
|
|
348
|
+
<svg
|
|
349
|
+
class={props.class}
|
|
350
|
+
fill="none"
|
|
351
|
+
viewBox="0 0 24 24"
|
|
352
|
+
stroke="currentColor"
|
|
353
|
+
stroke-width="2"
|
|
354
|
+
>
|
|
355
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
|
|
356
|
+
</svg>
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function CheckIcon(props: { class?: string }): JSX.Element {
|
|
361
|
+
return (
|
|
362
|
+
<svg
|
|
363
|
+
class={props.class}
|
|
364
|
+
fill="none"
|
|
365
|
+
viewBox="0 0 24 24"
|
|
366
|
+
stroke="currentColor"
|
|
367
|
+
stroke-width="2"
|
|
368
|
+
>
|
|
369
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
370
|
+
</svg>
|
|
371
|
+
)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Attach sub-components for convenience
|
|
375
|
+
ComboBox.InputGroup = ComboBoxInputGroup
|
|
376
|
+
ComboBox.Input = ComboBoxInput
|
|
377
|
+
ComboBox.Button = ComboBoxButton
|
|
378
|
+
ComboBox.ListBox = ComboBoxListBox
|
|
379
|
+
ComboBox.Option = ComboBoxOption
|
|
380
|
+
|
|
381
|
+
// Re-export types and utilities for convenience
|
|
382
|
+
export type { Key, FilterFn, MenuTriggerAction }
|
|
383
|
+
export { defaultContainsFilter }
|