@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.
Files changed (64) 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.jsx +9056 -0
  20. package/dist/index.jsx.map +7 -0
  21. package/dist/index.ssr.js +15 -15
  22. package/dist/index.ssr.js.map +2 -2
  23. package/package.json +8 -10
  24. package/src/Autocomplete.tsx +0 -174
  25. package/src/Breadcrumbs.tsx +0 -264
  26. package/src/Button.tsx +0 -238
  27. package/src/Calendar.tsx +0 -471
  28. package/src/Checkbox.tsx +0 -387
  29. package/src/Color.tsx +0 -1370
  30. package/src/ComboBox.tsx +0 -824
  31. package/src/DateField.tsx +0 -337
  32. package/src/DatePicker.tsx +0 -367
  33. package/src/Dialog.tsx +0 -262
  34. package/src/Disclosure.tsx +0 -439
  35. package/src/GridList.tsx +0 -511
  36. package/src/Landmark.tsx +0 -203
  37. package/src/Link.tsx +0 -201
  38. package/src/ListBox.tsx +0 -346
  39. package/src/Menu.tsx +0 -544
  40. package/src/Meter.tsx +0 -157
  41. package/src/Modal.tsx +0 -433
  42. package/src/NumberField.tsx +0 -542
  43. package/src/Popover.tsx +0 -540
  44. package/src/ProgressBar.tsx +0 -162
  45. package/src/RadioGroup.tsx +0 -356
  46. package/src/RangeCalendar.tsx +0 -462
  47. package/src/SearchField.tsx +0 -479
  48. package/src/Select.tsx +0 -734
  49. package/src/Separator.tsx +0 -130
  50. package/src/Slider.tsx +0 -500
  51. package/src/Switch.tsx +0 -213
  52. package/src/Table.tsx +0 -857
  53. package/src/Tabs.tsx +0 -552
  54. package/src/TagGroup.tsx +0 -421
  55. package/src/TextField.tsx +0 -271
  56. package/src/TimeField.tsx +0 -455
  57. package/src/Toast.tsx +0 -503
  58. package/src/Toolbar.tsx +0 -160
  59. package/src/Tooltip.tsx +0 -423
  60. package/src/Tree.tsx +0 -551
  61. package/src/VisuallyHidden.tsx +0 -60
  62. package/src/contexts.ts +0 -74
  63. package/src/index.ts +0 -620
  64. 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;