@proyecto-viviana/ui 0.2.5 → 0.3.1
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/index.js +210 -557
- package/dist/index.js.map +7 -1
- package/dist/index.ssr.js +42 -399
- package/dist/index.ssr.js.map +7 -1
- package/dist/radio/index.d.ts +27 -12
- package/dist/radio/index.d.ts.map +1 -1
- package/package.json +11 -12
- package/src/alert/index.tsx +0 -48
- package/src/assets/favicon.png +0 -0
- package/src/assets/fire.gif +0 -0
- package/src/autocomplete/index.tsx +0 -313
- package/src/avatar/index.tsx +0 -75
- package/src/badge/index.tsx +0 -43
- package/src/breadcrumbs/index.tsx +0 -207
- package/src/button/Button.tsx +0 -74
- package/src/button/index.ts +0 -2
- package/src/button/types.ts +0 -24
- package/src/calendar/DateField.tsx +0 -200
- package/src/calendar/DatePicker.tsx +0 -298
- package/src/calendar/RangeCalendar.tsx +0 -236
- package/src/calendar/TimeField.tsx +0 -196
- package/src/calendar/index.tsx +0 -223
- package/src/checkbox/index.tsx +0 -257
- package/src/color/index.tsx +0 -687
- package/src/combobox/index.tsx +0 -383
- package/src/components.css +0 -1077
- package/src/custom/calendar-card/index.tsx +0 -66
- package/src/custom/chip/index.tsx +0 -46
- package/src/custom/conversation/index.tsx +0 -105
- package/src/custom/event-card/index.tsx +0 -132
- package/src/custom/header/index.tsx +0 -33
- package/src/custom/lateral-nav/index.tsx +0 -88
- package/src/custom/logo/index.tsx +0 -58
- package/src/custom/nav-header/index.tsx +0 -42
- package/src/custom/page-layout/index.tsx +0 -29
- package/src/custom/profile-card/index.tsx +0 -64
- package/src/custom/project-card/index.tsx +0 -59
- package/src/custom/timeline-item/index.tsx +0 -105
- package/src/dialog/Dialog.tsx +0 -260
- package/src/dialog/index.tsx +0 -3
- package/src/disclosure/index.tsx +0 -307
- package/src/gridlist/index.tsx +0 -403
- package/src/icon/icons/GitHubIcon.tsx +0 -20
- package/src/icon/index.tsx +0 -48
- package/src/index.ts +0 -322
- package/src/landmark/index.tsx +0 -231
- package/src/link/index.tsx +0 -130
- package/src/listbox/index.tsx +0 -231
- package/src/menu/index.tsx +0 -297
- package/src/meter/index.tsx +0 -163
- package/src/numberfield/index.tsx +0 -482
- package/src/popover/index.tsx +0 -260
- package/src/progress-bar/index.tsx +0 -169
- package/src/radio/index.tsx +0 -173
- package/src/searchfield/index.tsx +0 -453
- package/src/select/index.tsx +0 -349
- package/src/separator/index.tsx +0 -141
- package/src/slider/index.tsx +0 -382
- package/src/styles.css +0 -450
- package/src/switch/ToggleSwitch.tsx +0 -112
- package/src/switch/index.tsx +0 -90
- package/src/table/index.tsx +0 -531
- package/src/tabs/index.tsx +0 -273
- package/src/tag-group/index.tsx +0 -240
- package/src/test-utils/index.ts +0 -32
- package/src/textfield/index.tsx +0 -211
- package/src/theme.css +0 -101
- package/src/toast/index.tsx +0 -324
- package/src/toolbar/index.tsx +0 -108
- package/src/tooltip/index.tsx +0 -197
- package/src/tree/index.tsx +0 -494
|
@@ -1,453 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SearchField component for proyecto-viviana-ui
|
|
3
|
-
*
|
|
4
|
-
* A styled search field component with clear button and search icon.
|
|
5
|
-
* Built directly on solidaria hooks for full accessibility support.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { type JSX, splitProps, mergeProps as solidMergeProps, Show } from 'solid-js'
|
|
9
|
-
import {
|
|
10
|
-
createSearchField,
|
|
11
|
-
createFocusRing,
|
|
12
|
-
createPress,
|
|
13
|
-
createHover,
|
|
14
|
-
type AriaSearchFieldProps,
|
|
15
|
-
} from '@proyecto-viviana/solidaria'
|
|
16
|
-
import {
|
|
17
|
-
createSearchFieldState,
|
|
18
|
-
} from '@proyecto-viviana/solid-stately'
|
|
19
|
-
|
|
20
|
-
// ============================================
|
|
21
|
-
// TYPES
|
|
22
|
-
// ============================================
|
|
23
|
-
|
|
24
|
-
export type SearchFieldSize = 'sm' | 'md' | 'lg'
|
|
25
|
-
export type SearchFieldVariant = 'outline' | 'filled'
|
|
26
|
-
|
|
27
|
-
export interface SearchFieldProps extends Omit<AriaSearchFieldProps, 'label'> {
|
|
28
|
-
/** The size of the search field. */
|
|
29
|
-
size?: SearchFieldSize
|
|
30
|
-
/** The visual variant of the search field. */
|
|
31
|
-
variant?: SearchFieldVariant
|
|
32
|
-
/** Additional CSS class name. */
|
|
33
|
-
class?: string
|
|
34
|
-
/** Label text for the input. */
|
|
35
|
-
label?: string
|
|
36
|
-
/** Description text shown below the input. */
|
|
37
|
-
description?: string
|
|
38
|
-
/** Error message shown when invalid. */
|
|
39
|
-
errorMessage?: string
|
|
40
|
-
/** The current value (controlled). */
|
|
41
|
-
value?: string
|
|
42
|
-
/** The default value (uncontrolled). */
|
|
43
|
-
defaultValue?: string
|
|
44
|
-
/** Handler called when the value changes. */
|
|
45
|
-
onChange?: (value: string) => void
|
|
46
|
-
/** Handler called when the user submits the search. */
|
|
47
|
-
onSubmit?: (value: string) => void
|
|
48
|
-
/** Handler called when the field is cleared. */
|
|
49
|
-
onClear?: () => void
|
|
50
|
-
/** Whether to hide the search icon. */
|
|
51
|
-
hideSearchIcon?: boolean
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ============================================
|
|
55
|
-
// STYLES
|
|
56
|
-
// ============================================
|
|
57
|
-
|
|
58
|
-
const sizeStyles = {
|
|
59
|
-
sm: {
|
|
60
|
-
container: 'h-8',
|
|
61
|
-
input: 'text-sm pl-8 pr-8',
|
|
62
|
-
label: 'text-sm',
|
|
63
|
-
description: 'text-xs',
|
|
64
|
-
icon: 'w-4 h-4 left-2',
|
|
65
|
-
clearButton: 'w-5 h-5 right-1.5',
|
|
66
|
-
},
|
|
67
|
-
md: {
|
|
68
|
-
container: 'h-10',
|
|
69
|
-
input: 'text-base pl-10 pr-10',
|
|
70
|
-
label: 'text-sm',
|
|
71
|
-
description: 'text-sm',
|
|
72
|
-
icon: 'w-5 h-5 left-2.5',
|
|
73
|
-
clearButton: 'w-6 h-6 right-2',
|
|
74
|
-
},
|
|
75
|
-
lg: {
|
|
76
|
-
container: 'h-12',
|
|
77
|
-
input: 'text-lg pl-12 pr-12',
|
|
78
|
-
label: 'text-base',
|
|
79
|
-
description: 'text-sm',
|
|
80
|
-
icon: 'w-6 h-6 left-3',
|
|
81
|
-
clearButton: 'w-7 h-7 right-2.5',
|
|
82
|
-
},
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ============================================
|
|
86
|
-
// ICONS
|
|
87
|
-
// ============================================
|
|
88
|
-
|
|
89
|
-
function SearchIcon(props: { class?: string }) {
|
|
90
|
-
return (
|
|
91
|
-
<svg
|
|
92
|
-
class={props.class}
|
|
93
|
-
viewBox="0 0 20 20"
|
|
94
|
-
fill="none"
|
|
95
|
-
stroke="currentColor"
|
|
96
|
-
stroke-width="2"
|
|
97
|
-
>
|
|
98
|
-
<circle cx="8" cy="8" r="5" />
|
|
99
|
-
<path d="M12 12L17 17" stroke-linecap="round" />
|
|
100
|
-
</svg>
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function ClearIcon(props: { class?: string }) {
|
|
105
|
-
return (
|
|
106
|
-
<svg
|
|
107
|
-
class={props.class}
|
|
108
|
-
viewBox="0 0 16 16"
|
|
109
|
-
fill="none"
|
|
110
|
-
stroke="currentColor"
|
|
111
|
-
stroke-width="2"
|
|
112
|
-
>
|
|
113
|
-
<path d="M4 4L12 12M12 4L4 12" stroke-linecap="round" />
|
|
114
|
-
</svg>
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ============================================
|
|
119
|
-
// COMPONENT
|
|
120
|
-
// ============================================
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* A search field allows users to enter and clear a search query.
|
|
124
|
-
*
|
|
125
|
-
* Built directly on solidaria hooks for full accessibility support.
|
|
126
|
-
*/
|
|
127
|
-
export function SearchField(props: SearchFieldProps): JSX.Element {
|
|
128
|
-
const defaultProps: Partial<SearchFieldProps> = {
|
|
129
|
-
size: 'md',
|
|
130
|
-
variant: 'outline',
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const merged = solidMergeProps(defaultProps, props)
|
|
134
|
-
|
|
135
|
-
const [local, stateProps, ariaProps] = splitProps(merged, [
|
|
136
|
-
'size',
|
|
137
|
-
'variant',
|
|
138
|
-
'class',
|
|
139
|
-
'label',
|
|
140
|
-
'description',
|
|
141
|
-
'errorMessage',
|
|
142
|
-
'hideSearchIcon',
|
|
143
|
-
], [
|
|
144
|
-
'value',
|
|
145
|
-
'defaultValue',
|
|
146
|
-
'onChange',
|
|
147
|
-
'onSubmit',
|
|
148
|
-
'onClear',
|
|
149
|
-
])
|
|
150
|
-
|
|
151
|
-
const size = () => sizeStyles[local.size!]
|
|
152
|
-
|
|
153
|
-
// Ref for input element
|
|
154
|
-
let inputRef: HTMLInputElement | undefined
|
|
155
|
-
|
|
156
|
-
// Create search field state
|
|
157
|
-
const state = createSearchFieldState({
|
|
158
|
-
get value() {
|
|
159
|
-
return stateProps.value
|
|
160
|
-
},
|
|
161
|
-
get defaultValue() {
|
|
162
|
-
return stateProps.defaultValue
|
|
163
|
-
},
|
|
164
|
-
get onChange() {
|
|
165
|
-
return stateProps.onChange
|
|
166
|
-
},
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
// Create search field aria props
|
|
170
|
-
const searchFieldAria = createSearchField(
|
|
171
|
-
{
|
|
172
|
-
get label() {
|
|
173
|
-
return local.label
|
|
174
|
-
},
|
|
175
|
-
get 'aria-label'() {
|
|
176
|
-
return ariaProps['aria-label']
|
|
177
|
-
},
|
|
178
|
-
get 'aria-labelledby'() {
|
|
179
|
-
return ariaProps['aria-labelledby']
|
|
180
|
-
},
|
|
181
|
-
get 'aria-describedby'() {
|
|
182
|
-
return ariaProps['aria-describedby']
|
|
183
|
-
},
|
|
184
|
-
get isDisabled() {
|
|
185
|
-
return ariaProps.isDisabled
|
|
186
|
-
},
|
|
187
|
-
get isReadOnly() {
|
|
188
|
-
return ariaProps.isReadOnly
|
|
189
|
-
},
|
|
190
|
-
get isRequired() {
|
|
191
|
-
return ariaProps.isRequired
|
|
192
|
-
},
|
|
193
|
-
get isInvalid() {
|
|
194
|
-
return ariaProps.isInvalid
|
|
195
|
-
},
|
|
196
|
-
get description() {
|
|
197
|
-
return local.description
|
|
198
|
-
},
|
|
199
|
-
get errorMessage() {
|
|
200
|
-
return local.errorMessage
|
|
201
|
-
},
|
|
202
|
-
get placeholder() {
|
|
203
|
-
return ariaProps.placeholder
|
|
204
|
-
},
|
|
205
|
-
get name() {
|
|
206
|
-
return ariaProps.name
|
|
207
|
-
},
|
|
208
|
-
get autoFocus() {
|
|
209
|
-
return ariaProps.autoFocus
|
|
210
|
-
},
|
|
211
|
-
get autoComplete() {
|
|
212
|
-
return ariaProps.autoComplete
|
|
213
|
-
},
|
|
214
|
-
get maxLength() {
|
|
215
|
-
return ariaProps.maxLength
|
|
216
|
-
},
|
|
217
|
-
get minLength() {
|
|
218
|
-
return ariaProps.minLength
|
|
219
|
-
},
|
|
220
|
-
get pattern() {
|
|
221
|
-
return ariaProps.pattern
|
|
222
|
-
},
|
|
223
|
-
get onSubmit() {
|
|
224
|
-
return stateProps.onSubmit
|
|
225
|
-
},
|
|
226
|
-
get onClear() {
|
|
227
|
-
return stateProps.onClear
|
|
228
|
-
},
|
|
229
|
-
},
|
|
230
|
-
state,
|
|
231
|
-
() => inputRef ?? null
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
// Create focus ring for input
|
|
235
|
-
const { isFocused, isFocusVisible, focusProps } = createFocusRing()
|
|
236
|
-
|
|
237
|
-
// Create hover for input
|
|
238
|
-
const { isHovered, hoverProps } = createHover({
|
|
239
|
-
get isDisabled() {
|
|
240
|
-
return ariaProps.isDisabled
|
|
241
|
-
},
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
// Clear button interactions
|
|
245
|
-
const { isPressed: clearPressed, pressProps: clearPressProps } = createPress({
|
|
246
|
-
get isDisabled() {
|
|
247
|
-
return ariaProps.isDisabled || ariaProps.isReadOnly
|
|
248
|
-
},
|
|
249
|
-
onPress: () => {
|
|
250
|
-
searchFieldAria.clearButtonProps.onClick()
|
|
251
|
-
},
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
const { isHovered: clearHovered, hoverProps: clearHoverProps } = createHover({
|
|
255
|
-
get isDisabled() {
|
|
256
|
-
return ariaProps.isDisabled || ariaProps.isReadOnly
|
|
257
|
-
},
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
// Compute classes
|
|
261
|
-
const containerClasses = () => {
|
|
262
|
-
const base = 'flex flex-col'
|
|
263
|
-
const disabledClass = ariaProps.isDisabled ? 'opacity-60' : ''
|
|
264
|
-
const custom = local.class || ''
|
|
265
|
-
return [base, disabledClass, custom].filter(Boolean).join(' ')
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const inputWrapperClasses = () => {
|
|
269
|
-
const base = 'relative flex items-center'
|
|
270
|
-
const sizeClass = size().container
|
|
271
|
-
return [base, sizeClass].filter(Boolean).join(' ')
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const inputClasses = () => {
|
|
275
|
-
const base = 'w-full h-full rounded-md transition-all duration-200 outline-none'
|
|
276
|
-
const sizeClass = size().input
|
|
277
|
-
|
|
278
|
-
// Adjust padding based on search icon visibility
|
|
279
|
-
const paddingClass = local.hideSearchIcon ? 'pl-3' : ''
|
|
280
|
-
|
|
281
|
-
let variantClass: string
|
|
282
|
-
if (local.variant === 'filled') {
|
|
283
|
-
variantClass = 'bg-bg-200 border border-transparent'
|
|
284
|
-
} else {
|
|
285
|
-
variantClass = 'bg-transparent border border-bg-400'
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
let stateClass: string
|
|
289
|
-
if (ariaProps.isDisabled) {
|
|
290
|
-
stateClass = 'bg-bg-200 text-primary-500 cursor-not-allowed'
|
|
291
|
-
} else if (ariaProps.isInvalid) {
|
|
292
|
-
stateClass = 'border-danger-500 focus:border-danger-400 focus:ring-2 focus:ring-danger-400/20'
|
|
293
|
-
} else {
|
|
294
|
-
stateClass = 'text-primary-100 placeholder:text-primary-500 focus:border-accent focus:ring-2 focus:ring-accent/20'
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
const hoverClass = ariaProps.isDisabled ? '' : 'hover:border-accent-300'
|
|
298
|
-
|
|
299
|
-
return [base, sizeClass, paddingClass, variantClass, stateClass, hoverClass].filter(Boolean).join(' ')
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const searchIconClasses = () => {
|
|
303
|
-
const base = 'absolute pointer-events-none text-primary-400'
|
|
304
|
-
const sizeClass = size().icon
|
|
305
|
-
const focusedClass = isFocused() ? 'text-accent' : ''
|
|
306
|
-
return [base, sizeClass, focusedClass].filter(Boolean).join(' ')
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const clearButtonClasses = () => {
|
|
310
|
-
const base = 'absolute flex items-center justify-center rounded-md transition-all duration-150 select-none'
|
|
311
|
-
const sizeClass = size().clearButton
|
|
312
|
-
|
|
313
|
-
const isDisabled = ariaProps.isDisabled || ariaProps.isReadOnly
|
|
314
|
-
|
|
315
|
-
let stateClass: string
|
|
316
|
-
if (isDisabled) {
|
|
317
|
-
stateClass = 'text-primary-600 cursor-not-allowed'
|
|
318
|
-
} else if (clearPressed()) {
|
|
319
|
-
stateClass = 'bg-bg-400 text-primary-100 scale-90'
|
|
320
|
-
} else if (clearHovered()) {
|
|
321
|
-
stateClass = 'bg-bg-300 text-primary-100'
|
|
322
|
-
} else {
|
|
323
|
-
stateClass = 'text-primary-400 hover:bg-bg-300 hover:text-primary-100'
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
return [base, sizeClass, stateClass].filter(Boolean).join(' ')
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const labelClasses = () => {
|
|
330
|
-
const base = 'block font-medium text-primary-200 mb-1'
|
|
331
|
-
const sizeClass = size().label
|
|
332
|
-
return [base, sizeClass].filter(Boolean).join(' ')
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const descriptionClasses = () => {
|
|
336
|
-
const base = 'mt-1 text-primary-400'
|
|
337
|
-
const sizeClass = size().description
|
|
338
|
-
return [base, sizeClass].filter(Boolean).join(' ')
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
const errorClasses = () => {
|
|
342
|
-
const base = 'mt-1 text-danger-500'
|
|
343
|
-
const sizeClass = size().description
|
|
344
|
-
return [base, sizeClass].filter(Boolean).join(' ')
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// Clean props helpers
|
|
348
|
-
const cleanInputProps = () => {
|
|
349
|
-
const { ref: _ref, ...rest } = searchFieldAria.inputProps as Record<string, unknown>
|
|
350
|
-
return rest
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
const cleanFocusProps = () => {
|
|
354
|
-
const { ref: _ref, ...rest } = focusProps as Record<string, unknown>
|
|
355
|
-
return rest
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const cleanHoverProps = () => {
|
|
359
|
-
const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>
|
|
360
|
-
return rest
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const cleanLabelProps = () => {
|
|
364
|
-
const { ref: _ref, ...rest } = searchFieldAria.labelProps as Record<string, unknown>
|
|
365
|
-
return rest
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const cleanClearPressProps = () => {
|
|
369
|
-
const { ref: _ref, ...rest } = clearPressProps as Record<string, unknown>
|
|
370
|
-
return rest
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const cleanClearHoverProps = () => {
|
|
374
|
-
const { ref: _ref, ...rest } = clearHoverProps as Record<string, unknown>
|
|
375
|
-
return rest
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
const isEmpty = () => state.value() === ''
|
|
379
|
-
|
|
380
|
-
return (
|
|
381
|
-
<div
|
|
382
|
-
class={containerClasses()}
|
|
383
|
-
data-empty={isEmpty() || undefined}
|
|
384
|
-
data-disabled={ariaProps.isDisabled || undefined}
|
|
385
|
-
data-invalid={ariaProps.isInvalid || undefined}
|
|
386
|
-
>
|
|
387
|
-
{/* Label */}
|
|
388
|
-
<Show when={local.label}>
|
|
389
|
-
<span {...cleanLabelProps()} class={labelClasses()}>
|
|
390
|
-
{local.label}
|
|
391
|
-
<Show when={ariaProps.isRequired}>
|
|
392
|
-
<span class="text-danger-500 ml-1">*</span>
|
|
393
|
-
</Show>
|
|
394
|
-
</span>
|
|
395
|
-
</Show>
|
|
396
|
-
|
|
397
|
-
{/* Input Wrapper */}
|
|
398
|
-
<div class={inputWrapperClasses()}>
|
|
399
|
-
{/* Search Icon */}
|
|
400
|
-
<Show when={!local.hideSearchIcon}>
|
|
401
|
-
<SearchIcon class={searchIconClasses()} />
|
|
402
|
-
</Show>
|
|
403
|
-
|
|
404
|
-
{/* Input */}
|
|
405
|
-
<input
|
|
406
|
-
ref={inputRef}
|
|
407
|
-
{...cleanInputProps()}
|
|
408
|
-
{...cleanFocusProps()}
|
|
409
|
-
{...cleanHoverProps()}
|
|
410
|
-
class={inputClasses()}
|
|
411
|
-
data-focused={isFocused() || undefined}
|
|
412
|
-
data-focus-visible={isFocusVisible() || undefined}
|
|
413
|
-
data-hovered={isHovered() || undefined}
|
|
414
|
-
/>
|
|
415
|
-
|
|
416
|
-
{/* Clear Button */}
|
|
417
|
-
<Show when={!isEmpty()}>
|
|
418
|
-
<button
|
|
419
|
-
type="button"
|
|
420
|
-
aria-label={searchFieldAria.clearButtonProps['aria-label']}
|
|
421
|
-
tabIndex={searchFieldAria.clearButtonProps.tabIndex}
|
|
422
|
-
disabled={searchFieldAria.clearButtonProps.disabled}
|
|
423
|
-
onMouseDown={searchFieldAria.clearButtonProps.onMouseDown}
|
|
424
|
-
{...cleanClearPressProps()}
|
|
425
|
-
{...cleanClearHoverProps()}
|
|
426
|
-
class={clearButtonClasses()}
|
|
427
|
-
data-pressed={clearPressed() || undefined}
|
|
428
|
-
data-hovered={clearHovered() || undefined}
|
|
429
|
-
>
|
|
430
|
-
<ClearIcon class="w-3 h-3" />
|
|
431
|
-
</button>
|
|
432
|
-
</Show>
|
|
433
|
-
</div>
|
|
434
|
-
|
|
435
|
-
{/* Description */}
|
|
436
|
-
<Show when={local.description && !ariaProps.isInvalid}>
|
|
437
|
-
<span {...searchFieldAria.descriptionProps} class={descriptionClasses()}>
|
|
438
|
-
{local.description}
|
|
439
|
-
</span>
|
|
440
|
-
</Show>
|
|
441
|
-
|
|
442
|
-
{/* Error Message */}
|
|
443
|
-
<Show when={ariaProps.isInvalid && local.errorMessage}>
|
|
444
|
-
<span {...searchFieldAria.errorMessageProps} class={errorClasses()}>
|
|
445
|
-
{local.errorMessage}
|
|
446
|
-
</span>
|
|
447
|
-
</Show>
|
|
448
|
-
</div>
|
|
449
|
-
)
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Re-export types
|
|
453
|
-
export type { SearchFieldState } from '@proyecto-viviana/solid-stately'
|