@proyecto-viviana/solidaria 0.2.2 → 0.2.4

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 (210) hide show
  1. package/dist/autocomplete/createAutocomplete.d.ts +2 -2
  2. package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
  3. package/dist/index.js +233 -234
  4. package/dist/index.js.map +2 -2
  5. package/dist/index.ssr.js +233 -234
  6. package/dist/index.ssr.js.map +2 -2
  7. package/dist/interactions/PressEvent.d.ts +13 -10
  8. package/dist/interactions/PressEvent.d.ts.map +1 -1
  9. package/dist/interactions/createPress.d.ts.map +1 -1
  10. package/dist/interactions/index.d.ts +1 -1
  11. package/dist/interactions/index.d.ts.map +1 -1
  12. package/dist/select/createHiddenSelect.d.ts.map +1 -1
  13. package/dist/toolbar/createToolbar.d.ts.map +1 -1
  14. package/dist/tooltip/createTooltipTrigger.d.ts.map +1 -1
  15. package/package.json +9 -7
  16. package/src/autocomplete/createAutocomplete.ts +341 -0
  17. package/src/autocomplete/index.ts +9 -0
  18. package/src/breadcrumbs/createBreadcrumbs.ts +196 -0
  19. package/src/breadcrumbs/index.ts +8 -0
  20. package/src/button/createButton.ts +142 -0
  21. package/src/button/createToggleButton.ts +101 -0
  22. package/src/button/index.ts +4 -0
  23. package/src/button/types.ts +78 -0
  24. package/src/calendar/createCalendar.ts +138 -0
  25. package/src/calendar/createCalendarCell.ts +187 -0
  26. package/src/calendar/createCalendarGrid.ts +140 -0
  27. package/src/calendar/createRangeCalendar.ts +136 -0
  28. package/src/calendar/createRangeCalendarCell.ts +186 -0
  29. package/src/calendar/index.ts +34 -0
  30. package/src/checkbox/createCheckbox.ts +135 -0
  31. package/src/checkbox/createCheckboxGroup.ts +137 -0
  32. package/src/checkbox/createCheckboxGroupItem.ts +117 -0
  33. package/src/checkbox/createCheckboxGroupState.ts +193 -0
  34. package/src/checkbox/index.ts +13 -0
  35. package/src/color/createColorArea.ts +314 -0
  36. package/src/color/createColorField.ts +137 -0
  37. package/src/color/createColorSlider.ts +197 -0
  38. package/src/color/createColorSwatch.ts +40 -0
  39. package/src/color/createColorWheel.ts +208 -0
  40. package/src/color/index.ts +24 -0
  41. package/src/color/types.ts +116 -0
  42. package/src/combobox/createComboBox.ts +647 -0
  43. package/src/combobox/index.ts +6 -0
  44. package/src/combobox/intl/en-US.json +7 -0
  45. package/src/combobox/intl/es-ES.json +7 -0
  46. package/src/combobox/intl/index.ts +23 -0
  47. package/src/datepicker/createDateField.ts +154 -0
  48. package/src/datepicker/createDatePicker.ts +206 -0
  49. package/src/datepicker/createDateSegment.ts +229 -0
  50. package/src/datepicker/createTimeField.ts +154 -0
  51. package/src/datepicker/index.ts +28 -0
  52. package/src/dialog/createDialog.ts +120 -0
  53. package/src/dialog/index.ts +2 -0
  54. package/src/dialog/types.ts +19 -0
  55. package/src/disclosure/createDisclosure.ts +131 -0
  56. package/src/disclosure/createDisclosureGroup.ts +62 -0
  57. package/src/disclosure/index.ts +11 -0
  58. package/src/dnd/createDrag.ts +209 -0
  59. package/src/dnd/createDraggableCollection.ts +63 -0
  60. package/src/dnd/createDraggableItem.ts +243 -0
  61. package/src/dnd/createDrop.ts +321 -0
  62. package/src/dnd/createDroppableCollection.ts +293 -0
  63. package/src/dnd/createDroppableItem.ts +213 -0
  64. package/src/dnd/index.ts +47 -0
  65. package/src/dnd/types.ts +89 -0
  66. package/src/dnd/utils.ts +294 -0
  67. package/src/focus/FocusScope.tsx +408 -0
  68. package/src/focus/createAutoFocus.ts +321 -0
  69. package/src/focus/createFocusRestore.ts +313 -0
  70. package/src/focus/createVirtualFocus.ts +396 -0
  71. package/src/focus/index.ts +35 -0
  72. package/src/form/createFormReset.ts +51 -0
  73. package/src/form/createFormValidation.ts +224 -0
  74. package/src/form/index.ts +11 -0
  75. package/src/grid/GridKeyboardDelegate.ts +429 -0
  76. package/src/grid/createGrid.ts +261 -0
  77. package/src/grid/createGridCell.ts +182 -0
  78. package/src/grid/createGridRow.ts +153 -0
  79. package/src/grid/index.ts +18 -0
  80. package/src/grid/types.ts +133 -0
  81. package/src/gridlist/createGridList.ts +185 -0
  82. package/src/gridlist/createGridListItem.ts +180 -0
  83. package/src/gridlist/createGridListSelectionCheckbox.ts +59 -0
  84. package/src/gridlist/index.ts +16 -0
  85. package/src/gridlist/types.ts +81 -0
  86. package/src/i18n/NumberFormatter.ts +266 -0
  87. package/src/i18n/createCollator.ts +79 -0
  88. package/src/i18n/createDateFormatter.ts +83 -0
  89. package/src/i18n/createFilter.ts +131 -0
  90. package/src/i18n/createNumberFormatter.ts +52 -0
  91. package/src/i18n/createStringFormatter.ts +87 -0
  92. package/src/i18n/index.ts +40 -0
  93. package/src/i18n/locale.tsx +188 -0
  94. package/src/i18n/utils.ts +99 -0
  95. package/src/index.ts +670 -0
  96. package/src/interactions/FocusableProvider.tsx +44 -0
  97. package/src/interactions/PressEvent.ts +126 -0
  98. package/src/interactions/createFocus.ts +163 -0
  99. package/src/interactions/createFocusRing.ts +89 -0
  100. package/src/interactions/createFocusWithin.ts +206 -0
  101. package/src/interactions/createFocusable.ts +168 -0
  102. package/src/interactions/createHover.ts +254 -0
  103. package/src/interactions/createInteractionModality.ts +424 -0
  104. package/src/interactions/createKeyboard.ts +82 -0
  105. package/src/interactions/createLongPress.ts +174 -0
  106. package/src/interactions/createMove.ts +289 -0
  107. package/src/interactions/createPress.ts +834 -0
  108. package/src/interactions/index.ts +78 -0
  109. package/src/label/createField.ts +145 -0
  110. package/src/label/createLabel.ts +117 -0
  111. package/src/label/createLabels.ts +50 -0
  112. package/src/label/index.ts +19 -0
  113. package/src/landmark/createLandmark.ts +377 -0
  114. package/src/landmark/index.ts +8 -0
  115. package/src/link/createLink.ts +182 -0
  116. package/src/link/index.ts +1 -0
  117. package/src/listbox/createListBox.ts +269 -0
  118. package/src/listbox/createOption.ts +151 -0
  119. package/src/listbox/index.ts +12 -0
  120. package/src/live-announcer/announce.ts +322 -0
  121. package/src/live-announcer/index.ts +9 -0
  122. package/src/menu/createMenu.ts +396 -0
  123. package/src/menu/createMenuItem.ts +149 -0
  124. package/src/menu/createMenuTrigger.ts +88 -0
  125. package/src/menu/index.ts +18 -0
  126. package/src/meter/createMeter.ts +75 -0
  127. package/src/meter/index.ts +1 -0
  128. package/src/numberfield/createNumberField.ts +268 -0
  129. package/src/numberfield/index.ts +5 -0
  130. package/src/overlays/ariaHideOutside.ts +219 -0
  131. package/src/overlays/createInteractOutside.ts +149 -0
  132. package/src/overlays/createModal.tsx +202 -0
  133. package/src/overlays/createOverlay.ts +155 -0
  134. package/src/overlays/createOverlayTrigger.ts +85 -0
  135. package/src/overlays/createPreventScroll.ts +266 -0
  136. package/src/overlays/index.ts +44 -0
  137. package/src/popover/calculatePosition.ts +766 -0
  138. package/src/popover/createOverlayPosition.ts +356 -0
  139. package/src/popover/createPopover.ts +170 -0
  140. package/src/popover/index.ts +24 -0
  141. package/src/progress/createProgressBar.ts +128 -0
  142. package/src/progress/index.ts +5 -0
  143. package/src/radio/createRadio.ts +287 -0
  144. package/src/radio/createRadioGroup.ts +189 -0
  145. package/src/radio/createRadioGroupState.ts +201 -0
  146. package/src/radio/index.ts +23 -0
  147. package/src/searchfield/createSearchField.ts +186 -0
  148. package/src/searchfield/index.ts +2 -0
  149. package/src/select/createHiddenSelect.tsx +236 -0
  150. package/src/select/createSelect.ts +395 -0
  151. package/src/select/index.ts +14 -0
  152. package/src/selection/createTypeSelect.ts +201 -0
  153. package/src/selection/index.ts +6 -0
  154. package/src/separator/createSeparator.ts +82 -0
  155. package/src/separator/index.ts +6 -0
  156. package/src/slider/createSlider.ts +349 -0
  157. package/src/slider/index.ts +2 -0
  158. package/src/ssr/index.tsx +370 -0
  159. package/src/switch/createSwitch.ts +70 -0
  160. package/src/switch/index.ts +1 -0
  161. package/src/table/createTable.ts +526 -0
  162. package/src/table/createTableCell.ts +147 -0
  163. package/src/table/createTableColumnHeader.ts +115 -0
  164. package/src/table/createTableHeaderRow.ts +40 -0
  165. package/src/table/createTableRow.ts +155 -0
  166. package/src/table/createTableRowGroup.ts +32 -0
  167. package/src/table/createTableSelectAllCheckbox.ts +73 -0
  168. package/src/table/createTableSelectionCheckbox.ts +59 -0
  169. package/src/table/index.ts +30 -0
  170. package/src/table/types.ts +165 -0
  171. package/src/tabs/createTabs.ts +472 -0
  172. package/src/tabs/index.ts +14 -0
  173. package/src/tag/createTag.ts +194 -0
  174. package/src/tag/createTagGroup.ts +154 -0
  175. package/src/tag/index.ts +12 -0
  176. package/src/textfield/createTextField.ts +198 -0
  177. package/src/textfield/index.ts +5 -0
  178. package/src/toast/createToast.ts +118 -0
  179. package/src/toast/createToastRegion.ts +100 -0
  180. package/src/toast/index.ts +11 -0
  181. package/src/toggle/createToggle.ts +223 -0
  182. package/src/toggle/createToggleState.ts +94 -0
  183. package/src/toggle/index.ts +7 -0
  184. package/src/toolbar/createToolbar.ts +369 -0
  185. package/src/toolbar/index.ts +6 -0
  186. package/src/tooltip/createTooltip.ts +79 -0
  187. package/src/tooltip/createTooltipTrigger.ts +222 -0
  188. package/src/tooltip/index.ts +6 -0
  189. package/src/tree/createTree.ts +246 -0
  190. package/src/tree/createTreeItem.ts +233 -0
  191. package/src/tree/createTreeSelectionCheckbox.ts +68 -0
  192. package/src/tree/index.ts +16 -0
  193. package/src/tree/types.ts +87 -0
  194. package/src/utils/createDescription.ts +137 -0
  195. package/src/utils/dom.ts +327 -0
  196. package/src/utils/env.ts +54 -0
  197. package/src/utils/events.ts +106 -0
  198. package/src/utils/filterDOMProps.ts +116 -0
  199. package/src/utils/focus.ts +151 -0
  200. package/src/utils/geometry.ts +115 -0
  201. package/src/utils/globalListeners.ts +142 -0
  202. package/src/utils/index.ts +80 -0
  203. package/src/utils/mergeProps.ts +52 -0
  204. package/src/utils/platform.ts +52 -0
  205. package/src/utils/reactivity.ts +36 -0
  206. package/src/utils/textSelection.ts +114 -0
  207. package/src/visually-hidden/createVisuallyHidden.ts +124 -0
  208. package/src/visually-hidden/index.ts +6 -0
  209. package/dist/index.jsx +0 -15845
  210. package/dist/index.jsx.map +0 -7
