@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,542 +0,0 @@
1
- /**
2
- * NumberField component for solidaria-components
3
- *
4
- * A pre-wired headless number field that combines state + aria hooks.
5
- * Port of react-aria-components/src/NumberField.tsx
6
- */
7
-
8
- import {
9
- type JSX,
10
- createContext,
11
- createMemo,
12
- splitProps,
13
- useContext,
14
- } from 'solid-js';
15
- import {
16
- createNumberField,
17
- createFocusRing,
18
- createHover,
19
- createPress,
20
- type AriaNumberFieldProps,
21
- } from '@proyecto-viviana/solidaria';
22
- import {
23
- createNumberFieldState,
24
- type NumberFieldState,
25
- } from '@proyecto-viviana/solid-stately';
26
- import {
27
- type RenderChildren,
28
- type ClassNameOrFunction,
29
- type StyleOrFunction,
30
- type SlotProps,
31
- useRenderProps,
32
- filterDOMProps,
33
- } from './utils';
34
-
35
- // ============================================
36
- // TYPES
37
- // ============================================
38
-
39
- export interface NumberFieldRenderProps {
40
- /** Whether the number field is disabled. */
41
- isDisabled: boolean;
42
- /** Whether the number field is invalid. */
43
- isInvalid: boolean;
44
- /** Whether the number field is required. */
45
- isRequired: boolean;
46
- /** Whether the number field is read-only. */
47
- isReadOnly: boolean;
48
- /** The current numeric value. */
49
- value: number;
50
- }
51
-
52
- export interface NumberFieldProps extends Omit<AriaNumberFieldProps, 'label'>, SlotProps {
53
- /** The current value (controlled). */
54
- value?: number;
55
- /** The default value (uncontrolled). */
56
- defaultValue?: number;
57
- /** Handler called when the value changes. */
58
- onChange?: (value: number) => void;
59
- /** The minimum value. */
60
- minValue?: number;
61
- /** The maximum value. */
62
- maxValue?: number;
63
- /** The step value for increment/decrement. */
64
- step?: number;
65
- /** The locale for number formatting. */
66
- locale?: string;
67
- /** Number format options. */
68
- formatOptions?: Intl.NumberFormatOptions;
69
- /** A visible label for the number field. */
70
- label?: JSX.Element;
71
- /** The children of the component. */
72
- children?: RenderChildren<NumberFieldRenderProps>;
73
- /** The CSS className for the element. */
74
- class?: ClassNameOrFunction<NumberFieldRenderProps>;
75
- /** The inline style for the element. */
76
- style?: StyleOrFunction<NumberFieldRenderProps>;
77
- }
78
-
79
- export interface NumberFieldInputRenderProps {
80
- /** Whether the input is focused. */
81
- isFocused: boolean;
82
- /** Whether the input has keyboard focus. */
83
- isFocusVisible: boolean;
84
- /** Whether the input is hovered. */
85
- isHovered: boolean;
86
- /** Whether the input is disabled. */
87
- isDisabled: boolean;
88
- /** Whether the input is invalid. */
89
- isInvalid: boolean;
90
- }
91
-
92
- export interface NumberFieldInputProps extends SlotProps {
93
- /** The CSS className for the element. */
94
- class?: ClassNameOrFunction<NumberFieldInputRenderProps>;
95
- /** The inline style for the element. */
96
- style?: StyleOrFunction<NumberFieldInputRenderProps>;
97
- }
98
-
99
- export interface NumberFieldButtonRenderProps {
100
- /** Whether the button is pressed. */
101
- isPressed: boolean;
102
- /** Whether the button is hovered. */
103
- isHovered: boolean;
104
- /** Whether the button is disabled. */
105
- isDisabled: boolean;
106
- }
107
-
108
- export interface NumberFieldIncrementButtonProps extends SlotProps {
109
- /** The children of the button. */
110
- children?: RenderChildren<NumberFieldButtonRenderProps>;
111
- /** The CSS className for the element. */
112
- class?: ClassNameOrFunction<NumberFieldButtonRenderProps>;
113
- /** The inline style for the element. */
114
- style?: StyleOrFunction<NumberFieldButtonRenderProps>;
115
- }
116
-
117
- export interface NumberFieldDecrementButtonProps extends SlotProps {
118
- /** The children of the button. */
119
- children?: RenderChildren<NumberFieldButtonRenderProps>;
120
- /** The CSS className for the element. */
121
- class?: ClassNameOrFunction<NumberFieldButtonRenderProps>;
122
- /** The inline style for the element. */
123
- style?: StyleOrFunction<NumberFieldButtonRenderProps>;
124
- }
125
-
126
- // ============================================
127
- // CONTEXT
128
- // ============================================
129
-
130
- interface NumberFieldContextValue {
131
- state: NumberFieldState;
132
- inputProps: JSX.InputHTMLAttributes<HTMLInputElement>;
133
- incrementButtonProps: JSX.ButtonHTMLAttributes<HTMLButtonElement>;
134
- decrementButtonProps: JSX.ButtonHTMLAttributes<HTMLButtonElement>;
135
- labelProps: JSX.HTMLAttributes<HTMLElement>;
136
- groupProps: JSX.HTMLAttributes<HTMLElement>;
137
- descriptionProps: JSX.HTMLAttributes<HTMLElement>;
138
- errorMessageProps: JSX.HTMLAttributes<HTMLElement>;
139
- isDisabled: boolean;
140
- isInvalid: boolean;
141
- isRequired: boolean;
142
- isReadOnly: boolean;
143
- }
144
-
145
- export const NumberFieldContext = createContext<NumberFieldContextValue | null>(null);
146
-
147
- // ============================================
148
- // COMPONENTS
149
- // ============================================
150
-
151
- /**
152
- * A number field allows a user to enter a number and increment/decrement the value.
153
- */
154
- export function NumberField(props: NumberFieldProps): JSX.Element {
155
- const [local, stateProps, ariaProps, rest] = splitProps(
156
- props,
157
- ['children', 'class', 'style', 'slot'],
158
- ['value', 'defaultValue', 'onChange', 'minValue', 'maxValue', 'step', 'locale', 'formatOptions'],
159
- ['label', 'aria-label', 'aria-labelledby', 'aria-describedby', 'isDisabled', 'isReadOnly', 'isRequired', 'isInvalid', 'description', 'errorMessage', 'id', 'autoFocus', 'name']
160
- );
161
-
162
- // Create number field state
163
- const state = createNumberFieldState({
164
- get value() {
165
- return stateProps.value;
166
- },
167
- get defaultValue() {
168
- return stateProps.defaultValue;
169
- },
170
- get onChange() {
171
- return stateProps.onChange;
172
- },
173
- get minValue() {
174
- return stateProps.minValue;
175
- },
176
- get maxValue() {
177
- return stateProps.maxValue;
178
- },
179
- get step() {
180
- return stateProps.step;
181
- },
182
- get locale() {
183
- return stateProps.locale;
184
- },
185
- get formatOptions() {
186
- return stateProps.formatOptions;
187
- },
188
- get isDisabled() {
189
- return ariaProps.isDisabled;
190
- },
191
- get isReadOnly() {
192
- return ariaProps.isReadOnly;
193
- },
194
- });
195
-
196
- // Ref for the input
197
- let inputRef: HTMLInputElement | undefined;
198
-
199
- // Create number field aria props
200
- const {
201
- labelProps,
202
- groupProps,
203
- inputProps,
204
- incrementButtonProps,
205
- decrementButtonProps,
206
- descriptionProps,
207
- errorMessageProps,
208
- } = createNumberField(ariaProps, state, () => inputRef ?? null);
209
-
210
- // Render props values
211
- const renderValues = createMemo<NumberFieldRenderProps>(() => ({
212
- isDisabled: ariaProps.isDisabled ?? false,
213
- isInvalid: ariaProps.isInvalid ?? false,
214
- isRequired: ariaProps.isRequired ?? false,
215
- isReadOnly: ariaProps.isReadOnly ?? false,
216
- value: state.numberValue(),
217
- }));
218
-
219
- // Resolve render props
220
- const renderProps = useRenderProps(
221
- {
222
- children: props.children,
223
- class: local.class,
224
- style: local.style,
225
- defaultClassName: 'solidaria-NumberField',
226
- },
227
- renderValues
228
- );
229
-
230
- // Filter DOM props
231
- const domProps = createMemo(() => filterDOMProps(rest as Record<string, unknown>, { global: true }));
232
-
233
- return (
234
- <NumberFieldContext.Provider
235
- value={{
236
- state,
237
- inputProps,
238
- incrementButtonProps,
239
- decrementButtonProps,
240
- labelProps,
241
- groupProps,
242
- descriptionProps,
243
- errorMessageProps,
244
- isDisabled: ariaProps.isDisabled ?? false,
245
- isInvalid: ariaProps.isInvalid ?? false,
246
- isRequired: ariaProps.isRequired ?? false,
247
- isReadOnly: ariaProps.isReadOnly ?? false,
248
- }}
249
- >
250
- <div
251
- {...domProps()}
252
- class={renderProps.class()}
253
- style={renderProps.style()}
254
- data-disabled={ariaProps.isDisabled || undefined}
255
- data-invalid={ariaProps.isInvalid || undefined}
256
- data-required={ariaProps.isRequired || undefined}
257
- data-readonly={ariaProps.isReadOnly || undefined}
258
- >
259
- {renderProps.renderChildren()}
260
- </div>
261
- </NumberFieldContext.Provider>
262
- );
263
- }
264
-
265
- /**
266
- * The label for a number field.
267
- */
268
- export function NumberFieldLabel(props: { children?: JSX.Element; class?: string; style?: JSX.CSSProperties }): JSX.Element {
269
- const context = useContext(NumberFieldContext);
270
- if (!context) {
271
- throw new Error('NumberFieldLabel must be used within a NumberField');
272
- }
273
-
274
- return (
275
- <span
276
- {...context.labelProps}
277
- class={props.class ?? 'solidaria-NumberField-label'}
278
- style={props.style}
279
- >
280
- {props.children}
281
- </span>
282
- );
283
- }
284
-
285
- /**
286
- * The input group for a number field (contains input and buttons).
287
- */
288
- export function NumberFieldGroup(props: { children?: JSX.Element; class?: string; style?: JSX.CSSProperties }): JSX.Element {
289
- const context = useContext(NumberFieldContext);
290
- if (!context) {
291
- throw new Error('NumberFieldGroup must be used within a NumberField');
292
- }
293
-
294
- // Extract ref to avoid type issues
295
- const cleanGroupProps = () => {
296
- const { ref: _ref, ...rest } = context.groupProps as Record<string, unknown>;
297
- return rest;
298
- };
299
-
300
- return (
301
- <div
302
- {...cleanGroupProps()}
303
- class={props.class ?? 'solidaria-NumberField-group'}
304
- style={props.style}
305
- >
306
- {props.children}
307
- </div>
308
- );
309
- }
310
-
311
- /**
312
- * The input element for a number field.
313
- */
314
- export function NumberFieldInput(props: NumberFieldInputProps): JSX.Element {
315
- const [local] = splitProps(props, ['class', 'style', 'slot']);
316
-
317
- const context = useContext(NumberFieldContext);
318
- if (!context) {
319
- throw new Error('NumberFieldInput must be used within a NumberField');
320
- }
321
-
322
- // Create focus ring
323
- const { isFocused, isFocusVisible, focusProps } = createFocusRing();
324
-
325
- // Create hover
326
- const { isHovered, hoverProps } = createHover({
327
- get isDisabled() {
328
- return context.isDisabled;
329
- },
330
- });
331
-
332
- // Render props values
333
- const renderValues = createMemo<NumberFieldInputRenderProps>(() => ({
334
- isFocused: isFocused(),
335
- isFocusVisible: isFocusVisible(),
336
- isHovered: isHovered(),
337
- isDisabled: context.isDisabled,
338
- isInvalid: context.isInvalid,
339
- }));
340
-
341
- // Resolve render props
342
- const renderProps = useRenderProps(
343
- {
344
- class: local.class,
345
- style: local.style,
346
- defaultClassName: 'solidaria-NumberField-input',
347
- },
348
- renderValues
349
- );
350
-
351
- // Remove ref from spread props
352
- const cleanInputProps = () => {
353
- const { ref: _ref, ...rest } = context.inputProps as Record<string, unknown>;
354
- return rest;
355
- };
356
- const cleanFocusProps = () => {
357
- const { ref: _ref, ...rest } = focusProps as Record<string, unknown>;
358
- return rest;
359
- };
360
- const cleanHoverProps = () => {
361
- const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;
362
- return rest;
363
- };
364
-
365
- return (
366
- <input
367
- {...cleanInputProps()}
368
- {...cleanFocusProps()}
369
- {...cleanHoverProps()}
370
- class={renderProps.class()}
371
- style={renderProps.style()}
372
- data-focused={isFocused() || undefined}
373
- data-focus-visible={isFocusVisible() || undefined}
374
- data-hovered={isHovered() || undefined}
375
- data-disabled={context.isDisabled || undefined}
376
- data-invalid={context.isInvalid || undefined}
377
- />
378
- );
379
- }
380
-
381
- /**
382
- * The increment button for a number field.
383
- */
384
- export function NumberFieldIncrementButton(props: NumberFieldIncrementButtonProps): JSX.Element {
385
- const [local] = splitProps(props, ['class', 'style', 'slot']);
386
-
387
- const context = useContext(NumberFieldContext);
388
- if (!context) {
389
- throw new Error('NumberFieldIncrementButton must be used within a NumberField');
390
- }
391
-
392
- // Create press
393
- const { isPressed, pressProps } = createPress({
394
- get isDisabled() {
395
- return context.isDisabled || !context.state.canIncrement();
396
- },
397
- onPress: () => {
398
- context.state.increment();
399
- },
400
- });
401
-
402
- // Create hover
403
- const { isHovered, hoverProps } = createHover({
404
- get isDisabled() {
405
- return context.isDisabled || !context.state.canIncrement();
406
- },
407
- });
408
-
409
- const isDisabled = () => context.isDisabled || !context.state.canIncrement();
410
-
411
- // Render props values
412
- const renderValues = createMemo<NumberFieldButtonRenderProps>(() => ({
413
- isPressed: isPressed(),
414
- isHovered: isHovered(),
415
- isDisabled: isDisabled(),
416
- }));
417
-
418
- // Resolve render props
419
- const renderProps = useRenderProps(
420
- {
421
- children: props.children,
422
- class: local.class,
423
- style: local.style,
424
- defaultClassName: 'solidaria-NumberField-increment',
425
- },
426
- renderValues
427
- );
428
-
429
- // Remove ref from spread props
430
- const cleanButtonProps = () => {
431
- const { ref: _ref, ...rest } = context.incrementButtonProps as Record<string, unknown>;
432
- return rest;
433
- };
434
- const cleanPressProps = () => {
435
- const { ref: _ref, ...rest } = pressProps as Record<string, unknown>;
436
- return rest;
437
- };
438
- const cleanHoverProps = () => {
439
- const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;
440
- return rest;
441
- };
442
-
443
- return (
444
- <button
445
- {...cleanButtonProps()}
446
- {...cleanPressProps()}
447
- {...cleanHoverProps()}
448
- class={renderProps.class()}
449
- style={renderProps.style()}
450
- data-pressed={isPressed() || undefined}
451
- data-hovered={isHovered() || undefined}
452
- data-disabled={isDisabled() || undefined}
453
- >
454
- {renderProps.renderChildren()}
455
- </button>
456
- );
457
- }
458
-
459
- /**
460
- * The decrement button for a number field.
461
- */
462
- export function NumberFieldDecrementButton(props: NumberFieldDecrementButtonProps): JSX.Element {
463
- const [local] = splitProps(props, ['class', 'style', 'slot']);
464
-
465
- const context = useContext(NumberFieldContext);
466
- if (!context) {
467
- throw new Error('NumberFieldDecrementButton must be used within a NumberField');
468
- }
469
-
470
- // Create press
471
- const { isPressed, pressProps } = createPress({
472
- get isDisabled() {
473
- return context.isDisabled || !context.state.canDecrement();
474
- },
475
- onPress: () => {
476
- context.state.decrement();
477
- },
478
- });
479
-
480
- // Create hover
481
- const { isHovered, hoverProps } = createHover({
482
- get isDisabled() {
483
- return context.isDisabled || !context.state.canDecrement();
484
- },
485
- });
486
-
487
- const isDisabled = () => context.isDisabled || !context.state.canDecrement();
488
-
489
- // Render props values
490
- const renderValues = createMemo<NumberFieldButtonRenderProps>(() => ({
491
- isPressed: isPressed(),
492
- isHovered: isHovered(),
493
- isDisabled: isDisabled(),
494
- }));
495
-
496
- // Resolve render props
497
- const renderProps = useRenderProps(
498
- {
499
- children: props.children,
500
- class: local.class,
501
- style: local.style,
502
- defaultClassName: 'solidaria-NumberField-decrement',
503
- },
504
- renderValues
505
- );
506
-
507
- // Remove ref from spread props
508
- const cleanButtonProps = () => {
509
- const { ref: _ref, ...rest } = context.decrementButtonProps as Record<string, unknown>;
510
- return rest;
511
- };
512
- const cleanPressProps = () => {
513
- const { ref: _ref, ...rest } = pressProps as Record<string, unknown>;
514
- return rest;
515
- };
516
- const cleanHoverProps = () => {
517
- const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;
518
- return rest;
519
- };
520
-
521
- return (
522
- <button
523
- {...cleanButtonProps()}
524
- {...cleanPressProps()}
525
- {...cleanHoverProps()}
526
- class={renderProps.class()}
527
- style={renderProps.style()}
528
- data-pressed={isPressed() || undefined}
529
- data-hovered={isHovered() || undefined}
530
- data-disabled={isDisabled() || undefined}
531
- >
532
- {renderProps.renderChildren()}
533
- </button>
534
- );
535
- }
536
-
537
- // Attach sub-components
538
- NumberField.Label = NumberFieldLabel;
539
- NumberField.Group = NumberFieldGroup;
540
- NumberField.Input = NumberFieldInput;
541
- NumberField.IncrementButton = NumberFieldIncrementButton;
542
- NumberField.DecrementButton = NumberFieldDecrementButton;