@proyecto-viviana/solidaria-components 0.2.5 → 0.3.0

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 (225) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -272
  3. package/dist/ActionBar.d.ts +79 -0
  4. package/dist/ActionBar.d.ts.map +1 -0
  5. package/dist/ActionGroup.d.ts +74 -0
  6. package/dist/ActionGroup.d.ts.map +1 -0
  7. package/dist/Alert.d.ts +70 -0
  8. package/dist/Alert.d.ts.map +1 -0
  9. package/dist/Autocomplete.d.ts +5 -5
  10. package/dist/Autocomplete.d.ts.map +1 -1
  11. package/dist/Breadcrumbs.d.ts +27 -8
  12. package/dist/Breadcrumbs.d.ts.map +1 -1
  13. package/dist/Button.d.ts +28 -5
  14. package/dist/Button.d.ts.map +1 -1
  15. package/dist/Calendar.d.ts +51 -7
  16. package/dist/Calendar.d.ts.map +1 -1
  17. package/dist/Checkbox.d.ts +33 -8
  18. package/dist/Checkbox.d.ts.map +1 -1
  19. package/dist/Collection.d.ts +130 -0
  20. package/dist/Collection.d.ts.map +1 -0
  21. package/dist/Color.d.ts +210 -9
  22. package/dist/Color.d.ts.map +1 -1
  23. package/dist/ColorEditor.d.ts +42 -0
  24. package/dist/ColorEditor.d.ts.map +1 -0
  25. package/dist/ComboBox.d.ts +146 -16
  26. package/dist/ComboBox.d.ts.map +1 -1
  27. package/dist/ContextualHelpTrigger.d.ts +40 -0
  28. package/dist/ContextualHelpTrigger.d.ts.map +1 -0
  29. package/dist/DateField.d.ts +35 -8
  30. package/dist/DateField.d.ts.map +1 -1
  31. package/dist/DatePicker.d.ts +101 -5
  32. package/dist/DatePicker.d.ts.map +1 -1
  33. package/dist/DateRangePickerContext.d.ts +30 -0
  34. package/dist/DateRangePickerContext.d.ts.map +1 -0
  35. package/dist/Dialog.d.ts +5 -5
  36. package/dist/Dialog.d.ts.map +1 -1
  37. package/dist/Disclosure.d.ts +25 -5
  38. package/dist/Disclosure.d.ts.map +1 -1
  39. package/dist/DragAndDrop.d.ts +80 -0
  40. package/dist/DragAndDrop.d.ts.map +1 -0
  41. package/dist/DragPreview.d.ts +14 -0
  42. package/dist/DragPreview.d.ts.map +1 -0
  43. package/dist/DropZone.d.ts +27 -0
  44. package/dist/DropZone.d.ts.map +1 -0
  45. package/dist/FieldError.d.ts +27 -0
  46. package/dist/FieldError.d.ts.map +1 -0
  47. package/dist/FileTrigger.d.ts +26 -0
  48. package/dist/FileTrigger.d.ts.map +1 -0
  49. package/dist/Focusable.d.ts +27 -0
  50. package/dist/Focusable.d.ts.map +1 -0
  51. package/dist/Form.d.ts +41 -0
  52. package/dist/Form.d.ts.map +1 -0
  53. package/dist/GridList.d.ts +69 -10
  54. package/dist/GridList.d.ts.map +1 -1
  55. package/dist/HiddenDateInput.d.ts +26 -0
  56. package/dist/HiddenDateInput.d.ts.map +1 -0
  57. package/dist/HiddenTimeInput.d.ts +25 -0
  58. package/dist/HiddenTimeInput.d.ts.map +1 -0
  59. package/dist/Icon.d.ts +57 -0
  60. package/dist/Icon.d.ts.map +1 -0
  61. package/dist/Keyboard.d.ts +13 -0
  62. package/dist/Keyboard.d.ts.map +1 -0
  63. package/dist/Landmark.d.ts +3 -3
  64. package/dist/Landmark.d.ts.map +1 -1
  65. package/dist/Link.d.ts +10 -4
  66. package/dist/Link.d.ts.map +1 -1
  67. package/dist/ListBox.d.ts +73 -11
  68. package/dist/ListBox.d.ts.map +1 -1
  69. package/dist/ListDropTargetDelegate.d.ts +38 -0
  70. package/dist/ListDropTargetDelegate.d.ts.map +1 -0
  71. package/dist/Menu.d.ts +79 -10
  72. package/dist/Menu.d.ts.map +1 -1
  73. package/dist/Meter.d.ts +4 -4
  74. package/dist/Meter.d.ts.map +1 -1
  75. package/dist/Modal.d.ts +6 -4
  76. package/dist/Modal.d.ts.map +1 -1
  77. package/dist/NumberField.d.ts +10 -12
  78. package/dist/NumberField.d.ts.map +1 -1
  79. package/dist/Popover.d.ts +32 -7
  80. package/dist/Popover.d.ts.map +1 -1
  81. package/dist/Pressable.d.ts +27 -0
  82. package/dist/Pressable.d.ts.map +1 -0
  83. package/dist/ProgressBar.d.ts +6 -4
  84. package/dist/ProgressBar.d.ts.map +1 -1
  85. package/dist/RadioGroup.d.ts +43 -9
  86. package/dist/RadioGroup.d.ts.map +1 -1
  87. package/dist/RangeCalendar.d.ts +39 -7
  88. package/dist/RangeCalendar.d.ts.map +1 -1
  89. package/dist/RouterProvider.d.ts +75 -0
  90. package/dist/RouterProvider.d.ts.map +1 -0
  91. package/dist/SearchField.d.ts +23 -21
  92. package/dist/SearchField.d.ts.map +1 -1
  93. package/dist/Select.d.ts +48 -7
  94. package/dist/Select.d.ts.map +1 -1
  95. package/dist/SelectionIndicator.d.ts +30 -0
  96. package/dist/SelectionIndicator.d.ts.map +1 -0
  97. package/dist/Separator.d.ts +9 -3
  98. package/dist/Separator.d.ts.map +1 -1
  99. package/dist/SharedElementTransition.d.ts +41 -0
  100. package/dist/SharedElementTransition.d.ts.map +1 -0
  101. package/dist/Slider.d.ts +15 -8
  102. package/dist/Slider.d.ts.map +1 -1
  103. package/dist/StepList.d.ts +90 -0
  104. package/dist/StepList.d.ts.map +1 -0
  105. package/dist/Switch.d.ts +11 -5
  106. package/dist/Switch.d.ts.map +1 -1
  107. package/dist/Table.d.ts +222 -19
  108. package/dist/Table.d.ts.map +1 -1
  109. package/dist/Tabs.d.ts +47 -10
  110. package/dist/Tabs.d.ts.map +1 -1
  111. package/dist/TagGroup.d.ts +22 -10
  112. package/dist/TagGroup.d.ts.map +1 -1
  113. package/dist/Text.d.ts +10 -0
  114. package/dist/Text.d.ts.map +1 -0
  115. package/dist/TextField.d.ts +19 -11
  116. package/dist/TextField.d.ts.map +1 -1
  117. package/dist/TimeField.d.ts +32 -7
  118. package/dist/TimeField.d.ts.map +1 -1
  119. package/dist/Toast.d.ts +29 -14
  120. package/dist/Toast.d.ts.map +1 -1
  121. package/dist/ToggleButton.d.ts +36 -0
  122. package/dist/ToggleButton.d.ts.map +1 -0
  123. package/dist/ToggleButtonGroup.d.ts +33 -0
  124. package/dist/ToggleButtonGroup.d.ts.map +1 -0
  125. package/dist/Toolbar.d.ts +7 -3
  126. package/dist/Toolbar.d.ts.map +1 -1
  127. package/dist/Tooltip.d.ts +58 -7
  128. package/dist/Tooltip.d.ts.map +1 -1
  129. package/dist/Tree.d.ts +102 -11
  130. package/dist/Tree.d.ts.map +1 -1
  131. package/dist/Virtualizer.d.ts +61 -0
  132. package/dist/Virtualizer.d.ts.map +1 -0
  133. package/dist/VirtualizerLayouts.d.ts +82 -0
  134. package/dist/VirtualizerLayouts.d.ts.map +1 -0
  135. package/dist/VisuallyHidden.d.ts +4 -2
  136. package/dist/VisuallyHidden.d.ts.map +1 -1
  137. package/dist/contexts.d.ts +6 -1
  138. package/dist/contexts.d.ts.map +1 -1
  139. package/dist/index.d.ts +73 -39
  140. package/dist/index.d.ts.map +1 -1
  141. package/dist/index.js +23342 -10644
  142. package/dist/index.js.map +1 -7
  143. package/dist/index.jsx +18110 -0
  144. package/dist/index.jsx.map +1 -0
  145. package/dist/useDragAndDrop.d.ts +93 -0
  146. package/dist/useDragAndDrop.d.ts.map +1 -0
  147. package/dist/utils.d.ts +8 -2
  148. package/dist/utils.d.ts.map +1 -1
  149. package/dist/virtualizer/Layout.d.ts +79 -0
  150. package/dist/virtualizer/Layout.d.ts.map +1 -0
  151. package/package.json +33 -32
  152. package/src/ActionBar.tsx +251 -0
  153. package/src/ActionGroup.tsx +277 -0
  154. package/src/Alert.tsx +152 -0
  155. package/src/Autocomplete.tsx +39 -44
  156. package/src/Breadcrumbs.tsx +227 -72
  157. package/src/Button.tsx +315 -74
  158. package/src/Calendar.tsx +347 -141
  159. package/src/Checkbox.tsx +414 -123
  160. package/src/Collection.tsx +350 -0
  161. package/src/Color.tsx +1325 -284
  162. package/src/ColorEditor.tsx +213 -0
  163. package/src/ComboBox.tsx +644 -245
  164. package/src/ContextualHelpTrigger.tsx +195 -0
  165. package/src/DateField.tsx +274 -106
  166. package/src/DatePicker.tsx +892 -111
  167. package/src/DateRangePickerContext.tsx +44 -0
  168. package/src/Dialog.tsx +173 -104
  169. package/src/Disclosure.tsx +158 -105
  170. package/src/DragAndDrop.tsx +340 -0
  171. package/src/DragPreview.tsx +47 -0
  172. package/src/DropZone.tsx +233 -0
  173. package/src/FieldError.tsx +89 -0
  174. package/src/FileTrigger.tsx +83 -0
  175. package/src/Focusable.tsx +103 -0
  176. package/src/Form.tsx +140 -0
  177. package/src/GridList.tsx +542 -128
  178. package/src/HiddenDateInput.tsx +153 -0
  179. package/src/HiddenTimeInput.tsx +133 -0
  180. package/src/Icon.tsx +133 -0
  181. package/src/Keyboard.tsx +26 -0
  182. package/src/Landmark.tsx +37 -63
  183. package/src/Link.tsx +132 -69
  184. package/src/ListBox.tsx +656 -106
  185. package/src/ListDropTargetDelegate.ts +283 -0
  186. package/src/Menu.tsx +1234 -132
  187. package/src/Meter.tsx +44 -58
  188. package/src/Modal.tsx +262 -166
  189. package/src/NumberField.tsx +267 -151
  190. package/src/Popover.tsx +452 -343
  191. package/src/Pressable.tsx +108 -0
  192. package/src/ProgressBar.tsx +54 -59
  193. package/src/RadioGroup.tsx +533 -121
  194. package/src/RangeCalendar.tsx +249 -150
  195. package/src/RouterProvider.tsx +223 -0
  196. package/src/SearchField.tsx +460 -133
  197. package/src/Select.tsx +804 -233
  198. package/src/SelectionIndicator.tsx +108 -0
  199. package/src/Separator.tsx +47 -49
  200. package/src/SharedElementTransition.tsx +264 -0
  201. package/src/Slider.tsx +148 -98
  202. package/src/StepList.tsx +272 -0
  203. package/src/Switch.tsx +93 -46
  204. package/src/Table.tsx +1551 -225
  205. package/src/Tabs.tsx +377 -123
  206. package/src/TagGroup.tsx +233 -135
  207. package/src/Text.tsx +18 -0
  208. package/src/TextField.tsx +413 -86
  209. package/src/TimeField.tsx +232 -222
  210. package/src/Toast.tsx +306 -160
  211. package/src/ToggleButton.tsx +169 -0
  212. package/src/ToggleButtonGroup.tsx +141 -0
  213. package/src/Toolbar.tsx +61 -70
  214. package/src/Tooltip.tsx +473 -116
  215. package/src/Tree.tsx +1514 -175
  216. package/src/Virtualizer.tsx +730 -0
  217. package/src/VirtualizerLayouts.ts +280 -0
  218. package/src/VisuallyHidden.tsx +32 -38
  219. package/src/contexts.ts +29 -36
  220. package/src/index.ts +972 -620
  221. package/src/useDragAndDrop.ts +367 -0
  222. package/src/utils.tsx +69 -50
  223. package/src/virtualizer/Layout.ts +192 -0
  224. package/dist/index.ssr.js +0 -9785
  225. package/dist/index.ssr.js.map +0 -7