@@ -0,0 +1,78 @@
1
+ // Press interactions
2
+ export { createPress, type CreatePressProps, type PressResult } from './createPress';
3
+ export { PressEvent, type IPressEvent, type PressEventType } from './PressEvent';
4
+
5
+ // Long press interactions
6
+ export {
7
+ createLongPress,
8
+ type LongPressProps,
9
+ type LongPressResult,
10
+ type LongPressEvent,
11
+ } from './createLongPress';
12
+
13
+ // Move interactions
14
+ export { createMove, type MoveEvents, type MoveResult, type MoveStartEvent, type MoveMoveEvent, type MoveEndEvent } from './createMove';
15
+
16
+ // Focus interactions
17
+ export { createFocus, type CreateFocusProps, type FocusResult, type FocusEvents } from './createFocus';
18
+ export {
19
+ createFocusWithin,
20
+ type FocusWithinProps,
21
+ type FocusWithinResult,
22
+ } from './createFocusWithin';
23
+ export {
24
+ createFocusable,
25
+ FocusableContext,
26
+ type CreateFocusableProps,
27
+ type FocusableResult,
28
+ type FocusableContextValue,
29
+ type FocusableProviderProps,
30
+ type FocusableProps,
31
+ type FocusableDOMProps,
32
+ } from './createFocusable';
33
+ export { FocusableProvider } from './FocusableProvider';
34
+ export {
35
+ createFocusRing,
36
+ type FocusRingProps,
37
+ type FocusRingResult,
38
+ } from './createFocusRing';
39
+
40
+ // Interaction modality
41
+ export {
42
+ createInteractionModality,
43
+ createFocusVisible,
44
+ createFocusVisibleListener,
45
+ addWindowFocusTracking,
46
+ isFocusVisible,
47
+ getInteractionModality,
48
+ setInteractionModality,
49
+ getPointerType,
50
+ setupGlobalFocusListeners,
51
+ addModalityListener,
52
+ useIsKeyboardFocused,
53
+ type Modality,
54
+ type PointerType,
55
+ type FocusVisibleProps,
56
+ type FocusVisibleResult,
57
+ type FocusVisibleHandler,
58
+ type InteractionModalityResult,
59
+ } from './createInteractionModality';
60
+
61
+ // Hover interactions
62
+ export {
63
+ createHover,
64
+ type CreateHoverProps,
65
+ type HoverProps,
66
+ type HoverResult,
67
+ type HoverEvent,
68
+ type HoverEvents,
69
+ } from './createHover';
70
+
71
+ // Keyboard interactions
72
+ export {
73
+ createKeyboard,
74
+ type CreateKeyboardProps,
75
+ type KeyboardResult,
76
+ type KeyboardEvents,
77
+ type KeyboardEvent,
78
+ } from './createKeyboard';
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Field hook for Solidaria
3
+ *
4
+ * Provides the accessibility implementation for input fields.
5
+ * Fields accept user input, gain context from their label, and may display
6
+ * a description or error message.
7
+ *
8
+ * This is a 1:1 port of @react-aria/label's useField hook.
9
+ */
10
+
11
+ import { JSX } from 'solid-js';
12
+ import { createId } from '../ssr';
13
+ import { createLabel, type LabelAriaProps, type LabelAria, type AriaLabelingProps, type DOMProps } from './createLabel';
14
+ import { mergeProps } from '../utils/mergeProps';
15
+ import { type MaybeAccessor, access } from '../utils/reactivity';
16
+
17
+ // ============================================
18
+ // TYPES
19
+ // ============================================
20
+
21
+ export interface HelpTextProps {
22
+ /** A description for the field. Provides a hint such as specific requirements for what to choose. */
23
+ description?: JSX.Element;
24
+ /** An error message for the field. */
25
+ errorMessage?: JSX.Element | ((validation: ValidationResult) => JSX.Element);
26
+ }
27
+
28
+ export interface ValidationResult {
29
+ /** Whether the input value is invalid. */
30
+ isInvalid: boolean;
31
+ /** The current error messages for the input if it is invalid, otherwise an empty array. */
32
+ validationErrors: string[];
33
+ /** The native validity state for the input. */
34
+ validationDetails: ValidityState;
35
+ }
36
+
37
+ export interface Validation<T> {
38
+ /** Whether the input value is invalid. */
39
+ isInvalid?: boolean;
40
+ /** Whether the input is required before form submission. */
41
+ isRequired?: boolean;
42
+ /** A function that returns an error message if a given value is invalid. */
43
+ validate?: (value: T) => string | string[] | true | null | undefined;
44
+ }
45
+
46
+ export interface AriaFieldProps extends LabelAriaProps, HelpTextProps, Omit<Validation<any>, 'isRequired'> {}
47
+
48
+ export interface FieldAria extends LabelAria {
49
+ /** Props for the description element, if any. */
50
+ descriptionProps: JSX.HTMLAttributes<HTMLElement>;
51
+ /** Props for the error message element, if any. */
52
+ errorMessageProps: JSX.HTMLAttributes<HTMLElement>;
53
+ }
54
+
55
+ // ============================================
56
+ // IMPLEMENTATION
57
+ // ============================================
58
+
59
+ /**
60
+ * Provides the accessibility implementation for input fields.
61
+ * Fields accept user input, gain context from their label, and may display
62
+ * a description or error message.
63
+ *
64
+ * @param props - Props for the Field.
65
+ */
66
+ export function createField(props: MaybeAccessor<AriaFieldProps>): FieldAria {
67
+ const getProps = () => access(props);
68
+
69
+ const { labelProps, fieldProps: baseLabelFieldProps } = createLabel(props);
70
+
71
+ // Generate IDs for description and error message
72
+ const descriptionId = createId();
73
+ const errorMessageId = createId();
74
+
75
+ const getDescriptionProps = (): FieldAria['descriptionProps'] => {
76
+ const { description, errorMessage, isInvalid } = getProps();
77
+
78
+ // Only include ID if description exists or there's an error message that might be shown
79
+ if (!description && !errorMessage && !isInvalid) {
80
+ return {};
81
+ }
82
+
83
+ return {
84
+ id: descriptionId,
85
+ };
86
+ };
87
+
88
+ const getErrorMessageProps = (): FieldAria['errorMessageProps'] => {
89
+ const { errorMessage, isInvalid } = getProps();
90
+
91
+ // Only include ID if there's an error message and the field is invalid
92
+ if (!errorMessage && !isInvalid) {
93
+ return {};
94
+ }
95
+
96
+ return {
97
+ id: errorMessageId,
98
+ };
99
+ };
100
+
101
+ const getFieldProps = (): AriaLabelingProps & DOMProps => {
102
+ const { description, errorMessage, isInvalid } = getProps();
103
+
104
+ const describedByIds: string[] = [];
105
+
106
+ // Add description ID if description exists
107
+ if (description) {
108
+ describedByIds.push(descriptionId);
109
+ }
110
+
111
+ // Add error message ID if field is invalid and error message exists
112
+ // Use aria-describedby for error message because aria-errormessage is unsupported
113
+ // using VoiceOver or NVDA. See https://github.com/adobe/react-spectrum/issues/1346#issuecomment-740136268
114
+ if (isInvalid && errorMessage) {
115
+ describedByIds.push(errorMessageId);
116
+ }
117
+
118
+ // Add any existing aria-describedby from props
119
+ const existingDescribedBy = getProps()['aria-describedby'];
120
+ if (existingDescribedBy) {
121
+ describedByIds.push(existingDescribedBy);
122
+ }
123
+
124
+ const ariaDescribedBy = describedByIds.length > 0 ? describedByIds.join(' ') : undefined;
125
+
126
+ return mergeProps(baseLabelFieldProps, {
127
+ 'aria-describedby': ariaDescribedBy,
128
+ }) as AriaLabelingProps & DOMProps;
129
+ };
130
+
131
+ return {
132
+ get labelProps() {
133
+ return labelProps;
134
+ },
135
+ get fieldProps() {
136
+ return getFieldProps();
137
+ },
138
+ get descriptionProps() {
139
+ return getDescriptionProps();
140
+ },
141
+ get errorMessageProps() {
142
+ return getErrorMessageProps();
143
+ },
144
+ };
145
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Label hook for Solidaria
3
+ *
4
+ * Provides the accessibility implementation for labels and their associated elements.
5
+ * Labels provide context for user inputs.
6
+ *
7
+ * This is a 1:1 port of @react-aria/label's useLabel hook.
8
+ */
9
+
10
+ import { JSX } from 'solid-js';
11
+ import { createId } from '../ssr';
12
+ import { createLabels } from './createLabels';
13
+ import { type MaybeAccessor, access } from '../utils/reactivity';
14
+ import { isDevEnv } from '../utils/env';
15
+
16
+ // ============================================
17
+ // TYPES
18
+ // ============================================
19
+
20
+ export interface AriaLabelingProps {
21
+ /** Defines a string value that labels the current element. */
22
+ 'aria-label'?: string;
23
+ /** Identifies the element (or elements) that labels the current element. */
24
+ 'aria-labelledby'?: string;
25
+ /** Identifies the element (or elements) that describes the object. */
26
+ 'aria-describedby'?: string;
27
+ /** Identifies the element (or elements) that provide a detailed, extended description for the object. */
28
+ 'aria-details'?: string;
29
+ }
30
+
31
+ export interface LabelableProps {
32
+ /** The content to display as the label. */
33
+ label?: JSX.Element;
34
+ }
35
+
36
+ export interface DOMProps {
37
+ /** The element's unique identifier. */
38
+ id?: string;
39
+ }
40
+
41
+ export interface LabelAriaProps extends LabelableProps, DOMProps, AriaLabelingProps {
42
+ /**
43
+ * The HTML element used to render the label, e.g. 'label', or 'span'.
44
+ * @default 'label'
45
+ */
46
+ labelElementType?: 'label' | 'span' | 'div';
47
+ }
48
+
49
+ export interface LabelAria {
50
+ /** Props to apply to the label container element. */
51
+ labelProps: JSX.LabelHTMLAttributes<HTMLLabelElement> | JSX.HTMLAttributes<HTMLSpanElement>;
52
+ /** Props to apply to the field container element being labeled. */
53
+ fieldProps: AriaLabelingProps & DOMProps;
54
+ }
55
+
56
+ // ============================================
57
+ // IMPLEMENTATION
58
+ // ============================================
59
+
60
+ /**
61
+ * Provides the accessibility implementation for labels and their associated elements.
62
+ * Labels provide context for user inputs.
63
+ *
64
+ * @param props - The props for labels and fields.
65
+ */
66
+ export function createLabel(props: MaybeAccessor<LabelAriaProps>): LabelAria {
67
+ const getProps = () => access(props);
68
+
69
+ const id = createId(getProps().id);
70
+ const labelId = createId();
71
+
72
+ const getLabelProps = (): LabelAria['labelProps'] => {
73
+ const { label, labelElementType = 'label' } = getProps();
74
+
75
+ if (!label) {
76
+ return {};
77
+ }
78
+
79
+ return {
80
+ id: labelId,
81
+ ...(labelElementType === 'label' ? { for: id } : {}),
82
+ };
83
+ };
84
+
85
+ const getFieldProps = (): LabelAria['fieldProps'] => {
86
+ const {
87
+ label,
88
+ 'aria-labelledby': ariaLabelledby,
89
+ 'aria-label': ariaLabel,
90
+ } = getProps();
91
+
92
+ let labelledBy = ariaLabelledby;
93
+
94
+ if (label) {
95
+ labelledBy = ariaLabelledby ? `${labelId} ${ariaLabelledby}` : labelId;
96
+ } else if (!ariaLabelledby && !ariaLabel && isDevEnv()) {
97
+ console.warn(
98
+ 'If you do not provide a visible label, you must specify an aria-label or aria-labelledby attribute for accessibility'
99
+ );
100
+ }
101
+
102
+ return createLabels({
103
+ id,
104
+ 'aria-label': ariaLabel,
105
+ 'aria-labelledby': labelledBy,
106
+ });
107
+ };
108
+
109
+ return {
110
+ get labelProps() {
111
+ return getLabelProps();
112
+ },
113
+ get fieldProps() {
114
+ return getFieldProps();
115
+ },
116
+ };
117
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Labels utility for Solidaria
3
+ *
4
+ * Merges aria-label and aria-labelledby into aria-labelledby when both exist.
5
+ *
6
+ * This is a 1:1 port of @react-aria/utils's useLabels hook.
7
+ */
8
+
9
+ import { createId } from '../ssr';
10
+ import type { AriaLabelingProps, DOMProps } from './createLabel';
11
+
12
+ /**
13
+ * Merges aria-label and aria-labelledby into aria-labelledby when both exist.
14
+ *
15
+ * @param props - Aria label props.
16
+ * @param defaultLabel - Default value for aria-label when not present.
17
+ */
18
+ export function createLabels(
19
+ props: DOMProps & AriaLabelingProps,
20
+ defaultLabel?: string
21
+ ): DOMProps & AriaLabelingProps {
22
+ let {
23
+ id,
24
+ 'aria-label': label,
25
+ 'aria-labelledby': labelledBy,
26
+ } = props;
27
+
28
+ // Generate an ID if not provided
29
+ id = createId(id);
30
+
31
+ // If there is both an aria-label and aria-labelledby,
32
+ // combine them by pointing to the element itself.
33
+ if (labelledBy && label) {
34
+ const ids = new Set([id, ...labelledBy.trim().split(/\s+/)]);
35
+ labelledBy = [...ids].join(' ');
36
+ } else if (labelledBy) {
37
+ labelledBy = labelledBy.trim().split(/\s+/).join(' ');
38
+ }
39
+
40
+ // If no labels are provided, use the default
41
+ if (!label && !labelledBy && defaultLabel) {
42
+ label = defaultLabel;
43
+ }
44
+
45
+ return {
46
+ id,
47
+ 'aria-label': label,
48
+ 'aria-labelledby': labelledBy,
49
+ };
50
+ }
@@ -0,0 +1,19 @@
1
+ export { createLabel } from './createLabel';
2
+ export type {
3
+ LabelAriaProps,
4
+ LabelAria,
5
+ AriaLabelingProps,
6
+ LabelableProps,
7
+ DOMProps,
8
+ } from './createLabel';
9
+
10
+ export { createField } from './createField';
11
+ export type {
12
+ AriaFieldProps,
13
+ FieldAria,
14
+ HelpTextProps,
15
+ ValidationResult,
16
+ Validation,
17
+ } from './createField';
18
+
19
+ export { createLabels } from './createLabels';