@proyecto-viviana/solidaria-components 0.1.2 → 0.2.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.
Files changed (62) hide show
  1. package/dist/Color.d.ts +6 -2
  2. package/dist/Color.d.ts.map +1 -1
  3. package/dist/ComboBox.d.ts +3 -3
  4. package/dist/ComboBox.d.ts.map +1 -1
  5. package/dist/GridList.d.ts +2 -2
  6. package/dist/GridList.d.ts.map +1 -1
  7. package/dist/ListBox.d.ts +5 -5
  8. package/dist/ListBox.d.ts.map +1 -1
  9. package/dist/Menu.d.ts +3 -3
  10. package/dist/Menu.d.ts.map +1 -1
  11. package/dist/Select.d.ts +3 -3
  12. package/dist/Select.d.ts.map +1 -1
  13. package/dist/Table.d.ts +2 -2
  14. package/dist/Table.d.ts.map +1 -1
  15. package/dist/Tabs.d.ts +1 -1
  16. package/dist/Tabs.d.ts.map +1 -1
  17. package/dist/index.js +15 -15
  18. package/dist/index.js.map +2 -2
  19. package/dist/index.ssr.js +15 -15
  20. package/dist/index.ssr.js.map +2 -2
  21. package/package.json +8 -9
  22. package/src/Autocomplete.tsx +0 -174
  23. package/src/Breadcrumbs.tsx +0 -264
  24. package/src/Button.tsx +0 -238
  25. package/src/Calendar.tsx +0 -471
  26. package/src/Checkbox.tsx +0 -387
  27. package/src/Color.tsx +0 -1370
  28. package/src/ComboBox.tsx +0 -824
  29. package/src/DateField.tsx +0 -337
  30. package/src/DatePicker.tsx +0 -367
  31. package/src/Dialog.tsx +0 -262
  32. package/src/Disclosure.tsx +0 -439
  33. package/src/GridList.tsx +0 -511
  34. package/src/Landmark.tsx +0 -203
  35. package/src/Link.tsx +0 -201
  36. package/src/ListBox.tsx +0 -346
  37. package/src/Menu.tsx +0 -544
  38. package/src/Meter.tsx +0 -157
  39. package/src/Modal.tsx +0 -433
  40. package/src/NumberField.tsx +0 -542
  41. package/src/Popover.tsx +0 -540
  42. package/src/ProgressBar.tsx +0 -162
  43. package/src/RadioGroup.tsx +0 -356
  44. package/src/RangeCalendar.tsx +0 -462
  45. package/src/SearchField.tsx +0 -479
  46. package/src/Select.tsx +0 -734
  47. package/src/Separator.tsx +0 -130
  48. package/src/Slider.tsx +0 -500
  49. package/src/Switch.tsx +0 -213
  50. package/src/Table.tsx +0 -857
  51. package/src/Tabs.tsx +0 -552
  52. package/src/TagGroup.tsx +0 -421
  53. package/src/TextField.tsx +0 -271
  54. package/src/TimeField.tsx +0 -455
  55. package/src/Toast.tsx +0 -503
  56. package/src/Toolbar.tsx +0 -160
  57. package/src/Tooltip.tsx +0 -423
  58. package/src/Tree.tsx +0 -551
  59. package/src/VisuallyHidden.tsx +0 -60
  60. package/src/contexts.ts +0 -74
  61. package/src/index.ts +0 -620
  62. package/src/utils.tsx +0 -329