@@ -6,19 +6,28 @@
6
6
  */
7
7
 
8
8
  import {
9
+ type Accessor,
9
10
  type JSX,
10
11
  createContext,
11
12
  createMemo,
13
+ createSignal,
14
+ children as resolveChildren,
12
15
  splitProps,
13
16
  useContext,
14
17
  For,
15
- } from 'solid-js';
18
+ Show,
19
+ } from "solid-js";
20
+ import { Dynamic } from "solid-js/web";
16
21
  import {
17
22
  createBreadcrumbs,
18
23
  createBreadcrumbItem,
24
+ createFocusRing,
25
+ createHover,
26
+ mergeProps,
19
27
  type AriaBreadcrumbsProps,
20
28
  type AriaBreadcrumbItemProps,
21
- } from '@proyecto-viviana/solidaria';
29
+ type PressEvent,
30
+ } from "@proyecto-viviana/solidaria";
22
31
  import {
23
32
  type RenderChildren,
24
33
  type ClassNameOrFunction,
@@ -26,30 +35,44 @@ import {
26
35
  type SlotProps,
27
36
  useRenderProps,
28
37
  filterDOMProps,
29
- } from './utils';
38
+ } from "./utils";
30
39
 
31
- // ============================================
32
- // TYPES
33
- // ============================================
40
+ type RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;
41
+
42
+ function assignRef<T>(ref: RefLike<T>, el: T): void {
43
+ if (!ref) {
44
+ return;
45
+ }
46
+
47
+ if (typeof ref === "function") {
48
+ ref(el);
49
+ } else {
50
+ ref.current = el;
51
+ }
52
+ }
34
53
 
