@proyecto-viviana/solidaria-components 0.1.3 → 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 -10
  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
package/src/Tabs.tsx DELETED
@@ -1,552 +0,0 @@
1
- /**
2
- * Tabs component for solidaria-components
3
- *
4
- * A pre-wired headless tabs component that combines state + aria hooks.
5
- * Port of react-aria-components/src/Tabs.tsx
6
- */
7
-
8
- import {
9
- type JSX,
10
- createContext,
11
- createMemo,
12
- splitProps,
13
- useContext,
14
- For,
15
- Show,
16
- } from 'solid-js';
17
- import {
18
- createTabList,
19
- createTab,
20
- createTabPanel,
21
- createFocusRing,
22
- createHover,
23
- type AriaTabListProps,
24
- type AriaTabProps,
25
- type AriaTabPanelProps,
26
- } from '@proyecto-viviana/solidaria';
27
- import {
28
- createTabListState,
29
- type TabListState,
30
- type Key,
31
- type TabOrientation,
32
- type KeyboardActivation,
33
- } from '@proyecto-viviana/solid-stately';
34
- import {
35
- type RenderChildren,
36
- type ClassNameOrFunction,
37
- type StyleOrFunction,
38
- type SlotProps,
39
- useRenderProps,
40
- filterDOMProps,
41
- } from './utils';
42
-
43
- // ============================================
44
- // TYPES
45
- // ============================================
46
-
47
- export interface TabsRenderProps {
48
- /** The orientation of the tabs. */
49
- orientation: TabOrientation;
50
- /** Whether the tabs are disabled. */
51
- isDisabled: boolean;
52
- }
53
-
54
- export interface TabsProps<T> extends SlotProps {
55
- /** The items to render in the tab list. */
56
- items?: T[];
57
- /** Function to get the key from an item. */
58
- getKey?: (item: T) => Key;
59
- /** Function to get the text value from an item. */
60
- getTextValue?: (item: T) => string;
61
- /** Function to check if an item is disabled. */
62
- getDisabled?: (item: T) => boolean;
63
- /** Keys of disabled tabs. */
64
- disabledKeys?: Iterable<Key>;
65
- /** The currently selected tab key (controlled). */
66
- selectedKey?: Key | null;
67
- /** The default selected tab key (uncontrolled). */
68
- defaultSelectedKey?: Key;
69
- /** Handler for tab selection changes. */
70
- onSelectionChange?: (key: Key) => void;
71
- /** Whether the tabs are disabled. */
72
- isDisabled?: boolean;
73
- /** The keyboard activation mode. */
74
- keyboardActivation?: KeyboardActivation;
75
- /** The orientation of the tabs. */
76
- orientation?: TabOrientation;
77
- /** The children of the component. */
78
- children?: RenderChildren<TabsRenderProps>;
79
- /** The CSS className for the element. */
80
- class?: ClassNameOrFunction<TabsRenderProps>;
81
- /** The inline style for the element. */
82
- style?: StyleOrFunction<TabsRenderProps>;
83
- }
84
-
85
- export interface TabListRenderProps {
86
- /** The orientation of the tab list. */
87
- orientation: TabOrientation;
88
- /** Whether the tab list is disabled. */
89
- isDisabled: boolean;
90
- /** Whether the tab list has focus. */
91
- isFocused: boolean;
92
- /** Whether the tab list has visible focus. */
93
- isFocusVisible: boolean;
94
- }
95
-
96
- export interface TabListProps<T> extends Omit<AriaTabListProps, 'children'>, SlotProps {
97
- /** The children of the tab list - render function for each item. */
98
- children: (item: T) => JSX.Element;
99
- /** The CSS className for the element. */
100
- class?: ClassNameOrFunction<TabListRenderProps>;
101
- /** The inline style for the element. */
102
- style?: StyleOrFunction<TabListRenderProps>;
103
- }
104
-
105
- export interface TabRenderProps {
106
- /** Whether the tab is selected. */
107
- isSelected: boolean;
108
- /** Whether the tab is focused. */
109
- isFocused: boolean;
110
- /** Whether the tab has visible focus ring. */
111
- isFocusVisible: boolean;
112
- /** Whether the tab is pressed. */
113
- isPressed: boolean;
114
- /** Whether the tab is hovered. */
115
- isHovered: boolean;
116
- /** Whether the tab is disabled. */
117
- isDisabled: boolean;
118
- }
119
-
120
- export interface TabProps extends Omit<AriaTabProps, 'key'>, SlotProps {
121
- /** The unique key for the tab. */
122
- id: Key;
123
- /** The children of the tab. */
124
- children?: RenderChildren<TabRenderProps>;
125
- /** The CSS className for the element. */
126
- class?: ClassNameOrFunction<TabRenderProps>;
127
- /** The inline style for the element. */
128
- style?: StyleOrFunction<TabRenderProps>;
129
- }
130
-
131
- export interface TabPanelRenderProps {
132
- /** Whether the panel is the selected one. */
133
- isSelected: boolean;
134
- /** Whether the panel is focused. */
135
- isFocused: boolean;
136
- /** Whether the panel has visible focus ring. */
137
- isFocusVisible: boolean;
138
- }
139
-
140
- export interface TabPanelProps extends AriaTabPanelProps, SlotProps {
141
- /** The children of the tab panel. */
142
- children?: RenderChildren<TabPanelRenderProps>;
143
- /** The CSS className for the element. */
144
- class?: ClassNameOrFunction<TabPanelRenderProps>;
145
- /** The inline style for the element. */
146
- style?: StyleOrFunction<TabPanelRenderProps>;
147
- /** Whether to keep the panel mounted when not selected. */
148
- shouldForceMount?: boolean;
149
- }
150
-
151
- // ============================================
152
- // CONTEXT
153
- // ============================================
154
-
155
- interface TabsContextValue<T> {
156
- state: TabListState<T>;
157
- items: T[];
158
- }
159
-
160
- export const TabsContext = createContext<TabsContextValue<unknown> | null>(null);
161
- export const TabsStateContext = createContext<TabListState<unknown> | null>(null);
162
-
163
- // ============================================
164
- // COMPONENTS
165
- // ============================================
166
-
167
- /**
168
- * Tabs provide a way to organize content into multiple sections, with only one section visible at a time.
169
- */
170
- export function Tabs<T>(props: TabsProps<T>): JSX.Element {
171
- const [local, stateProps, rest] = splitProps(
172
- props,
173
- ['class', 'style', 'slot'],
174
- ['items', 'getKey', 'getTextValue', 'getDisabled', 'disabledKeys', 'selectedKey', 'defaultSelectedKey', 'onSelectionChange', 'isDisabled', 'keyboardActivation', 'orientation']
175
- );
176
-
177
- // Create tab list state
178
- const state = createTabListState<T>({
179
- get items() {
180
- return stateProps.items;
181
- },
182
- get getKey() {
183
- return stateProps.getKey;
184
- },
185
- get getTextValue() {
186
- return stateProps.getTextValue;
187
- },
188
- get getDisabled() {
189
- return stateProps.getDisabled;
190
- },
191
- get disabledKeys() {
192
- return stateProps.disabledKeys;
193
- },
194
- get selectedKey() {
195
- return stateProps.selectedKey;
196
- },
197
- get defaultSelectedKey() {
198
- return stateProps.defaultSelectedKey;
199
- },
200
- get onSelectionChange() {
201
- return stateProps.onSelectionChange;
202
- },
203
- get isDisabled() {
204
- return stateProps.isDisabled;
205
- },
206
- get keyboardActivation() {
207
- return stateProps.keyboardActivation;
208
- },
209
- get orientation() {
210
- return stateProps.orientation;
211
- },
212
- });
213
-
214
- // Render props values
215
- const renderValues = createMemo<TabsRenderProps>(() => ({
216
- orientation: state.orientation(),
217
- isDisabled: state.isDisabled(),
218
- }));
219
-
220
- // Resolve render props
221
- const renderProps = useRenderProps(
222
- {
223
- class: local.class,
224
- style: local.style,
225
- children: props.children,
226
- defaultClassName: 'solidaria-Tabs',
227
- },
228
- renderValues
229
- );
230
-
231
- // Filter DOM props
232
- const domProps = createMemo(() => filterDOMProps(rest as Record<string, unknown>, { global: true }));
233
-
234
- return (
235
- <TabsContext.Provider value={{ state, items: stateProps.items ?? [] }}>
236
- <TabsStateContext.Provider value={state}>
237
- <div
238
- {...domProps()}
239
- class={renderProps.class()}
240
- style={renderProps.style()}
241
- data-orientation={state.orientation()}
242
- data-disabled={state.isDisabled() || undefined}
243
- >
244
- {props.children as JSX.Element}
245
- </div>
246
- </TabsStateContext.Provider>
247
- </TabsContext.Provider>
248
- );
249
- }
250
-
251
- /**
252
- * A TabList contains Tab elements that represent the available tabs.
253
- */
254
- export function TabList<T>(props: TabListProps<T>): JSX.Element {
255
- const [local, ariaProps] = splitProps(props, [
256
- 'class',
257
- 'style',
258
- 'slot',
259
- ]);
260
-
261
- // Get state from context
262
- const context = useContext(TabsContext);
263
-
264
- return (
265
- <Show
266
- when={context}
267
- fallback={<div class="solidaria-TabList" role="tablist" />}
268
- >
269
- {(ctx) => (
270
- <TabListInner
271
- context={ctx()}
272
- local={local}
273
- ariaProps={ariaProps}
274
- children={props.children}
275
- />
276
- )}
277
- </Show>
278
- );
279
- }
280
-
281
- /** Inner TabList component that has access to context */
282
- function TabListInner<T>(props: {
283
- context: TabsContextValue<unknown>;
284
- local: { class?: ClassNameOrFunction<TabListRenderProps>; style?: StyleOrFunction<TabListRenderProps>; slot?: string };
285
- ariaProps: Omit<TabListProps<T>, 'children' | 'class' | 'style' | 'slot'>;
286
- children?: (item: T) => JSX.Element;
287
- }): JSX.Element {
288
- const state = props.context.state as TabListState<T>;
289
- const items = props.context.items as T[];
290
-
291
- // Create tab list aria props
292
- const { tabListProps } = createTabList<T>(props.ariaProps as AriaTabListProps, state);
293
-
294
- // Create focus ring
295
- const { isFocused, isFocusVisible, focusProps } = createFocusRing();
296
-
297
- // Render props values
298
- const renderValues = createMemo<TabListRenderProps>(() => ({
299
- orientation: state.orientation(),
300
- isDisabled: state.isDisabled(),
301
- isFocused: state.isFocused() || isFocused(),
302
- isFocusVisible: isFocusVisible(),
303
- }));
304
-
305
- // Resolve render props
306
- const renderProps = useRenderProps(
307
- {
308
- class: props.local.class,
309
- style: props.local.style,
310
- defaultClassName: 'solidaria-TabList',
311
- },
312
- renderValues
313
- );
314
-
315
- // Helper to safely call event handlers that may be bound tuples
316
- const callHandler = <E extends Event>(
317
- handler: ((e: E) => void) | [object, (e: E) => void] | undefined,
318
- event: E
319
- ) => {
320
- if (!handler) return;
321
- if (Array.isArray(handler)) {
322
- handler[1].call(handler[0], event);
323
- } else {
324
- handler(event);
325
- }
326
- };
327
-
328
- // Combine event handlers
329
- const handleKeyDown = (e: KeyboardEvent) => {
330
- tabListProps.onKeyDown(e);
331
- };
332
-
333
- const handleFocus = (e: FocusEvent) => {
334
- tabListProps.onFocus(e);
335
- callHandler(focusProps.onFocus as any, e);
336
- };
337
-
338
- const handleBlur = (e: FocusEvent) => {
339
- tabListProps.onBlur(e);
340
- callHandler(focusProps.onBlur as any, e);
341
- };
342
-
343
- return (
344
- <div
345
- role={tabListProps.role}
346
- aria-orientation={tabListProps['aria-orientation']}
347
- aria-label={tabListProps['aria-label']}
348
- aria-labelledby={tabListProps['aria-labelledby']}
349
- aria-describedby={tabListProps['aria-describedby']}
350
- class={renderProps.class()}
351
- style={renderProps.style()}
352
- onKeyDown={handleKeyDown}
353
- onFocus={handleFocus}
354
- onBlur={handleBlur}
355
- data-focused={state.isFocused() || undefined}
356
- data-focus-visible={isFocusVisible() || undefined}
357
- data-orientation={state.orientation()}
358
- data-disabled={state.isDisabled() || undefined}
359
- >
360
- <For each={items}>{(item) => props.children?.(item)}</For>
361
- </div>
362
- );
363
- }
364
-
365
- /**
366
- * A Tab represents an individual tab in a TabList.
367
- */
368
- export function Tab(props: TabProps): JSX.Element {
369
- const [local, ariaProps] = splitProps(props, [
370
- 'class',
371
- 'style',
372
- 'slot',
373
- 'id',
374
- ]);
375
-
376
- // Get state from context
377
- const context = useContext(TabsStateContext);
378
-
379
- return (
380
- <Show
381
- when={context}
382
- fallback={<div class="solidaria-Tab" role="tab" />}
383
- >
384
- {(state) => (
385
- <TabInner
386
- state={state()}
387
- local={local}
388
- ariaProps={ariaProps}
389
- children={props.children}
390
- />
391
- )}
392
- </Show>
393
- );
394
- }
395
-
396
- /** Inner Tab component that has access to context */
397
- function TabInner(props: {
398
- state: TabListState<unknown>;
399
- local: { class?: ClassNameOrFunction<TabRenderProps>; style?: StyleOrFunction<TabRenderProps>; slot?: string; id: Key };
400
- ariaProps: Omit<TabProps, 'children' | 'class' | 'style' | 'slot' | 'id'>;
401
- children?: RenderChildren<TabRenderProps>;
402
- }): JSX.Element {
403
- // Create tab aria props
404
- const tabAria = createTab<unknown>(
405
- {
406
- key: props.local.id,
407
- get isDisabled() {
408
- return props.ariaProps.isDisabled;
409
- },
410
- get 'aria-label'() {
411
- return props.ariaProps['aria-label'];
412
- },
413
- },
414
- props.state
415
- );
416
-
417
- // Create hover
418
- const { isHovered, hoverProps } = createHover({
419
- get isDisabled() {
420
- return tabAria.isDisabled();
421
- },
422
- });
423
-
424
- // Render props values
425
- const renderValues = createMemo<TabRenderProps>(() => ({
426
- isSelected: tabAria.isSelected(),
427
- isFocused: tabAria.isFocused(),
428
- isFocusVisible: tabAria.isFocusVisible(),
429
- isPressed: tabAria.isPressed(),
430
- isHovered: isHovered(),
431
- isDisabled: tabAria.isDisabled(),
432
- }));
433
-
434
- // Resolve render props
435
- const renderProps = useRenderProps(
436
- {
437
- children: props.children,
438
- class: props.local.class,
439
- style: props.local.style,
440
- defaultClassName: 'solidaria-Tab',
441
- },
442
- renderValues
443
- );
444
-
445
- return (
446
- <div
447
- id={tabAria.tabProps.id}
448
- role={tabAria.tabProps.role}
449
- aria-selected={tabAria.isSelected()}
450
- aria-disabled={tabAria.isDisabled() || undefined}
451
- aria-controls={tabAria.isSelected() ? tabAria.tabProps['aria-controls'] : undefined}
452
- aria-label={tabAria.tabProps['aria-label']}
453
- tabIndex={tabAria.isSelected() && !tabAria.isDisabled() ? 0 : -1}
454
- class={renderProps.class()}
455
- style={renderProps.style()}
456
- onKeyDown={tabAria.tabProps.onKeyDown}
457
- onMouseDown={tabAria.tabProps.onMouseDown}
458
- onPointerDown={tabAria.tabProps.onPointerDown}
459
- onClick={tabAria.tabProps.onClick}
460
- onFocus={tabAria.tabProps.onFocus}
461
- {...hoverProps}
462
- data-selected={tabAria.isSelected() || undefined}
463
- data-focused={tabAria.isFocused() || undefined}
464
- data-focus-visible={tabAria.isFocusVisible() || undefined}
465
- data-pressed={tabAria.isPressed() || undefined}
466
- data-hovered={isHovered() || undefined}
467
- data-disabled={tabAria.isDisabled() || undefined}
468
- >
469
- {renderProps.renderChildren()}
470
- </div>
471
- );
472
- }
473
-
474
- /**
475
- * A TabPanel displays the content for a selected Tab.
476
- */
477
- export function TabPanel(props: TabPanelProps): JSX.Element {
478
- const [local, ariaProps] = splitProps(props, [
479
- 'class',
480
- 'style',
481
- 'slot',
482
- 'shouldForceMount',
483
- ]);
484
-
485
- // Get state from context (may be null for SSR scenarios)
486
- const state = useContext(TabsStateContext);
487
-
488
- // Create tab panel aria props
489
- const { tabPanelProps, isSelected } = createTabPanel<unknown>(ariaProps, state);
490
-
491
- // Create focus ring for the panel
492
- const { isFocused, isFocusVisible, focusProps } = createFocusRing();
493
-
494
- // Render props values
495
- const renderValues = createMemo<TabPanelRenderProps>(() => ({
496
- isSelected: isSelected(),
497
- isFocused: isFocused(),
498
- isFocusVisible: isFocusVisible(),
499
- }));
500
-
501
- // Resolve render props
502
- const renderProps = useRenderProps(
503
- {
504
- children: props.children,
505
- class: local.class,
506
- style: local.style,
507
- defaultClassName: 'solidaria-TabPanel',
508
- },
509
- renderValues
510
- );
511
-
512
- // Determine if we should render the panel
513
- // If no id is provided, render when any tab is selected (shared panel pattern)
514
- // If id is provided, render when that specific tab is selected
515
- const shouldRender = () => {
516
- if (local.shouldForceMount) return true;
517
- if (ariaProps.id === undefined) {
518
- // Shared panel pattern - render when any tab is selected
519
- return state ? state.selectedKey() !== null : true;
520
- }
521
- return isSelected();
522
- };
523
-
524
- return (
525
- <Show when={shouldRender()}>
526
- <div
527
- id={tabPanelProps.id}
528
- role={tabPanelProps.role}
529
- aria-labelledby={tabPanelProps['aria-labelledby']}
530
- aria-label={tabPanelProps['aria-label']}
531
- aria-describedby={tabPanelProps['aria-describedby']}
532
- tabIndex={tabPanelProps.tabIndex}
533
- class={renderProps.class()}
534
- style={renderProps.style()}
535
- onFocus={focusProps.onFocus}
536
- onBlur={focusProps.onBlur}
537
- data-selected={isSelected() || undefined}
538
- data-focused={isFocused() || undefined}
539
- data-focus-visible={isFocusVisible() || undefined}
540
- inert={ariaProps.id !== undefined && !isSelected() ? true : undefined}
541
- hidden={ariaProps.id !== undefined && !isSelected() && !local.shouldForceMount ? true : undefined}
542
- >
543
- {renderProps.renderChildren()}
544
- </div>
545
- </Show>
546
- );
547
- }
548
-
549
- // Attach sub-components
550
- Tabs.List = TabList;
551
- Tabs.Tab = Tab;
552
- Tabs.Panel = TabPanel;