@@ -1,479 +0,0 @@
1
- /**
2
- * SearchField component for solidaria-components
3
- *
4
- * A pre-wired headless search field that combines state + aria hooks.
5
- * Port of react-aria-components/src/SearchField.tsx
6
- */
7
-
8
- import {
9
- type JSX,
10
- createContext,
11
- createMemo,
12
- splitProps,
13
- useContext,
14
- Show,
15
- } from 'solid-js';
16
- import {
17
- createSearchField,
18
- createFocusRing,
19
- createHover,
20
- createPress,
21
- type AriaSearchFieldProps,
22
- } from '@proyecto-viviana/solidaria';
23
- import {
24
- createSearchFieldState,
25
- type SearchFieldState,
26
- } from '@proyecto-viviana/solid-stately';
27
- import {
28
- type RenderChildren,
29
- type ClassNameOrFunction,
30
- type StyleOrFunction,
31
- type SlotProps,
32
- useRenderProps,
33
- filterDOMProps,
34
- } from './utils';
35
-
36
- // ============================================
37
- // TYPES
38
- // ============================================
39
-
40
- export interface SearchFieldRenderProps {
41
- /** Whether the search field is empty. */
42
- isEmpty: boolean;
43
- /** Whether the search field is disabled. */
44
- isDisabled: boolean;
45
- /** Whether the search field is invalid. */
46
- isInvalid: boolean;
47
- /** Whether the search field is read-only. */
48
- isReadOnly: boolean;
49
- /** Whether the search field is required. */
50
- isRequired: boolean;
51
- /** The current value. */
52
- value: string;
53
- }
54
-
55
- export interface SearchFieldProps extends Omit<AriaSearchFieldProps, 'label'>, SlotProps {
56
- /** The current value (controlled). */
57
- value?: string;
58
- /** The default value (uncontrolled). */
59
- defaultValue?: string;
60
- /** Handler called when the value changes. */
61
- onChange?: (value: string) => void;
62
- /** Handler called when the user submits the search. */
63
- onSubmit?: (value: string) => void;
64
- /** Handler called when the field is cleared. */
65
- onClear?: () => void;
66
- /** A visible label for the search field. */
67
- label?: JSX.Element;
68
- /** The children of the component. */
69
- children?: RenderChildren<SearchFieldRenderProps>;
70
- /** The CSS className for the element. */
71
- class?: ClassNameOrFunction<SearchFieldRenderProps>;
72
- /** The inline style for the element. */
73
- style?: StyleOrFunction<SearchFieldRenderProps>;
74
- }
75
-
76
- export interface SearchFieldInputRenderProps {
77
- /** Whether the input is focused. */
78
- isFocused: boolean;
79
- /** Whether the input has keyboard focus. */
80
- isFocusVisible: boolean;
81
- /** Whether the input is hovered. */
82
- isHovered: boolean;
83
- /** Whether the input is disabled. */
84
- isDisabled: boolean;
85
- /** Whether the input is invalid. */
86
- isInvalid: boolean;
87
- }
88
-
89
- export interface SearchFieldInputProps extends SlotProps {
90
- /** The CSS className for the element. */
91
- class?: ClassNameOrFunction<SearchFieldInputRenderProps>;
92
- /** The inline style for the element. */
93
- style?: StyleOrFunction<SearchFieldInputRenderProps>;
94
- }
95
-
96
- export interface SearchFieldClearButtonRenderProps {
97
- /** Whether the button is pressed. */
98
- isPressed: boolean;
99
- /** Whether the button is hovered. */
100
- isHovered: boolean;
101
- /** Whether the button is disabled. */
102
- isDisabled: boolean;
103
- }
104
-
105
- export interface SearchFieldClearButtonProps extends SlotProps {
106
- /** The children of the button. */
107
- children?: RenderChildren<SearchFieldClearButtonRenderProps>;
108
- /** The CSS className for the element. */
109
- class?: ClassNameOrFunction<SearchFieldClearButtonRenderProps>;
110
- /** The inline style for the element. */
111
- style?: StyleOrFunction<SearchFieldClearButtonRenderProps>;
112
- }
113
-
114
- // ============================================
115
- // CONTEXT
116
- // ============================================
117
-
118
- interface SearchFieldContextValue {
119
- state: SearchFieldState;
120
- inputProps: JSX.InputHTMLAttributes<HTMLInputElement>;
121
- clearButtonProps: {
122
- 'aria-label': string;
123
- tabIndex: number;
124
- disabled?: boolean;
125
- onMouseDown: (e: MouseEvent) => void;
126
- onClick: () => void;
127
- };
128
- labelProps: JSX.HTMLAttributes<HTMLElement>;
129
- descriptionProps: JSX.HTMLAttributes<HTMLElement>;
130
- errorMessageProps: JSX.HTMLAttributes<HTMLElement>;
131
- isDisabled: boolean;
132
- isInvalid: boolean;
133
- isRequired: boolean;
134
- isReadOnly: boolean;
135
- inputRef: HTMLInputElement | undefined;
136
- setInputRef: (el: HTMLInputElement) => void;
137
- }
138
-
139
- export const SearchFieldContext = createContext<SearchFieldContextValue | null>(null);
140
-
141
- // ============================================
142
- // COMPONENTS
143
- // ============================================
144
-
145
- /**
146
- * A search field allows a user to enter and clear a search query.
147
- */
148
- export function SearchField(props: SearchFieldProps): JSX.Element {
149
- const [local, stateProps, ariaProps, rest] = splitProps(
150
- props,
151
- ['children', 'class', 'style', 'slot'],
152
- ['value', 'defaultValue', 'onChange', 'onSubmit', 'onClear'],
153
- ['label', 'aria-label', 'aria-labelledby', 'aria-describedby', 'isDisabled', 'isReadOnly', 'isRequired', 'isInvalid', 'description', 'errorMessage', 'id', 'autoFocus', 'name', 'placeholder', 'autoComplete', 'maxLength', 'minLength', 'pattern']
154
- );
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
- // Ref for the input
170
- let inputRef: HTMLInputElement | undefined;
171
- const setInputRef = (el: HTMLInputElement) => {
172
- inputRef = el;
173
- };
174
-
175
- // Create search field aria props
176
- const {
177
- labelProps,
178
- inputProps,
179
- clearButtonProps,
180
- descriptionProps,
181
- errorMessageProps,
182
- } = createSearchField(
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 label() {
197
- return ariaProps.label;
198
- },
199
- get 'aria-label'() {
200
- return ariaProps['aria-label'];
201
- },
202
- get 'aria-labelledby'() {
203
- return ariaProps['aria-labelledby'];
204
- },
205
- get 'aria-describedby'() {
206
- return ariaProps['aria-describedby'];
207
- },
208
- get description() {
209
- return ariaProps.description;
210
- },
211
- get errorMessage() {
212
- return ariaProps.errorMessage;
213
- },
214
- get placeholder() {
215
- return ariaProps.placeholder;
216
- },
217
- get name() {
218
- return ariaProps.name;
219
- },
220
- get autoFocus() {
221
- return ariaProps.autoFocus;
222
- },
223
- get autoComplete() {
224
- return ariaProps.autoComplete;
225
- },
226
- get maxLength() {
227
- return ariaProps.maxLength;
228
- },
229
- get minLength() {
230
- return ariaProps.minLength;
231
- },
232
- get pattern() {
233
- return ariaProps.pattern;
234
- },
235
- get onSubmit() {
236
- return stateProps.onSubmit;
237
- },
238
- get onClear() {
239
- return stateProps.onClear;
240
- },
241
- },
242
- state,
243
- () => inputRef ?? null
244
- );
245
-
246
- // Render props values
247
- const renderValues = createMemo<SearchFieldRenderProps>(() => ({
248
- isEmpty: state.value() === '',
249
- isDisabled: ariaProps.isDisabled ?? false,
250
- isInvalid: ariaProps.isInvalid ?? false,
251
- isRequired: ariaProps.isRequired ?? false,
252
- isReadOnly: ariaProps.isReadOnly ?? false,
253
- value: state.value(),
254
- }));
255
-
256
- // Resolve render props
257
- const renderProps = useRenderProps(
258
- {
259
- children: props.children,
260
- class: local.class,
261
- style: local.style,
262
- defaultClassName: 'solidaria-SearchField',
263
- },
264
- renderValues
265
- );
266
-
267
- // Filter DOM props
268
- const domProps = createMemo(() => filterDOMProps(rest as Record<string, unknown>, { global: true }));
269
-
270
- return (
271
- <SearchFieldContext.Provider
272
- value={{
273
- state,
274
- inputProps,
275
- clearButtonProps,
276
- labelProps: labelProps as JSX.HTMLAttributes<HTMLElement>,
277
- descriptionProps,
278
- errorMessageProps,
279
- isDisabled: ariaProps.isDisabled ?? false,
280
- isInvalid: ariaProps.isInvalid ?? false,
281
- isRequired: ariaProps.isRequired ?? false,
282
- isReadOnly: ariaProps.isReadOnly ?? false,
283
- inputRef,
284
- setInputRef,
285
- }}
286
- >
287
- <div
288
- {...domProps()}
289
- class={renderProps.class()}
290
- style={renderProps.style()}
291
- data-empty={state.value() === '' || undefined}
292
- data-disabled={ariaProps.isDisabled || undefined}
293
- data-invalid={ariaProps.isInvalid || undefined}
294
- data-required={ariaProps.isRequired || undefined}
295
- data-readonly={ariaProps.isReadOnly || undefined}
296
- >
297
- {renderProps.renderChildren()}
298
- </div>
299
- </SearchFieldContext.Provider>
300
- );
301
- }
302
-
303
- /**
304
- * The label for a search field.
305
- */
306
- export function SearchFieldLabel(props: { children?: JSX.Element; class?: string; style?: JSX.CSSProperties }): JSX.Element {
307
- const context = useContext(SearchFieldContext);
308
- if (!context) {
309
- throw new Error('SearchFieldLabel must be used within a SearchField');
310
- }
311
-
312
- return (
313
- <span
314
- {...context.labelProps}
315
- class={props.class ?? 'solidaria-SearchField-label'}
316
- style={props.style}
317
- >
318
- {props.children}
319
- </span>
320
- );
321
- }
322
-
323
- /**
324
- * The input element for a search field.
325
- */
326
- export function SearchFieldInput(props: SearchFieldInputProps): JSX.Element {
327
- const [local] = splitProps(props, ['class', 'style', 'slot']);
328
-
329
- const context = useContext(SearchFieldContext);
330
- if (!context) {
331
- throw new Error('SearchFieldInput must be used within a SearchField');
332
- }
333
-
334
- // Create focus ring
335
- const { isFocused, isFocusVisible, focusProps } = createFocusRing();
336
-
337
- // Create hover
338
- const { isHovered, hoverProps } = createHover({
339
- get isDisabled() {
340
- return context.isDisabled;
341
- },
342
- });
343
-
344
- // Render props values
345
- const renderValues = createMemo<SearchFieldInputRenderProps>(() => ({
346
- isFocused: isFocused(),
347
- isFocusVisible: isFocusVisible(),
348
- isHovered: isHovered(),
349
- isDisabled: context.isDisabled,
350
- isInvalid: context.isInvalid,
351
- }));
352
-
353
- // Resolve render props
354
- const renderProps = useRenderProps(
355
- {
356
- class: local.class,
357
- style: local.style,
358
- defaultClassName: 'solidaria-SearchField-input',
359
- },
360
- renderValues
361
- );
362
-
363
- // Remove ref from spread props
364
- const cleanInputProps = () => {
365
- const { ref: _ref, ...rest } = context.inputProps as Record<string, unknown>;
366
- return rest;
367
- };
368
- const cleanFocusProps = () => {
369
- const { ref: _ref, ...rest } = focusProps as Record<string, unknown>;
370
- return rest;
371
- };
372
- const cleanHoverProps = () => {
373
- const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;
374
- return rest;
375
- };
376
-
377
- return (
378
- <input
379
- ref={context.setInputRef}
380
- {...cleanInputProps()}
381
- {...cleanFocusProps()}
382
- {...cleanHoverProps()}
383
- class={renderProps.class()}
384
- style={renderProps.style()}
385
- data-focused={isFocused() || undefined}
386
- data-focus-visible={isFocusVisible() || undefined}
387
- data-hovered={isHovered() || undefined}
388
- data-disabled={context.isDisabled || undefined}
389
- data-invalid={context.isInvalid || undefined}
390
- />
391
- );
392
- }
393
-
394
- /**
395
- * The clear button for a search field.
396
- */
397
- export function SearchFieldClearButton(props: SearchFieldClearButtonProps): JSX.Element {
398
- const [local] = splitProps(props, ['class', 'style', 'slot']);
399
-
400
- const context = useContext(SearchFieldContext);
401
- if (!context) {
402
- throw new Error('SearchFieldClearButton must be used within a SearchField');
403
- }
404
-
405
- // Create press
406
- const { isPressed, pressProps } = createPress({
407
- get isDisabled() {
408
- return context.isDisabled || context.isReadOnly;
409
- },
410
- onPress: () => {
411
- context.clearButtonProps.onClick();
412
- },
413
- });
414
-
415
- // Create hover
416
- const { isHovered, hoverProps } = createHover({
417
- get isDisabled() {
418
- return context.isDisabled || context.isReadOnly;
419
- },
420
- });
421
-
422
- const isDisabled = () => context.isDisabled || context.isReadOnly;
423
- const isEmpty = () => context.state.value() === '';
424
-
425
- // Render props values
426
- const renderValues = createMemo<SearchFieldClearButtonRenderProps>(() => ({
427
- isPressed: isPressed(),
428
- isHovered: isHovered(),
429
- isDisabled: isDisabled(),
430
- }));
431
-
432
- // Resolve render props
433
- const renderProps = useRenderProps(
434
- {
435
- children: props.children,
436
- class: local.class,
437
- style: local.style,
438
- defaultClassName: 'solidaria-SearchField-clear',
439
- },
440
- renderValues
441
- );
442
-
443
- // Remove ref from spread props
444
- const cleanPressProps = () => {
445
- const { ref: _ref, ...rest } = pressProps as Record<string, unknown>;
446
- return rest;
447
- };
448
- const cleanHoverProps = () => {
449
- const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;
450
- return rest;
451
- };
452
-
453
- // Only show clear button when there's a value
454
- return (
455
- <Show when={!isEmpty()}>
456
- <button
457
- type="button"
458
- aria-label={context.clearButtonProps['aria-label']}
459
- tabIndex={context.clearButtonProps.tabIndex}
460
- disabled={context.clearButtonProps.disabled}
461
- onMouseDown={context.clearButtonProps.onMouseDown}
462
- {...cleanPressProps()}
463
- {...cleanHoverProps()}
464
- class={renderProps.class()}
465
- style={renderProps.style()}
466
- data-pressed={isPressed() || undefined}
467
- data-hovered={isHovered() || undefined}
468
- data-disabled={isDisabled() || undefined}
469
- >
470
- {renderProps.renderChildren()}
471
- </button>
472
- </Show>
473
- );
474
- }
475
-
476
- // Attach sub-components
477
- SearchField.Label = SearchFieldLabel;
478
- SearchField.Input = SearchFieldInput;
479
- SearchField.ClearButton = SearchFieldClearButton;