35
54
  export interface BreadcrumbsRenderProps {
36
55
  /** Whether the breadcrumbs are disabled. */
37
56
  isDisabled: boolean;
38
57
  }
39
58
 
40
- export interface BreadcrumbsProps<T> extends Omit<AriaBreadcrumbsProps, 'isDisabled'>, SlotProps {
59
+ export interface BreadcrumbsProps<T> extends Omit<AriaBreadcrumbsProps, "isDisabled">, SlotProps {
41
60
  /** The items to render in the breadcrumbs. */
42
61
  items?: T[];
43
62
  /** Function to get the key from an item. */
44
63
  getKey?: (item: T) => string | number;
45
64
  /** Whether the breadcrumbs are disabled. */
46
65
  isDisabled?: boolean;
47
- /** The children of the component - render function for each item. */
48
- children: (item: T) => JSX.Element;
66
+ /** Handler called when a breadcrumb item is activated. */
67
+ onAction?: (key: string | number) => void;
68
+ /** The children of the component, or a render function for collection items. */
69
+ children?: JSX.Element | ((item: T) => JSX.Element);
49
70
  /** The CSS className for the element. */
50
71
  class?: ClassNameOrFunction<BreadcrumbsRenderProps>;
51
72
  /** The inline style for the element. */
52
73
  style?: StyleOrFunction<BreadcrumbsRenderProps>;
74
+ /** Ref for the navigation element. */
75
+ ref?: RefLike<HTMLElement>;
53
76
  }
54
77
 
55
78
  export interface BreadcrumbItemRenderProps {
@@ -67,7 +90,8 @@ export interface BreadcrumbItemRenderProps {
67
90
  isHovered: boolean;
68
91
  }
69
92
 
70
- export interface BreadcrumbItemProps extends Omit<AriaBreadcrumbItemProps, 'isDisabled'>, SlotProps {
93
+ export interface BreadcrumbItemProps
94
+ extends Omit<AriaBreadcrumbItemProps, "isDisabled">, SlotProps {
71
95
  /** The children of the breadcrumb item. */
72
96
  children?: RenderChildren<BreadcrumbItemRenderProps>;
73
97
  /** The CSS className for the element. */
@@ -76,21 +100,32 @@ export interface BreadcrumbItemProps extends Omit<AriaBreadcrumbItemProps, 'isDi
76
100
  style?: StyleOrFunction<BreadcrumbItemRenderProps>;
77
101
  /** Whether this item is disabled. */
78
102
  isDisabled?: boolean;
103
+ /** Ref for the breadcrumb item element. */
104
+ ref?: RefLike<HTMLElement>;
79
105
  }
80
106
 
81
- // ============================================
82
- // CONTEXT
83
- // ============================================
84
-
85
107
  interface BreadcrumbsContextValue {
86
- isDisabled: boolean;
108
+ isDisabled: Accessor<boolean>;
109
+ onAction?: (key: string | number) => void;
110
+ registerStaticItem?: () => number;
111
+ staticItemCount?: Accessor<number>;
112
+ resetStaticItems?: () => void;
113
+ setStaticItemCount?: (count: number) => void;
87
114
  }
88
115
 
89
116
  export const BreadcrumbsContext = createContext<BreadcrumbsContextValue | null>(null);
90
117
 
91
- // ============================================
92
- // COMPONENTS
93
- // ============================================
118
+ interface BreadcrumbItemContextValue {
119
+ itemKey: string | number | null;
120
+ isLast: Accessor<boolean>;
121
+ }
122
+
123
+ export const BreadcrumbItemContext = createContext<BreadcrumbItemContextValue | null>(null);
124
+
125
+ function defaultItemKey(item: unknown, index: number): string | number {
126
+ const maybeItem = item as { key?: string | number; id?: string | number };
127
+ return maybeItem.key ?? maybeItem.id ?? index;
128
+ }
94
129
 
95
130
  /**
96
131
  * Breadcrumbs show hierarchy and navigational context for a user's location within an application.
@@ -98,88 +133,162 @@ export const BreadcrumbsContext = createContext<BreadcrumbsContextValue | null>(
98
133
  export function Breadcrumbs<T>(props: BreadcrumbsProps<T>): JSX.Element {
99
134
  const [local, ariaProps, rest] = splitProps(
100
135
  props,
101
- ['children', 'class', 'style', 'slot', 'items', 'getKey', 'isDisabled'],
102
- ['aria-label', 'aria-labelledby', 'aria-describedby']
136
+ ["children", "class", "style", "slot", "items", "getKey", "isDisabled", "onAction", "ref"],
137
+ ["aria-label", "aria-labelledby", "aria-describedby", "aria-details"],
103
138
  );
104
139
 
105
140
  const isDisabled = () => local.isDisabled ?? false;
106
141
  const items = () => local.items ?? [];
142
+ const hasCollectionItems = () => local.items !== undefined;
143
+ const getItemKey = (item: T, index: number): string | number =>
144
+ local.getKey?.(item) ?? defaultItemKey(item, index);
145
+ const [staticItemCount, setStaticItemCount] = createSignal(0);
146
+ let nextStaticIndex = 0;
147
+ const resetStaticItems = () => {
148
+ nextStaticIndex = 0;
149
+ setStaticItemCount(0);
150
+ };
151
+ const registerStaticItem = () => {
152
+ const index = nextStaticIndex;
153
+ nextStaticIndex += 1;
154
+ return index;
155
+ };
107
156
 
108
- // Create breadcrumbs aria props
109
157
  const { navProps } = createBreadcrumbs({
110
- get 'aria-label'() {
111
- return ariaProps['aria-label'];
158
+ get "aria-label"() {
159
+ return ariaProps["aria-label"];
112
160
  },
113
- get 'aria-labelledby'() {
114
- return ariaProps['aria-labelledby'];
161
+ get "aria-labelledby"() {
162
+ return ariaProps["aria-labelledby"];
115
163
  },
116
- get 'aria-describedby'() {
117
- return ariaProps['aria-describedby'];
164
+ get "aria-describedby"() {
165
+ return ariaProps["aria-describedby"];
118
166
  },
119
167
  get isDisabled() {
120
168
  return isDisabled();
121
169
  },
122
170
  });
123
171
 
124
- // Render props values
125
172
  const renderValues = createMemo<BreadcrumbsRenderProps>(() => ({
126
173
  isDisabled: isDisabled(),
127
174
  }));
128
175
 
129
- // Resolve render props
130
176
  const renderProps = useRenderProps(
131
177
  {
132
178
  class: local.class,
133
179
  style: local.style,
134
- defaultClassName: 'solidaria-Breadcrumbs',
180
+ defaultClassName: "solidaria-Breadcrumbs",
135
181
  },
136
- renderValues
182
+ renderValues,
137
183
  );
138
184
 
139
- // Filter DOM props
140
- const domProps = createMemo(() => filterDOMProps(rest as Record<string, unknown>, { global: true }));
141
-
185
+ const domProps = createMemo(() =>
186
+ filterDOMProps(rest as Record<string, unknown>, { global: true }),
187
+ );
142
188
  return (
143
- <BreadcrumbsContext.Provider value={{ isDisabled: isDisabled() }}>
189
+ <BreadcrumbsContext.Provider
190
+ value={{
191
+ isDisabled,
192
+ onAction: local.onAction,
193
+ registerStaticItem,
194
+ staticItemCount,
195
+ resetStaticItems,
196
+ setStaticItemCount,
197
+ }}
198
+ >
144
199
  <nav
145
200
  {...navProps}
146
201
  {...domProps()}
202
+ ref={(element) => assignRef(local.ref, element)}
147
203
  class={renderProps.class()}
148
204
  style={renderProps.style()}
149
205
  data-disabled={isDisabled() || undefined}
150
206
  >
151
- <ol style={{ display: 'flex', 'align-items': 'center', 'list-style': 'none', margin: 0, padding: 0 }}>
152
- <For each={items()}>
153
- {(item) => (
154
- <li style={{ display: 'flex', 'align-items': 'center' }}>
155
- {props.children(item)}
156
- </li>
157
- )}
158
- </For>
207
+ <ol
208
+ style={{
209
+ display: "flex",
210
+ "align-items": "center",
211
+ "list-style": "none",
212
+ margin: 0,
213
+ padding: 0,
214
+ }}
215
+ >
216
+ <Show
217
+ when={hasCollectionItems()}
218
+ fallback={
219
+ <StaticBreadcrumbItems>{local.children as JSX.Element}</StaticBreadcrumbItems>
220
+ }
221
+ >
222
+ <For each={items()}>
223
+ {(item, index) => {
224
+ const itemKey = getItemKey(item, index());
225
+ const isLast = () => index() === items().length - 1;
226
+ const renderItem = local.children as ((item: T) => JSX.Element) | undefined;
227
+
228
+ return (
229
+ <li style={{ display: "flex", "align-items": "center" }}>
230
+ <BreadcrumbItemContext.Provider value={{ itemKey, isLast }}>
231
+ {renderItem?.(item)}
232
+ </BreadcrumbItemContext.Provider>
233
+ </li>
234
+ );
235
+ }}
236
+ </For>
237
+ </Show>
159
238
  </ol>
160
239
  </nav>
161
240
  </BreadcrumbsContext.Provider>
162
241
  );
163
242
  }
164
243
 
244
+ function StaticBreadcrumbItems(props: { children?: JSX.Element }): JSX.Element {
245
+ const context = useContext(BreadcrumbsContext);
246
+ const staticChildren = resolveChildren(() => props.children);
247
+ const childArray = createMemo(() => {
248
+ context?.resetStaticItems?.();
249
+ const array = staticChildren.toArray();
250
+ context?.setStaticItemCount?.(array.length);
251
+ return array;
252
+ });
253
+
254
+ return (
255
+ <For each={childArray()}>
256
+ {(child) => <li style={{ display: "flex", "align-items": "center" }}>{child}</li>}
257
+ </For>
258
+ );
259
+ }
260
+
165
261
  /**
166
262
  * A BreadcrumbItem represents an individual breadcrumb in the navigation trail.
167
263
  */
168
264
  export function BreadcrumbItem(props: BreadcrumbItemProps): JSX.Element {
169
- const [local, ariaProps] = splitProps(props, [
170
- 'class',
171
- 'style',
172
- 'slot',
173
- 'isDisabled',
174
- ]);
175
-
176
- // Get context
265
+ const [local, ariaProps] = splitProps(props, ["class", "style", "slot", "isDisabled", "ref"]);
266
+
177
267
  const context = useContext(BreadcrumbsContext);
178
- const isDisabled = () => local.isDisabled ?? context?.isDisabled ?? false;
179
- const isCurrent = () => ariaProps.isCurrent ?? false;
268
+ const itemContext = useContext(BreadcrumbItemContext);
269
+ const staticIndex = itemContext ? null : context?.registerStaticItem?.();
270
+ const isDisabled = () => local.isDisabled ?? context?.isDisabled() ?? false;
271
+ const isCurrent = () =>
272
+ ariaProps.isCurrent ??
273
+ itemContext?.isLast() ??
274
+ (staticIndex !== null &&
275
+ staticIndex !== undefined &&
276
+ context?.staticItemCount !== undefined &&
277
+ staticIndex === context.staticItemCount() - 1);
278
+ const itemKey = () => itemContext?.itemKey ?? ariaProps.id ?? null;
279
+
280
+ const handlePress = (e: PressEvent) => {
281
+ ariaProps.onPress?.(e);
282
+ const key = itemKey();
283
+ if (key !== null && !isCurrent() && !isDisabled()) {
284
+ context?.onAction?.(key);
285
+ }
286
+ };
180
287
 
181
- // Create breadcrumb item aria props
182
288
  const { itemProps, isPressed } = createBreadcrumbItem({
289
+ get id() {
290
+ return ariaProps.id;
291
+ },
183
292
  get isCurrent() {
184
293
  return isCurrent();
185
294
  },
@@ -199,7 +308,7 @@ export function BreadcrumbItem(props: BreadcrumbItemProps): JSX.Element {
199
308
  return ariaProps.elementType;
200
309
  },
201
310
  get onPress() {
202
- return ariaProps.onPress;
311
+ return handlePress;
203
312
  },
204
313
  get onPressStart() {
205
314
  return ariaProps.onPressStart;
@@ -210,55 +319,101 @@ export function BreadcrumbItem(props: BreadcrumbItemProps): JSX.Element {
210
319
  get onClick() {
211
320
  return ariaProps.onClick;
212
321
  },
213
- get 'aria-label'() {
214
- return ariaProps['aria-label'];
322
+ get onFocus() {
323
+ return ariaProps.onFocus;
324
+ },
325
+ get onBlur() {
326
+ return ariaProps.onBlur;
327
+ },
328
+ get onFocusChange() {
329
+ return ariaProps.onFocusChange;
330
+ },
331
+ get onKeyDown() {
332
+ return ariaProps.onKeyDown;
333
+ },
334
+ get onKeyUp() {
335
+ return ariaProps.onKeyUp;
336
+ },
337
+ get autoFocus() {
338
+ return ariaProps.autoFocus;
215
339
  },
216
- get 'aria-current'() {
217
- return ariaProps['aria-current'];
340
+ get "aria-label"() {
341
+ return ariaProps["aria-label"];
342
+ },
343
+ get "aria-labelledby"() {
344
+ return ariaProps["aria-labelledby"];
345
+ },
346
+ get "aria-describedby"() {
347
+ return ariaProps["aria-describedby"];
348
+ },
349
+ get "aria-details"() {
350
+ return ariaProps["aria-details"];
351
+ },
352
+ get "aria-current"() {
353
+ return ariaProps["aria-current"];
354
+ },
355
+ });
356
+
357
+ const { isFocused, isFocusVisible, focusProps } = createFocusRing();
358
+ const { isHovered, hoverProps } = createHover({
359
+ get isDisabled() {
360
+ return isDisabled();
218
361
  },
219
362
  });
363
+ const mergedItemProps = createMemo(() =>
364
+ mergeProps(
365
+ itemProps as Record<string, unknown>,
366
+ focusProps as Record<string, unknown>,
367
+ hoverProps as Record<string, unknown>,
368
+ ),
369
+ );
370
+ const elementType = () => ariaProps.elementType ?? "a";
220
371
 
221
- // Render props values
222
372
  const renderValues = createMemo<BreadcrumbItemRenderProps>(() => ({
223
373
  isCurrent: isCurrent(),
224
374
  isDisabled: isDisabled(),
225
375
  isPressed: isPressed(),
226
- isFocused: false, // Would need focus tracking
227
- isFocusVisible: false, // Would need focus visible tracking
228
- isHovered: false, // Would need hover tracking
376
+ isFocused: isFocused(),
377
+ isFocusVisible: isFocusVisible(),
378
+ isHovered: isHovered(),
229
379
  }));
230
380
 
231
- // Resolve render props
232
381
  const renderProps = useRenderProps(
233
382
  {
234
383
  children: props.children,
235
384
  class: local.class,
236
385
  style: local.style,
237
- defaultClassName: 'solidaria-BreadcrumbItem',
386
+ defaultClassName: "solidaria-BreadcrumbItem",
238
387
  },
239
- renderValues
388
+ renderValues,
240
389
  );
241
390
 
242
- // Merge inline flex styles with user styles
243
391
  const mergedStyle = () => {
244
392
  const userStyle = renderProps.style();
245
- const baseStyle = { display: 'inline-flex', 'align-items': 'center' };
393
+ const baseStyle = { display: "inline-flex", "align-items": "center" };
246
394
  return userStyle ? { ...baseStyle, ...userStyle } : baseStyle;
247
395
  };
248
396
 
249
397
  return (
250
- <a
251
- {...(itemProps as Record<string, unknown>)}
398
+ <Dynamic
399
+ component={elementType()}
400
+ {...mergedItemProps()}
401
+ ref={(element: HTMLElement) => assignRef(local.ref, element)}
402
+ href={isCurrent() ? undefined : (mergedItemProps() as { href?: string }).href}
403
+ aria-current={isCurrent() ? (ariaProps["aria-current"] ?? "page") : undefined}
404
+ aria-disabled={isDisabled() || isCurrent() || undefined}
252
405
  class={renderProps.class()}
253
406
  style={mergedStyle()}
254
407
  data-current={isCurrent() || undefined}
255
408
  data-disabled={isDisabled() || undefined}
256
409
  data-pressed={isPressed() || undefined}
410
+ data-focused={isFocused() || undefined}
411
+ data-focus-visible={isFocusVisible() || undefined}
412
+ data-hovered={isHovered() || undefined}
257
413
  >
258
414
  {renderProps.renderChildren()}
259
- </a>
415
+ </Dynamic>
260
416
  );
261
417
  }
262
418
 
263
- // Attach sub-components
264
419
  Breadcrumbs.Item = BreadcrumbItem;