@proyecto-viviana/solidaria 0.3.0 → 0.4.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.
- package/dist/_chunk/actiongroup.js +207 -0
- package/dist/_chunk/actiongroup.js.map +1 -0
- package/dist/_chunk/actiongroup.jsx +207 -0
- package/dist/_chunk/actiongroup.jsx.map +1 -0
- package/dist/_chunk/ariaHideOutside.js +122 -0
- package/dist/_chunk/ariaHideOutside.js.map +1 -0
- package/dist/_chunk/ariaHideOutside.jsx +122 -0
- package/dist/_chunk/ariaHideOutside.jsx.map +1 -0
- package/dist/_chunk/autocomplete.js +196 -0
- package/dist/_chunk/autocomplete.js.map +1 -0
- package/dist/_chunk/autocomplete.jsx +196 -0
- package/dist/_chunk/autocomplete.jsx.map +1 -0
- package/dist/_chunk/breadcrumbs.js +119 -0
- package/dist/_chunk/breadcrumbs.js.map +1 -0
- package/dist/_chunk/breadcrumbs.jsx +119 -0
- package/dist/_chunk/breadcrumbs.jsx.map +1 -0
- package/dist/_chunk/button.js +276 -0
- package/dist/_chunk/button.js.map +1 -0
- package/dist/_chunk/button.jsx +276 -0
- package/dist/_chunk/button.jsx.map +1 -0
- package/dist/_chunk/calendar.js +1036 -0
- package/dist/_chunk/calendar.js.map +1 -0
- package/dist/_chunk/calendar.jsx +1036 -0
- package/dist/_chunk/calendar.jsx.map +1 -0
- package/dist/_chunk/checkbox.js +234 -0
- package/dist/_chunk/checkbox.js.map +1 -0
- package/dist/_chunk/checkbox.jsx +234 -0
- package/dist/_chunk/checkbox.jsx.map +1 -0
- package/dist/_chunk/color.js +1174 -0
- package/dist/_chunk/color.js.map +1 -0
- package/dist/_chunk/color.jsx +1174 -0
- package/dist/_chunk/color.jsx.map +1 -0
- package/dist/_chunk/combobox.js +436 -0
- package/dist/_chunk/combobox.js.map +1 -0
- package/dist/_chunk/combobox.jsx +436 -0
- package/dist/_chunk/combobox.jsx.map +1 -0
- package/dist/_chunk/createCollator.js +229 -0
- package/dist/_chunk/createCollator.js.map +1 -0
- package/dist/_chunk/createCollator.jsx +223 -0
- package/dist/_chunk/createCollator.jsx.map +1 -0
- package/dist/_chunk/createCollectionRowInteraction.js +133 -0
- package/dist/_chunk/createCollectionRowInteraction.js.map +1 -0
- package/dist/_chunk/createCollectionRowInteraction.jsx +133 -0
- package/dist/_chunk/createCollectionRowInteraction.jsx.map +1 -0
- package/dist/_chunk/createField.js +54 -0
- package/dist/_chunk/createField.js.map +1 -0
- package/dist/_chunk/createField.jsx +54 -0
- package/dist/_chunk/createField.jsx.map +1 -0
- package/dist/_chunk/createFocus.js +101 -0
- package/dist/_chunk/createFocus.js.map +1 -0
- package/dist/_chunk/createFocus.jsx +101 -0
- package/dist/_chunk/createFocus.jsx.map +1 -0
- package/dist/_chunk/createFocusRing.js +54 -0
- package/dist/_chunk/createFocusRing.js.map +1 -0
- package/dist/_chunk/createFocusRing.jsx +54 -0
- package/dist/_chunk/createFocusRing.jsx.map +1 -0
- package/dist/_chunk/createFocusWithin.js +121 -0
- package/dist/_chunk/createFocusWithin.js.map +1 -0
- package/dist/_chunk/createFocusWithin.jsx +121 -0
- package/dist/_chunk/createFocusWithin.jsx.map +1 -0
- package/dist/_chunk/createFocusable.js +131 -0
- package/dist/_chunk/createFocusable.js.map +1 -0
- package/dist/_chunk/createFocusable.jsx +131 -0
- package/dist/_chunk/createFocusable.jsx.map +1 -0
- package/dist/_chunk/createFormValidation.js +135 -0
- package/dist/_chunk/createFormValidation.js.map +1 -0
- package/dist/_chunk/createFormValidation.jsx +135 -0
- package/dist/_chunk/createFormValidation.jsx.map +1 -0
- package/dist/_chunk/createHover.js +130 -0
- package/dist/_chunk/createHover.js.map +1 -0
- package/dist/_chunk/createHover.jsx +130 -0
- package/dist/_chunk/createHover.jsx.map +1 -0
- package/dist/_chunk/createInteractionModality.js +269 -0
- package/dist/_chunk/createInteractionModality.js.map +1 -0
- package/dist/_chunk/createInteractionModality.jsx +269 -0
- package/dist/_chunk/createInteractionModality.jsx.map +1 -0
- package/dist/_chunk/createLabel.js +46 -0
- package/dist/_chunk/createLabel.js.map +1 -0
- package/dist/_chunk/createLabel.jsx +46 -0
- package/dist/_chunk/createLabel.jsx.map +1 -0
- package/dist/_chunk/createLabels.js +31 -0
- package/dist/_chunk/createLabels.js.map +1 -0
- package/dist/_chunk/createLabels.jsx +31 -0
- package/dist/_chunk/createLabels.jsx.map +1 -0
- package/dist/_chunk/createLandmark.js +198 -0
- package/dist/_chunk/createLandmark.js.map +1 -0
- package/dist/_chunk/createLandmark.jsx +198 -0
- package/dist/_chunk/createLandmark.jsx.map +1 -0
- package/dist/_chunk/createLongPress.js +91 -0
- package/dist/_chunk/createLongPress.js.map +1 -0
- package/dist/_chunk/createLongPress.jsx +91 -0
- package/dist/_chunk/createLongPress.jsx.map +1 -0
- package/dist/_chunk/createOverlay.js +327 -0
- package/dist/_chunk/createOverlay.js.map +1 -0
- package/dist/_chunk/createOverlay.jsx +327 -0
- package/dist/_chunk/createOverlay.jsx.map +1 -0
- package/dist/_chunk/createPress.js +526 -0
- package/dist/_chunk/createPress.js.map +1 -0
- package/dist/_chunk/createPress.jsx +526 -0
- package/dist/_chunk/createPress.jsx.map +1 -0
- package/dist/_chunk/createProgressBar.js +81 -0
- package/dist/_chunk/createProgressBar.js.map +1 -0
- package/dist/_chunk/createProgressBar.jsx +81 -0
- package/dist/_chunk/createProgressBar.jsx.map +1 -0
- package/dist/_chunk/createSelectableItem.js +298 -0
- package/dist/_chunk/createSelectableItem.js.map +1 -0
- package/dist/_chunk/createSelectableItem.jsx +298 -0
- package/dist/_chunk/createSelectableItem.jsx.map +1 -0
- package/dist/_chunk/createToggle.js +158 -0
- package/dist/_chunk/createToggle.js.map +1 -0
- package/dist/_chunk/createToggle.jsx +158 -0
- package/dist/_chunk/createToggle.jsx.map +1 -0
- package/dist/_chunk/createTypeSelect.js +125 -0
- package/dist/_chunk/createTypeSelect.js.map +1 -0
- package/dist/_chunk/createTypeSelect.jsx +125 -0
- package/dist/_chunk/createTypeSelect.jsx.map +1 -0
- package/dist/_chunk/datepicker.js +1393 -0
- package/dist/_chunk/datepicker.js.map +1 -0
- package/dist/_chunk/datepicker.jsx +1393 -0
- package/dist/_chunk/datepicker.jsx.map +1 -0
- package/dist/_chunk/dialog.js +62 -0
- package/dist/_chunk/dialog.js.map +1 -0
- package/dist/_chunk/dialog.jsx +62 -0
- package/dist/_chunk/dialog.jsx.map +1 -0
- package/dist/_chunk/disclosure.js +185 -0
- package/dist/_chunk/disclosure.js.map +1 -0
- package/dist/_chunk/disclosure.jsx +185 -0
- package/dist/_chunk/disclosure.jsx.map +1 -0
- package/dist/_chunk/dnd.js +1304 -0
- package/dist/_chunk/dnd.js.map +1 -0
- package/dist/_chunk/dnd.jsx +1304 -0
- package/dist/_chunk/dnd.jsx.map +1 -0
- package/dist/_chunk/env.js +105 -0
- package/dist/_chunk/env.js.map +1 -0
- package/dist/_chunk/env.jsx +105 -0
- package/dist/_chunk/env.jsx.map +1 -0
- package/dist/_chunk/filterDOMProps.js +82 -0
- package/dist/_chunk/filterDOMProps.js.map +1 -0
- package/dist/_chunk/filterDOMProps.jsx +82 -0
- package/dist/_chunk/filterDOMProps.jsx.map +1 -0
- package/dist/_chunk/focus.js +399 -0
- package/dist/_chunk/focus.js.map +1 -0
- package/dist/_chunk/focus.jsx +399 -0
- package/dist/_chunk/focus.jsx.map +1 -0
- package/dist/_chunk/focus2.js +895 -0
- package/dist/_chunk/focus2.js.map +1 -0
- package/dist/_chunk/focus2.jsx +870 -0
- package/dist/_chunk/focus2.jsx.map +1 -0
- package/dist/_chunk/form.js +39 -0
- package/dist/_chunk/form.js.map +1 -0
- package/dist/_chunk/form.jsx +39 -0
- package/dist/_chunk/form.jsx.map +1 -0
- package/dist/_chunk/grid.js +623 -0
- package/dist/_chunk/grid.js.map +1 -0
- package/dist/_chunk/grid.jsx +623 -0
- package/dist/_chunk/grid.jsx.map +1 -0
- package/dist/_chunk/gridlist.js +364 -0
- package/dist/_chunk/gridlist.js.map +1 -0
- package/dist/_chunk/gridlist.jsx +364 -0
- package/dist/_chunk/gridlist.jsx.map +1 -0
- package/dist/_chunk/i18n.js +254 -0
- package/dist/_chunk/i18n.js.map +1 -0
- package/dist/_chunk/i18n.jsx +254 -0
- package/dist/_chunk/i18n.jsx.map +1 -0
- package/dist/_chunk/interactions.js +241 -0
- package/dist/_chunk/interactions.js.map +1 -0
- package/dist/_chunk/interactions.jsx +237 -0
- package/dist/_chunk/interactions.jsx.map +1 -0
- package/dist/_chunk/link.js +96 -0
- package/dist/_chunk/link.js.map +1 -0
- package/dist/_chunk/link.jsx +96 -0
- package/dist/_chunk/link.jsx.map +1 -0
- package/dist/_chunk/listbox.js +324 -0
- package/dist/_chunk/listbox.js.map +1 -0
- package/dist/_chunk/listbox.jsx +324 -0
- package/dist/_chunk/listbox.jsx.map +1 -0
- package/dist/_chunk/live-announcer.js +207 -0
- package/dist/_chunk/live-announcer.js.map +1 -0
- package/dist/_chunk/live-announcer.jsx +207 -0
- package/dist/_chunk/live-announcer.jsx.map +1 -0
- package/dist/_chunk/menu.js +518 -0
- package/dist/_chunk/menu.js.map +1 -0
- package/dist/_chunk/menu.jsx +518 -0
- package/dist/_chunk/menu.jsx.map +1 -0
- package/dist/_chunk/meter.js +33 -0
- package/dist/_chunk/meter.js.map +1 -0
- package/dist/_chunk/meter.jsx +33 -0
- package/dist/_chunk/meter.jsx.map +1 -0
- package/dist/_chunk/numberfield.js +258 -0
- package/dist/_chunk/numberfield.js.map +1 -0
- package/dist/_chunk/numberfield.jsx +258 -0
- package/dist/_chunk/numberfield.jsx.map +1 -0
- package/dist/_chunk/overlays.js +186 -0
- package/dist/_chunk/overlays.js.map +1 -0
- package/dist/_chunk/overlays.jsx +162 -0
- package/dist/_chunk/overlays.jsx.map +1 -0
- package/dist/_chunk/popover.js +574 -0
- package/dist/_chunk/popover.js.map +1 -0
- package/dist/_chunk/popover.jsx +574 -0
- package/dist/_chunk/popover.jsx.map +1 -0
- package/dist/_chunk/radio.js +319 -0
- package/dist/_chunk/radio.js.map +1 -0
- package/dist/_chunk/radio.jsx +319 -0
- package/dist/_chunk/radio.jsx.map +1 -0
- package/dist/_chunk/searchfield.js +209 -0
- package/dist/_chunk/searchfield.js.map +1 -0
- package/dist/_chunk/searchfield.jsx +209 -0
- package/dist/_chunk/searchfield.jsx.map +1 -0
- package/dist/_chunk/select.js +403 -0
- package/dist/_chunk/select.js.map +1 -0
- package/dist/_chunk/select.jsx +394 -0
- package/dist/_chunk/select.jsx.map +1 -0
- package/dist/_chunk/selection.js +679 -0
- package/dist/_chunk/selection.js.map +1 -0
- package/dist/_chunk/selection.jsx +679 -0
- package/dist/_chunk/selection.jsx.map +1 -0
- package/dist/_chunk/separator.js +29 -0
- package/dist/_chunk/separator.js.map +1 -0
- package/dist/_chunk/separator.jsx +29 -0
- package/dist/_chunk/separator.jsx.map +1 -0
- package/dist/_chunk/slider.js +255 -0
- package/dist/_chunk/slider.js.map +1 -0
- package/dist/_chunk/slider.jsx +255 -0
- package/dist/_chunk/slider.jsx.map +1 -0
- package/dist/_chunk/steplist.js +66 -0
- package/dist/_chunk/steplist.js.map +1 -0
- package/dist/_chunk/steplist.jsx +66 -0
- package/dist/_chunk/steplist.jsx.map +1 -0
- package/dist/_chunk/switch.js +34 -0
- package/dist/_chunk/switch.js.map +1 -0
- package/dist/_chunk/switch.jsx +34 -0
- package/dist/_chunk/switch.jsx.map +1 -0
- package/dist/_chunk/table.js +1051 -0
- package/dist/_chunk/table.js.map +1 -0
- package/dist/_chunk/table.jsx +1051 -0
- package/dist/_chunk/table.jsx.map +1 -0
- package/dist/_chunk/tabs.js +260 -0
- package/dist/_chunk/tabs.js.map +1 -0
- package/dist/_chunk/tabs.jsx +260 -0
- package/dist/_chunk/tabs.jsx.map +1 -0
- package/dist/_chunk/tag.js +286 -0
- package/dist/_chunk/tag.js.map +1 -0
- package/dist/_chunk/tag.jsx +286 -0
- package/dist/_chunk/tag.jsx.map +1 -0
- package/dist/_chunk/textfield.js +109 -0
- package/dist/_chunk/textfield.js.map +1 -0
- package/dist/_chunk/textfield.jsx +109 -0
- package/dist/_chunk/textfield.jsx.map +1 -0
- package/dist/_chunk/toast.js +250 -0
- package/dist/_chunk/toast.js.map +1 -0
- package/dist/_chunk/toast.jsx +250 -0
- package/dist/_chunk/toast.jsx.map +1 -0
- package/dist/_chunk/toolbar.js +258 -0
- package/dist/_chunk/toolbar.js.map +1 -0
- package/dist/_chunk/toolbar.jsx +258 -0
- package/dist/_chunk/toolbar.jsx.map +1 -0
- package/dist/_chunk/tooltip.js +185 -0
- package/dist/_chunk/tooltip.js.map +1 -0
- package/dist/_chunk/tooltip.jsx +185 -0
- package/dist/_chunk/tooltip.jsx.map +1 -0
- package/dist/_chunk/tree.js +424 -0
- package/dist/_chunk/tree.js.map +1 -0
- package/dist/_chunk/tree.jsx +424 -0
- package/dist/_chunk/tree.jsx.map +1 -0
- package/dist/_chunk/utils.js +665 -0
- package/dist/_chunk/utils.js.map +1 -0
- package/dist/_chunk/utils.jsx +665 -0
- package/dist/_chunk/utils.jsx.map +1 -0
- package/dist/_chunk/visually-hidden.js +92 -0
- package/dist/_chunk/visually-hidden.js.map +1 -0
- package/dist/_chunk/visually-hidden.jsx +92 -0
- package/dist/_chunk/visually-hidden.jsx.map +1 -0
- package/dist/actiongroup/index.js +2 -0
- package/dist/actiongroup/index.jsx +2 -0
- package/dist/autocomplete/createAutocomplete.d.ts +2 -0
- package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
- package/dist/autocomplete/index.js +2 -0
- package/dist/autocomplete/index.jsx +2 -0
- package/dist/breadcrumbs/index.js +2 -0
- package/dist/breadcrumbs/index.jsx +2 -0
- package/dist/button/index.js +2 -0
- package/dist/button/index.jsx +2 -0
- package/dist/calendar/createCalendar.d.ts.map +1 -1
- package/dist/calendar/createCalendarCell.d.ts.map +1 -1
- package/dist/calendar/createCalendarGrid.d.ts.map +1 -1
- package/dist/calendar/createCalendarMonthPicker.d.ts +41 -0
- package/dist/calendar/createCalendarMonthPicker.d.ts.map +1 -0
- package/dist/calendar/createCalendarYearPicker.d.ts +49 -0
- package/dist/calendar/createCalendarYearPicker.d.ts.map +1 -0
- package/dist/calendar/createRangeCalendar.d.ts.map +1 -1
- package/dist/calendar/index.d.ts +2 -0
- package/dist/calendar/index.d.ts.map +1 -1
- package/dist/calendar/index.js +2 -0
- package/dist/calendar/index.jsx +2 -0
- package/dist/calendar/utils.d.ts +4 -0
- package/dist/calendar/utils.d.ts.map +1 -1
- package/dist/checkbox/createCheckbox.d.ts +4 -0
- package/dist/checkbox/createCheckbox.d.ts.map +1 -1
- package/dist/checkbox/createCheckboxGroupItem.d.ts.map +1 -1
- package/dist/checkbox/index.js +2 -0
- package/dist/checkbox/index.jsx +2 -0
- package/dist/collections/index.js +160 -0
- package/dist/collections/index.js.map +1 -0
- package/dist/collections/index.jsx +160 -0
- package/dist/collections/index.jsx.map +1 -0
- package/dist/color/index.js +2 -0
- package/dist/color/index.jsx +2 -0
- package/dist/combobox/index.js +2 -0
- package/dist/combobox/index.jsx +2 -0
- package/dist/datepicker/createDateSegment.d.ts.map +1 -1
- package/dist/datepicker/index.js +2 -0
- package/dist/datepicker/index.jsx +2 -0
- package/dist/dialog/index.js +2 -0
- package/dist/dialog/index.jsx +2 -0
- package/dist/disclosure/index.js +2 -0
- package/dist/disclosure/index.jsx +2 -0
- package/dist/dnd/createDroppableCollection.d.ts.map +1 -1
- package/dist/dnd/index.js +2 -0
- package/dist/dnd/index.jsx +2 -0
- package/dist/dnd/utils.d.ts +2 -2
- package/dist/dnd/utils.d.ts.map +1 -1
- package/dist/focus/FocusScope.d.ts.map +1 -1
- package/dist/focus/index.js +2 -0
- package/dist/focus/index.jsx +2 -0
- package/dist/form/createFormValidation.d.ts.map +1 -1
- package/dist/form/index.js +3 -0
- package/dist/form/index.jsx +3 -0
- package/dist/grid/index.js +2 -0
- package/dist/grid/index.jsx +2 -0
- package/dist/gridlist/createGridList.d.ts +7 -1
- package/dist/gridlist/createGridList.d.ts.map +1 -1
- package/dist/gridlist/createGridListItem.d.ts +1 -1
- package/dist/gridlist/createGridListItem.d.ts.map +1 -1
- package/dist/gridlist/createGridListSection.d.ts +15 -0
- package/dist/gridlist/createGridListSection.d.ts.map +1 -0
- package/dist/gridlist/index.d.ts +2 -1
- package/dist/gridlist/index.d.ts.map +1 -1
- package/dist/gridlist/index.js +2 -0
- package/dist/gridlist/index.jsx +2 -0
- package/dist/gridlist/types.d.ts +50 -0
- package/dist/gridlist/types.d.ts.map +1 -1
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/index.jsx +3 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +71 -18311
- package/dist/index.jsx +71 -18242
- package/dist/interactions/PressEvent.d.ts +11 -0
- package/dist/interactions/PressEvent.d.ts.map +1 -1
- package/dist/interactions/createInteractionModality.d.ts +0 -1
- package/dist/interactions/createInteractionModality.d.ts.map +1 -1
- package/dist/interactions/createKeyboard.d.ts.map +1 -1
- package/dist/interactions/createPress.d.ts.map +1 -1
- package/dist/interactions/index.js +10 -0
- package/dist/interactions/index.jsx +10 -0
- package/dist/label/index.js +4 -0
- package/dist/label/index.jsx +4 -0
- package/dist/landmark/index.js +2 -0
- package/dist/landmark/index.jsx +2 -0
- package/dist/link/index.js +2 -0
- package/dist/link/index.jsx +2 -0
- package/dist/listbox/createListBox.d.ts +37 -0
- package/dist/listbox/createListBox.d.ts.map +1 -1
- package/dist/listbox/createOption.d.ts +6 -0
- package/dist/listbox/createOption.d.ts.map +1 -1
- package/dist/listbox/index.js +2 -0
- package/dist/listbox/index.jsx +2 -0
- package/dist/live-announcer/index.js +2 -0
- package/dist/live-announcer/index.jsx +2 -0
- package/dist/menu/createMenu.d.ts +7 -4
- package/dist/menu/createMenu.d.ts.map +1 -1
- package/dist/menu/createMenuItem.d.ts +9 -1
- package/dist/menu/createMenuItem.d.ts.map +1 -1
- package/dist/menu/index.js +2 -0
- package/dist/menu/index.jsx +2 -0
- package/dist/meter/index.js +2 -0
- package/dist/meter/index.jsx +2 -0
- package/dist/numberfield/createNumberField.d.ts.map +1 -1
- package/dist/numberfield/index.js +2 -0
- package/dist/numberfield/index.jsx +2 -0
- package/dist/overlays/index.js +4 -0
- package/dist/overlays/index.jsx +4 -0
- package/dist/popover/calculatePosition.d.ts +2 -0
- package/dist/popover/calculatePosition.d.ts.map +1 -1
- package/dist/popover/createOverlayPosition.d.ts +8 -0
- package/dist/popover/createOverlayPosition.d.ts.map +1 -1
- package/dist/popover/index.js +2 -0
- package/dist/popover/index.jsx +2 -0
- package/dist/progress/index.js +2 -0
- package/dist/progress/index.jsx +2 -0
- package/dist/radio/createRadio.d.ts +2 -0
- package/dist/radio/createRadio.d.ts.map +1 -1
- package/dist/radio/index.js +2 -0
- package/dist/radio/index.jsx +2 -0
- package/dist/searchfield/index.js +2 -0
- package/dist/searchfield/index.jsx +2 -0
- package/dist/select/createSelect.d.ts.map +1 -1
- package/dist/select/index.js +2 -0
- package/dist/select/index.jsx +2 -0
- package/dist/selection/DOMLayoutDelegate.d.ts +58 -0
- package/dist/selection/DOMLayoutDelegate.d.ts.map +1 -0
- package/dist/selection/ListKeyboardDelegate.d.ts +95 -0
- package/dist/selection/ListKeyboardDelegate.d.ts.map +1 -0
- package/dist/selection/constants.d.ts +15 -0
- package/dist/selection/constants.d.ts.map +1 -0
- package/dist/selection/createCollectionRowInteraction.d.ts +13 -0
- package/dist/selection/createCollectionRowInteraction.d.ts.map +1 -0
- package/dist/selection/createScrollIntoViewOnFocus.d.ts +31 -0
- package/dist/selection/createScrollIntoViewOnFocus.d.ts.map +1 -0
- package/dist/selection/createSelectableCollection.d.ts +69 -0
- package/dist/selection/createSelectableCollection.d.ts.map +1 -0
- package/dist/selection/createSelectableItem.d.ts +154 -0
- package/dist/selection/createSelectableItem.d.ts.map +1 -0
- package/dist/selection/createSelectableList.d.ts +43 -0
- package/dist/selection/createSelectableList.d.ts.map +1 -0
- package/dist/selection/createTypeSelect.d.ts.map +1 -1
- package/dist/selection/index.d.ts +9 -0
- package/dist/selection/index.d.ts.map +1 -1
- package/dist/selection/index.js +4 -0
- package/dist/selection/index.jsx +4 -0
- package/dist/selection/selectItem.d.ts +29 -0
- package/dist/selection/selectItem.d.ts.map +1 -0
- package/dist/selection/utils.d.ts +40 -0
- package/dist/selection/utils.d.ts.map +1 -0
- package/dist/separator/index.js +2 -0
- package/dist/separator/index.jsx +2 -0
- package/dist/slider/createSlider.d.ts.map +1 -1
- package/dist/slider/index.js +2 -0
- package/dist/slider/index.jsx +2 -0
- package/dist/ssr/index.d.ts +17 -0
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/index.js +299 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/index.jsx +292 -0
- package/dist/ssr/index.jsx.map +1 -0
- package/dist/steplist/index.js +2 -0
- package/dist/steplist/index.jsx +2 -0
- package/dist/switch/createSwitch.d.ts +4 -0
- package/dist/switch/createSwitch.d.ts.map +1 -1
- package/dist/switch/index.js +2 -0
- package/dist/switch/index.jsx +2 -0
- package/dist/table/createTable.d.ts.map +1 -1
- package/dist/table/createTableRow.d.ts +1 -1
- package/dist/table/createTableRow.d.ts.map +1 -1
- package/dist/table/createTableSelectAllCheckbox.d.ts.map +1 -1
- package/dist/table/index.js +2 -0
- package/dist/table/index.jsx +2 -0
- package/dist/table/types.d.ts +27 -1
- package/dist/table/types.d.ts.map +1 -1
- package/dist/tabs/createTabs.d.ts +4 -3
- package/dist/tabs/createTabs.d.ts.map +1 -1
- package/dist/tabs/index.js +2 -0
- package/dist/tabs/index.jsx +2 -0
- package/dist/tag/createTag.d.ts +2 -0
- package/dist/tag/createTag.d.ts.map +1 -1
- package/dist/tag/index.js +2 -0
- package/dist/tag/index.jsx +2 -0
- package/dist/textfield/index.js +2 -0
- package/dist/textfield/index.jsx +2 -0
- package/dist/toast/createToast.d.ts.map +1 -1
- package/dist/toast/index.js +2 -0
- package/dist/toast/index.jsx +2 -0
- package/dist/toggle/createToggle.d.ts +4 -0
- package/dist/toggle/createToggle.d.ts.map +1 -1
- package/dist/toggle/index.js +3 -0
- package/dist/toggle/index.jsx +3 -0
- package/dist/toolbar/createToolbar.d.ts +1 -1
- package/dist/toolbar/createToolbar.d.ts.map +1 -1
- package/dist/toolbar/index.js +2 -0
- package/dist/toolbar/index.jsx +2 -0
- package/dist/tooltip/index.js +2 -0
- package/dist/tooltip/index.jsx +2 -0
- package/dist/tree/createTree.d.ts +5 -1
- package/dist/tree/createTree.d.ts.map +1 -1
- package/dist/tree/createTreeItem.d.ts +1 -1
- package/dist/tree/createTreeItem.d.ts.map +1 -1
- package/dist/tree/index.js +2 -0
- package/dist/tree/index.jsx +2 -0
- package/dist/tree/types.d.ts +10 -0
- package/dist/tree/types.d.ts.map +1 -1
- package/dist/utils/animation.d.ts +60 -0
- package/dist/utils/animation.d.ts.map +1 -0
- package/dist/utils/dom.d.ts +48 -2
- package/dist/utils/dom.d.ts.map +1 -1
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.jsx +5 -0
- package/dist/utils/keyboard.d.ts +17 -0
- package/dist/utils/keyboard.d.ts.map +1 -0
- package/dist/utils/mergeProps.d.ts.map +1 -1
- package/dist/utils/scrollIntoView.d.ts +30 -0
- package/dist/utils/scrollIntoView.d.ts.map +1 -0
- package/dist/visually-hidden/index.js +2 -0
- package/dist/visually-hidden/index.jsx +2 -0
- package/package.json +304 -3
- package/src/autocomplete/createAutocomplete.ts +67 -21
- package/src/calendar/createCalendar.ts +2 -0
- package/src/calendar/createCalendarCell.ts +19 -2
- package/src/calendar/createCalendarGrid.ts +43 -9
- package/src/calendar/createCalendarMonthPicker.ts +105 -0
- package/src/calendar/createCalendarYearPicker.ts +144 -0
- package/src/calendar/createRangeCalendar.ts +2 -0
- package/src/calendar/index.ts +17 -0
- package/src/calendar/utils.ts +4 -0
- package/src/checkbox/createCheckbox.ts +10 -0
- package/src/checkbox/createCheckboxGroupItem.ts +12 -16
- package/src/datepicker/createDateSegment.ts +6 -1
- package/src/dnd/createDroppableCollection.ts +4 -1
- package/src/dnd/utils.ts +27 -3
- package/src/focus/FocusScope.tsx +152 -18
- package/src/form/createFormValidation.ts +8 -1
- package/src/gridlist/createGridList.ts +145 -42
- package/src/gridlist/createGridListItem.ts +87 -155
- package/src/gridlist/createGridListSection.ts +54 -0
- package/src/gridlist/index.ts +3 -0
- package/src/gridlist/types.ts +47 -0
- package/src/index.ts +40 -0
- package/src/interactions/PressEvent.ts +14 -0
- package/src/interactions/createInteractionModality.ts +21 -12
- package/src/interactions/createKeyboard.ts +10 -0
- package/src/interactions/createPress.ts +29 -6
- package/src/listbox/createListBox.ts +129 -8
- package/src/listbox/createOption.ts +68 -73
- package/src/menu/createMenu.ts +93 -16
- package/src/menu/createMenuItem.ts +253 -41
- package/src/numberfield/createNumberField.ts +82 -14
- package/src/popover/calculatePosition.ts +19 -7
- package/src/popover/createOverlayPosition.ts +9 -0
- package/src/radio/createRadio.ts +19 -2
- package/src/select/createSelect.ts +18 -2
- package/src/selection/DOMLayoutDelegate.ts +102 -0
- package/src/selection/ListKeyboardDelegate.ts +398 -0
- package/src/selection/constants.ts +16 -0
- package/src/selection/createCollectionRowInteraction.ts +209 -0
- package/src/selection/createScrollIntoViewOnFocus.ts +65 -0
- package/src/selection/createSelectableCollection.ts +645 -0
- package/src/selection/createSelectableItem.ts +498 -0
- package/src/selection/createSelectableList.ts +93 -0
- package/src/selection/createTypeSelect.ts +112 -51
- package/src/selection/index.ts +31 -0
- package/src/selection/selectItem.ts +80 -0
- package/src/selection/utils.ts +82 -0
- package/src/slider/createSlider.ts +48 -1
- package/src/ssr/index.tsx +31 -0
- package/src/switch/createSwitch.ts +10 -0
- package/src/table/createTable.ts +56 -26
- package/src/table/createTableRow.ts +198 -203
- package/src/table/createTableSelectAllCheckbox.ts +3 -4
- package/src/table/types.ts +29 -1
- package/src/tabs/createTabs.ts +50 -20
- package/src/tag/createTag.ts +9 -4
- package/src/toast/createToast.ts +1 -0
- package/src/toggle/createToggle.ts +20 -0
- package/src/toolbar/createToolbar.ts +43 -42
- package/src/tree/createTree.ts +100 -42
- package/src/tree/createTreeItem.ts +105 -120
- package/src/tree/types.ts +10 -0
- package/src/utils/animation.ts +151 -0
- package/src/utils/dom.ts +215 -25
- package/src/utils/index.ts +8 -0
- package/src/utils/keyboard.ts +25 -0
- package/src/utils/mergeProps.ts +8 -1
- package/src/utils/scrollIntoView.ts +181 -0
- package/dist/index.js.map +0 -1
- package/dist/index.jsx.map +0 -1
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
import { g as isTabbable, p as isFocusable, s as getOwnerDocument, t as focusSafely } from "./focus.jsx";
|
|
2
|
+
import { createContext, createEffect, createSignal, onCleanup, onMount, useContext } from "solid-js";
|
|
3
|
+
import { isServer } from "solid-js/web";
|
|
4
|
+
//#region src/focus/FocusScope.tsx
|
|
5
|
+
/**
|
|
6
|
+
* FocusScope component for managing focus containment, restoration, and auto-focus.
|
|
7
|
+
* Based on @react-aria/focus FocusScope.
|
|
8
|
+
*/
|
|
9
|
+
const FocusScopeContext = createContext(null);
|
|
10
|
+
/**
|
|
11
|
+
* Returns a FocusManager interface for the parent FocusScope.
|
|
12
|
+
* A FocusManager can be used to programmatically move focus within
|
|
13
|
+
* a FocusScope, e.g. in response to user events like keyboard navigation.
|
|
14
|
+
*/
|
|
15
|
+
function useFocusManager() {
|
|
16
|
+
return useContext(FocusScopeContext)?.focusManager;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Gets all focusable elements within a scope.
|
|
20
|
+
*/
|
|
21
|
+
function getFocusableElements(scope, tabbable = false) {
|
|
22
|
+
const elements = [];
|
|
23
|
+
const filter = tabbable ? isTabbable : isFocusable;
|
|
24
|
+
for (const scopeElement of scope) {
|
|
25
|
+
if (filter(scopeElement)) elements.push(scopeElement);
|
|
26
|
+
const descendants = scopeElement.querySelectorAll("*");
|
|
27
|
+
for (let i = 0; i < descendants.length; i++) {
|
|
28
|
+
const el = descendants[i];
|
|
29
|
+
if (filter(el)) elements.push(el);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return elements;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks if an element is within a scope.
|
|
36
|
+
*/
|
|
37
|
+
function isElementInScope(element, scope) {
|
|
38
|
+
if (!element) return false;
|
|
39
|
+
return scope.some((node) => node.contains(element));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gets the active element, accounting for shadow DOM.
|
|
43
|
+
*/
|
|
44
|
+
function getActiveElement$1(doc) {
|
|
45
|
+
let activeElement = doc.activeElement;
|
|
46
|
+
while (activeElement?.shadowRoot?.activeElement) activeElement = activeElement.shadowRoot.activeElement;
|
|
47
|
+
return activeElement;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A registry of the live FocusScopes and their parent/child relationships,
|
|
51
|
+
* mirroring @react-aria/focus's `focusScopeTree`. The DOM tree alone can't
|
|
52
|
+
* express scope nesting because a child scope (e.g. a menu opened from inside a
|
|
53
|
+
* modal popover) is rendered in a portal, outside its parent scope's subtree.
|
|
54
|
+
* The tree records that nesting so containment can recognize a portaled
|
|
55
|
+
* descendant scope as "inside".
|
|
56
|
+
*/
|
|
57
|
+
var FocusScopeTree = class {
|
|
58
|
+
root;
|
|
59
|
+
fastMap = /* @__PURE__ */ new Map();
|
|
60
|
+
constructor() {
|
|
61
|
+
this.root = {
|
|
62
|
+
scopeRef: null,
|
|
63
|
+
parent: null,
|
|
64
|
+
children: /* @__PURE__ */ new Set()
|
|
65
|
+
};
|
|
66
|
+
this.fastMap.set(null, this.root);
|
|
67
|
+
}
|
|
68
|
+
getTreeNode(scopeRef) {
|
|
69
|
+
return this.fastMap.get(scopeRef);
|
|
70
|
+
}
|
|
71
|
+
addTreeNode(scopeRef, parent) {
|
|
72
|
+
const parentNode = this.fastMap.get(parent) ?? this.root;
|
|
73
|
+
const node = {
|
|
74
|
+
scopeRef,
|
|
75
|
+
parent: parentNode,
|
|
76
|
+
children: /* @__PURE__ */ new Set()
|
|
77
|
+
};
|
|
78
|
+
parentNode.children.add(node);
|
|
79
|
+
this.fastMap.set(scopeRef, node);
|
|
80
|
+
}
|
|
81
|
+
removeTreeNode(scopeRef) {
|
|
82
|
+
if (scopeRef === null) return;
|
|
83
|
+
const node = this.fastMap.get(scopeRef);
|
|
84
|
+
if (!node) return;
|
|
85
|
+
const parentNode = node.parent;
|
|
86
|
+
if (parentNode) {
|
|
87
|
+
parentNode.children.delete(node);
|
|
88
|
+
for (const child of node.children) {
|
|
89
|
+
child.parent = parentNode;
|
|
90
|
+
parentNode.children.add(child);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
this.fastMap.delete(scopeRef);
|
|
94
|
+
}
|
|
95
|
+
*traverse(node = this.root) {
|
|
96
|
+
if (node.scopeRef != null) yield node;
|
|
97
|
+
for (const child of node.children) yield* this.traverse(child);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const focusScopeTree = new FocusScopeTree();
|
|
101
|
+
/**
|
|
102
|
+
* Whether the element is inside `scope` or any of its descendant scopes.
|
|
103
|
+
*
|
|
104
|
+
* `isElementInScope`'s `node.contains` already covers descendant scopes that
|
|
105
|
+
* are DOM children, but not those rendered in a portal. Walking the scope
|
|
106
|
+
* subtree closes that gap so focus moving into a portaled child scope still
|
|
107
|
+
* counts as "inside". Mirrors @react-aria/focus's `isElementInChildScope`.
|
|
108
|
+
*/
|
|
109
|
+
function isElementInChildScope(element, scope = null) {
|
|
110
|
+
if (element instanceof Element && element.closest("[data-react-aria-top-layer]")) return true;
|
|
111
|
+
for (const node of focusScopeTree.traverse(focusScopeTree.getTreeNode(scope))) if (node.scopeRef && isElementInScope(element, node.scopeRef())) return true;
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* A FocusScope manages focus for its descendants. It supports containing focus inside
|
|
116
|
+
* the scope, restoring focus to the previously focused element on unmount, and auto
|
|
117
|
+
* focusing children on mount. It also acts as a container for a programmatic focus
|
|
118
|
+
* management interface that can be used to move focus forward and back in response
|
|
119
|
+
* to user events.
|
|
120
|
+
*/
|
|
121
|
+
const FocusScope = (props) => {
|
|
122
|
+
if (isServer) return <>{props.children}</>;
|
|
123
|
+
let startRef;
|
|
124
|
+
let endRef;
|
|
125
|
+
const [scopeElements, setScopeElements] = createSignal([]);
|
|
126
|
+
const parentScopeRef = useContext(FocusScopeContext)?.scopeRef ?? null;
|
|
127
|
+
let nodeToRestore = null;
|
|
128
|
+
const getRestorableElement = (element, doc) => {
|
|
129
|
+
if (!element || element === doc.body || element === doc.documentElement) return null;
|
|
130
|
+
return element;
|
|
131
|
+
};
|
|
132
|
+
const focusManager = {
|
|
133
|
+
focusNext(opts = {}) {
|
|
134
|
+
const scope = scopeElements();
|
|
135
|
+
if (scope.length === 0) return null;
|
|
136
|
+
const { from, tabbable = true, wrap = false, accept } = opts;
|
|
137
|
+
const elements = getFocusableElements(scope, tabbable).filter((el) => !accept || accept(el));
|
|
138
|
+
const doc = getOwnerDocument(scope[0]);
|
|
139
|
+
const current = from || getActiveElement$1(doc);
|
|
140
|
+
if (!current || elements.length === 0) return null;
|
|
141
|
+
let nextIndex = elements.indexOf(current) + 1;
|
|
142
|
+
if (nextIndex >= elements.length) if (wrap) nextIndex = 0;
|
|
143
|
+
else return null;
|
|
144
|
+
const nextElement = elements[nextIndex];
|
|
145
|
+
if (nextElement) {
|
|
146
|
+
focusSafely(nextElement);
|
|
147
|
+
return nextElement;
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
},
|
|
151
|
+
focusPrevious(opts = {}) {
|
|
152
|
+
const scope = scopeElements();
|
|
153
|
+
if (scope.length === 0) return null;
|
|
154
|
+
const { from, tabbable = true, wrap = false, accept } = opts;
|
|
155
|
+
const elements = getFocusableElements(scope, tabbable).filter((el) => !accept || accept(el));
|
|
156
|
+
const doc = getOwnerDocument(scope[0]);
|
|
157
|
+
const current = from || getActiveElement$1(doc);
|
|
158
|
+
if (!current || elements.length === 0) return null;
|
|
159
|
+
let prevIndex = elements.indexOf(current) - 1;
|
|
160
|
+
if (prevIndex < 0) if (wrap) prevIndex = elements.length - 1;
|
|
161
|
+
else return null;
|
|
162
|
+
const prevElement = elements[prevIndex];
|
|
163
|
+
if (prevElement) {
|
|
164
|
+
focusSafely(prevElement);
|
|
165
|
+
return prevElement;
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
},
|
|
169
|
+
focusFirst(opts = {}) {
|
|
170
|
+
const scope = scopeElements();
|
|
171
|
+
if (scope.length === 0) return null;
|
|
172
|
+
const { tabbable = true, accept } = opts;
|
|
173
|
+
const elements = getFocusableElements(scope, tabbable).filter((el) => !accept || accept(el));
|
|
174
|
+
if (elements.length > 0) {
|
|
175
|
+
focusSafely(elements[0]);
|
|
176
|
+
return elements[0];
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
},
|
|
180
|
+
focusLast(opts = {}) {
|
|
181
|
+
const scope = scopeElements();
|
|
182
|
+
if (scope.length === 0) return null;
|
|
183
|
+
const { tabbable = true, accept } = opts;
|
|
184
|
+
const elements = getFocusableElements(scope, tabbable).filter((el) => !accept || accept(el));
|
|
185
|
+
if (elements.length > 0) {
|
|
186
|
+
const lastElement = elements[elements.length - 1];
|
|
187
|
+
focusSafely(lastElement);
|
|
188
|
+
return lastElement;
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
onMount(() => {});
|
|
194
|
+
onMount(() => {
|
|
195
|
+
focusScopeTree.addTreeNode(scopeElements, parentScopeRef);
|
|
196
|
+
});
|
|
197
|
+
onCleanup(() => {
|
|
198
|
+
focusScopeTree.removeTreeNode(scopeElements);
|
|
199
|
+
});
|
|
200
|
+
onMount(() => {
|
|
201
|
+
if (!props.restoreFocus) return;
|
|
202
|
+
const scopeDoc = document;
|
|
203
|
+
const scopeActive = getActiveElement$1(scopeDoc);
|
|
204
|
+
const topActive = getActiveElement$1(document);
|
|
205
|
+
if (scopeDoc !== document && document.activeElement instanceof HTMLIFrameElement && document.activeElement.contentDocument === scopeDoc && scopeActive && scopeActive !== scopeDoc.body) {
|
|
206
|
+
nodeToRestore = getRestorableElement(scopeActive, scopeDoc);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
nodeToRestore = getRestorableElement(topActive, document);
|
|
210
|
+
});
|
|
211
|
+
createEffect(() => {
|
|
212
|
+
if (!props.autoFocus) return;
|
|
213
|
+
const scope = scopeElements();
|
|
214
|
+
if (scope.length === 0) return;
|
|
215
|
+
if (!isElementInScope(getActiveElement$1(getOwnerDocument(scope[0])), scope)) focusManager.focusFirst();
|
|
216
|
+
});
|
|
217
|
+
createEffect(() => {
|
|
218
|
+
if (!props.contain) return;
|
|
219
|
+
const scope = scopeElements();
|
|
220
|
+
if (scope.length === 0) return;
|
|
221
|
+
const doc = getOwnerDocument(scope[0]);
|
|
222
|
+
let focusedNode = null;
|
|
223
|
+
const onKeyDown = (e) => {
|
|
224
|
+
if (e.key !== "Tab" || e.altKey || e.ctrlKey || e.metaKey) return;
|
|
225
|
+
const scope = scopeElements();
|
|
226
|
+
const activeElement = getActiveElement$1(doc);
|
|
227
|
+
if (!isElementInScope(activeElement, scope)) return;
|
|
228
|
+
const elements = getFocusableElements(scope, true);
|
|
229
|
+
if (elements.length === 0) return;
|
|
230
|
+
const firstElement = elements[0];
|
|
231
|
+
const lastElement = elements[elements.length - 1];
|
|
232
|
+
if (e.shiftKey && activeElement === firstElement) {
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
focusSafely(lastElement);
|
|
235
|
+
} else if (!e.shiftKey && activeElement === lastElement) {
|
|
236
|
+
e.preventDefault();
|
|
237
|
+
focusSafely(firstElement);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const onFocusIn = (e) => {
|
|
241
|
+
const scope = scopeElements();
|
|
242
|
+
const target = e.target;
|
|
243
|
+
if (isElementInScope(target, scope)) focusedNode = target;
|
|
244
|
+
else if (isElementInChildScope(target, scopeElements)) focusedNode = target;
|
|
245
|
+
else if (focusedNode) focusSafely(focusedNode);
|
|
246
|
+
else focusManager.focusFirst();
|
|
247
|
+
};
|
|
248
|
+
let restoreRaf = null;
|
|
249
|
+
const onFocusOut = (e) => {
|
|
250
|
+
const target = e.target;
|
|
251
|
+
if (!isElementInScope(target, scopeElements())) return;
|
|
252
|
+
const win = doc.defaultView ?? window;
|
|
253
|
+
if (restoreRaf != null) win.cancelAnimationFrame(restoreRaf);
|
|
254
|
+
restoreRaf = win.requestAnimationFrame(() => {
|
|
255
|
+
restoreRaf = null;
|
|
256
|
+
const scope = scopeElements();
|
|
257
|
+
const activeElement = getActiveElement$1(doc);
|
|
258
|
+
if (activeElement && (isElementInScope(activeElement, scope) || isElementInChildScope(activeElement, scopeElements))) return;
|
|
259
|
+
if (doc.body.contains(target)) {
|
|
260
|
+
focusedNode = target;
|
|
261
|
+
focusSafely(target);
|
|
262
|
+
} else focusManager.focusFirst();
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
doc.addEventListener("keydown", onKeyDown, true);
|
|
266
|
+
doc.addEventListener("focusin", onFocusIn, true);
|
|
267
|
+
doc.addEventListener("focusout", onFocusOut, true);
|
|
268
|
+
onCleanup(() => {
|
|
269
|
+
doc.removeEventListener("keydown", onKeyDown, true);
|
|
270
|
+
doc.removeEventListener("focusin", onFocusIn, true);
|
|
271
|
+
doc.removeEventListener("focusout", onFocusOut, true);
|
|
272
|
+
if (restoreRaf != null) (doc.defaultView ?? window).cancelAnimationFrame(restoreRaf);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
onCleanup(() => {
|
|
276
|
+
if (props.restoreFocus && nodeToRestore && nodeToRestore.focus) {
|
|
277
|
+
const doc = getOwnerDocument(nodeToRestore);
|
|
278
|
+
(doc.defaultView ?? window).requestAnimationFrame(() => {
|
|
279
|
+
if (nodeToRestore && doc.body.contains(nodeToRestore)) nodeToRestore.focus();
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
return <FocusScopeContext.Provider value={{
|
|
284
|
+
focusManager,
|
|
285
|
+
scopeRef: scopeElements
|
|
286
|
+
}}>
|
|
287
|
+
<span data-focus-scope-start hidden ref={startRef} />
|
|
288
|
+
{props.children}
|
|
289
|
+
<span data-focus-scope-end hidden ref={endRef} />
|
|
290
|
+
</FocusScopeContext.Provider>;
|
|
291
|
+
};
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region src/focus/createFocusRestore.ts
|
|
294
|
+
/**
|
|
295
|
+
* Focus restoration utilities for solidaria
|
|
296
|
+
*
|
|
297
|
+
* Provides enhanced focus restoration with retry logic, cross-scope tracking,
|
|
298
|
+
* and safe restoration patterns.
|
|
299
|
+
*/
|
|
300
|
+
const focusStack = [];
|
|
301
|
+
/**
|
|
302
|
+
* Push an element onto the focus stack.
|
|
303
|
+
*/
|
|
304
|
+
function pushFocusStack(element) {
|
|
305
|
+
focusStack.push(element);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Pop the last element from the focus stack.
|
|
309
|
+
*/
|
|
310
|
+
function popFocusStack() {
|
|
311
|
+
return focusStack.pop();
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Get the current focus stack length.
|
|
315
|
+
*/
|
|
316
|
+
function getFocusStackLength() {
|
|
317
|
+
return focusStack.length;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Clear the entire focus stack.
|
|
321
|
+
*/
|
|
322
|
+
function clearFocusStack() {
|
|
323
|
+
focusStack.length = 0;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Gets the active element, accounting for shadow DOM.
|
|
327
|
+
*/
|
|
328
|
+
function getActiveElement(doc) {
|
|
329
|
+
let activeElement = doc.activeElement;
|
|
330
|
+
while (activeElement?.shadowRoot?.activeElement) activeElement = activeElement.shadowRoot.activeElement;
|
|
331
|
+
return activeElement;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Checks if an element is still valid for focus restoration.
|
|
335
|
+
*/
|
|
336
|
+
function isValidForRestore(element) {
|
|
337
|
+
if (!element) return false;
|
|
338
|
+
if (!document.body.contains(element)) return false;
|
|
339
|
+
if (element.hasAttribute("disabled")) return false;
|
|
340
|
+
if (element.getAttribute("aria-disabled") === "true") return false;
|
|
341
|
+
if (element.getAttribute("aria-hidden") === "true") return false;
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Attempts to restore focus with retries.
|
|
346
|
+
*/
|
|
347
|
+
function tryRestoreFocus(element, options) {
|
|
348
|
+
const { maxRetries, retryDelay, preventScroll, onRestore, onRestoreFailed } = options;
|
|
349
|
+
let attempts = 0;
|
|
350
|
+
const attempt = () => {
|
|
351
|
+
if (!element) {
|
|
352
|
+
onRestoreFailed?.();
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (isValidForRestore(element)) {
|
|
356
|
+
if (preventScroll) focusSafely(element);
|
|
357
|
+
else element.focus();
|
|
358
|
+
onRestore?.(element);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
attempts++;
|
|
362
|
+
if (attempts < maxRetries) setTimeout(attempt, retryDelay);
|
|
363
|
+
else onRestoreFailed?.();
|
|
364
|
+
};
|
|
365
|
+
requestAnimationFrame(attempt);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Creates a focus restoration manager.
|
|
369
|
+
*
|
|
370
|
+
* This hook saves the currently focused element when mounted and provides
|
|
371
|
+
* methods to restore focus later, with retry logic for reliability.
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```tsx
|
|
375
|
+
* function Modal(props) {
|
|
376
|
+
* const focusRestore = createFocusRestore({
|
|
377
|
+
* restoreOnUnmount: true,
|
|
378
|
+
* onRestore: () => console.log('Focus restored'),
|
|
379
|
+
* });
|
|
380
|
+
*
|
|
381
|
+
* return (
|
|
382
|
+
* <div role="dialog">
|
|
383
|
+
* {props.children}
|
|
384
|
+
* <button onClick={() => focusRestore.restore()}>
|
|
385
|
+
* Close
|
|
386
|
+
* </button>
|
|
387
|
+
* </div>
|
|
388
|
+
* );
|
|
389
|
+
* }
|
|
390
|
+
* ```
|
|
391
|
+
*
|
|
392
|
+
* @example
|
|
393
|
+
* ```tsx
|
|
394
|
+
* // Manual focus management
|
|
395
|
+
* function Dropdown() {
|
|
396
|
+
* const focusRestore = createFocusRestore({ restoreOnUnmount: false });
|
|
397
|
+
*
|
|
398
|
+
* const onOpen = () => {
|
|
399
|
+
* focusRestore.saveCurrentFocus();
|
|
400
|
+
* // Focus dropdown content
|
|
401
|
+
* };
|
|
402
|
+
*
|
|
403
|
+
* const onClose = () => {
|
|
404
|
+
* focusRestore.restore();
|
|
405
|
+
* };
|
|
406
|
+
*
|
|
407
|
+
* return <div>...</div>;
|
|
408
|
+
* }
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
function createFocusRestore(options = {}) {
|
|
412
|
+
const { restoreOnUnmount = true, maxRetries = 3, retryDelay = 50, onRestore, onRestoreFailed, preventScroll = true } = options;
|
|
413
|
+
if (isServer) return {
|
|
414
|
+
restore: () => false,
|
|
415
|
+
getSavedElement: () => null,
|
|
416
|
+
saveCurrentFocus: () => {},
|
|
417
|
+
clear: () => {}
|
|
418
|
+
};
|
|
419
|
+
let savedElement = null;
|
|
420
|
+
onMount(() => {
|
|
421
|
+
saveCurrentFocus();
|
|
422
|
+
});
|
|
423
|
+
onCleanup(() => {
|
|
424
|
+
if (restoreOnUnmount && savedElement) tryRestoreFocus(savedElement, {
|
|
425
|
+
maxRetries,
|
|
426
|
+
retryDelay,
|
|
427
|
+
preventScroll,
|
|
428
|
+
onRestore: onRestore ?? (() => {}),
|
|
429
|
+
onRestoreFailed: onRestoreFailed ?? (() => {})
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
function saveCurrentFocus() {
|
|
433
|
+
const doc = typeof document !== "undefined" ? document : null;
|
|
434
|
+
if (!doc) return;
|
|
435
|
+
const active = getActiveElement(doc);
|
|
436
|
+
if (active && active !== doc.body) {
|
|
437
|
+
savedElement = active;
|
|
438
|
+
pushFocusStack(active);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function restore() {
|
|
442
|
+
if (!savedElement) return false;
|
|
443
|
+
if (isValidForRestore(savedElement)) {
|
|
444
|
+
if (preventScroll) focusSafely(savedElement);
|
|
445
|
+
else savedElement.focus();
|
|
446
|
+
onRestore?.(savedElement);
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
while (focusStack.length > 0) {
|
|
450
|
+
const stackElement = popFocusStack();
|
|
451
|
+
if (stackElement && isValidForRestore(stackElement)) {
|
|
452
|
+
if (preventScroll) focusSafely(stackElement);
|
|
453
|
+
else stackElement.focus();
|
|
454
|
+
onRestore?.(stackElement);
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
onRestoreFailed?.();
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
function getSavedElement() {
|
|
462
|
+
return savedElement;
|
|
463
|
+
}
|
|
464
|
+
function clear() {
|
|
465
|
+
savedElement = null;
|
|
466
|
+
}
|
|
467
|
+
return {
|
|
468
|
+
restore,
|
|
469
|
+
getSavedElement,
|
|
470
|
+
saveCurrentFocus,
|
|
471
|
+
clear
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
//#endregion
|
|
475
|
+
//#region src/focus/createVirtualFocus.ts
|
|
476
|
+
/**
|
|
477
|
+
* Virtual focus management for solidaria
|
|
478
|
+
*
|
|
479
|
+
* Provides virtual focus for large collections where tracking DOM focus
|
|
480
|
+
* on every item is impractical. Instead, a single element receives real
|
|
481
|
+
* focus while aria-activedescendant indicates the virtually focused item.
|
|
482
|
+
*
|
|
483
|
+
* This is commonly used in:
|
|
484
|
+
* - Virtualized lists (where not all items are in the DOM)
|
|
485
|
+
* - Large trees
|
|
486
|
+
* - Autocomplete/combobox suggestions
|
|
487
|
+
* - Grid/table navigation
|
|
488
|
+
*/
|
|
489
|
+
const DEFAULT_PAGE_SIZE = 10;
|
|
490
|
+
/**
|
|
491
|
+
* Creates virtual focus management for a collection.
|
|
492
|
+
*
|
|
493
|
+
* Virtual focus uses aria-activedescendant to indicate which item is
|
|
494
|
+
* "focused" while keeping real DOM focus on a container element. This
|
|
495
|
+
* is more performant for large collections and required for virtualized
|
|
496
|
+
* lists where items may not be in the DOM.
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* ```tsx
|
|
500
|
+
* function Listbox(props) {
|
|
501
|
+
* const virtualFocus = createVirtualFocus({
|
|
502
|
+
* items: () => props.items,
|
|
503
|
+
* getKey: (item) => item.id,
|
|
504
|
+
* isDisabled: (item) => item.disabled,
|
|
505
|
+
* });
|
|
506
|
+
*
|
|
507
|
+
* return (
|
|
508
|
+
* <ul
|
|
509
|
+
* role="listbox"
|
|
510
|
+
* tabIndex={0}
|
|
511
|
+
* aria-activedescendant={virtualFocus.containerProps['aria-activedescendant']()}
|
|
512
|
+
* onKeyDown={virtualFocus.containerProps.onKeyDown}
|
|
513
|
+
* >
|
|
514
|
+
* <For each={props.items}>
|
|
515
|
+
* {(item) => (
|
|
516
|
+
* <li
|
|
517
|
+
* {...virtualFocus.getItemProps(item.id)}
|
|
518
|
+
* role="option"
|
|
519
|
+
* aria-selected={virtualFocus.isFocused(item.id)}
|
|
520
|
+
* >
|
|
521
|
+
* {item.name}
|
|
522
|
+
* </li>
|
|
523
|
+
* )}
|
|
524
|
+
* </For>
|
|
525
|
+
* </ul>
|
|
526
|
+
* );
|
|
527
|
+
* }
|
|
528
|
+
* ```
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```tsx
|
|
532
|
+
* // With controlled focus
|
|
533
|
+
* function ControlledListbox() {
|
|
534
|
+
* const [focusedKey, setFocusedKey] = createSignal<string | null>(null);
|
|
535
|
+
*
|
|
536
|
+
* const virtualFocus = createVirtualFocus({
|
|
537
|
+
* items: () => items,
|
|
538
|
+
* getKey: (item) => item.id,
|
|
539
|
+
* focusedKey: focusedKey,
|
|
540
|
+
* onFocusChange: setFocusedKey,
|
|
541
|
+
* });
|
|
542
|
+
*
|
|
543
|
+
* return <ul>...</ul>;
|
|
544
|
+
* }
|
|
545
|
+
* ```
|
|
546
|
+
*/
|
|
547
|
+
function createVirtualFocus(options) {
|
|
548
|
+
const { items, getKey, isDisabled = () => false, defaultFocusedKey, focusedKey: controlledFocusedKey, onFocusChange, wrap = true, skipDisabled = true, orientation = "vertical" } = options;
|
|
549
|
+
if (isServer) {
|
|
550
|
+
const emptyAccessor = () => null;
|
|
551
|
+
return {
|
|
552
|
+
focusedKey: emptyAccessor,
|
|
553
|
+
focusedItem: emptyAccessor,
|
|
554
|
+
setFocusedKey: () => {},
|
|
555
|
+
focusNext: () => {},
|
|
556
|
+
focusPrevious: () => {},
|
|
557
|
+
focusFirst: () => {},
|
|
558
|
+
focusLast: () => {},
|
|
559
|
+
focusPageDown: () => {},
|
|
560
|
+
focusPageUp: () => {},
|
|
561
|
+
isFocused: () => false,
|
|
562
|
+
containerProps: {
|
|
563
|
+
"aria-activedescendant": () => void 0,
|
|
564
|
+
onKeyDown: () => {}
|
|
565
|
+
},
|
|
566
|
+
getItemProps: (key) => ({ id: `item-${key}` })
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
const [internalKey, setInternalKey] = createSignal(defaultFocusedKey ?? null);
|
|
570
|
+
const focusedKey = controlledFocusedKey ?? internalKey;
|
|
571
|
+
const setFocusedKey = (key) => {
|
|
572
|
+
if (controlledFocusedKey) onFocusChange?.(key);
|
|
573
|
+
else {
|
|
574
|
+
setInternalKey(key);
|
|
575
|
+
onFocusChange?.(key);
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
const focusedItem = () => {
|
|
579
|
+
const key = focusedKey();
|
|
580
|
+
if (!key) return null;
|
|
581
|
+
return items().find((item) => getKey(item) === key) ?? null;
|
|
582
|
+
};
|
|
583
|
+
const getValidItems = () => {
|
|
584
|
+
if (!skipDisabled) return items();
|
|
585
|
+
return items().filter((item) => !isDisabled(item));
|
|
586
|
+
};
|
|
587
|
+
const getKeyIndex = (key) => {
|
|
588
|
+
if (!key) return -1;
|
|
589
|
+
return getValidItems().findIndex((item) => getKey(item) === key);
|
|
590
|
+
};
|
|
591
|
+
const focusByIndex = (index) => {
|
|
592
|
+
const validItems = getValidItems();
|
|
593
|
+
if (validItems.length === 0) return;
|
|
594
|
+
let targetIndex = index;
|
|
595
|
+
if (wrap) targetIndex = (index % validItems.length + validItems.length) % validItems.length;
|
|
596
|
+
else targetIndex = Math.max(0, Math.min(index, validItems.length - 1));
|
|
597
|
+
const item = validItems[targetIndex];
|
|
598
|
+
if (item) setFocusedKey(getKey(item));
|
|
599
|
+
};
|
|
600
|
+
const focusNext = () => {
|
|
601
|
+
focusByIndex(getKeyIndex(focusedKey()) + 1);
|
|
602
|
+
};
|
|
603
|
+
const focusPrevious = () => {
|
|
604
|
+
const currentIndex = getKeyIndex(focusedKey());
|
|
605
|
+
if (currentIndex === -1) focusByIndex(getValidItems().length - 1);
|
|
606
|
+
else focusByIndex(currentIndex - 1);
|
|
607
|
+
};
|
|
608
|
+
const focusFirst = () => {
|
|
609
|
+
focusByIndex(0);
|
|
610
|
+
};
|
|
611
|
+
const focusLast = () => {
|
|
612
|
+
focusByIndex(getValidItems().length - 1);
|
|
613
|
+
};
|
|
614
|
+
const focusPageDown = (pageSize = DEFAULT_PAGE_SIZE) => {
|
|
615
|
+
focusByIndex(getKeyIndex(focusedKey()) + pageSize);
|
|
616
|
+
};
|
|
617
|
+
const focusPageUp = (pageSize = DEFAULT_PAGE_SIZE) => {
|
|
618
|
+
const currentIndex = getKeyIndex(focusedKey());
|
|
619
|
+
if (currentIndex === -1) focusByIndex(getValidItems().length - 1);
|
|
620
|
+
else focusByIndex(currentIndex - pageSize);
|
|
621
|
+
};
|
|
622
|
+
const isFocused = (key) => {
|
|
623
|
+
return focusedKey() === key;
|
|
624
|
+
};
|
|
625
|
+
const onKeyDown = (e) => {
|
|
626
|
+
const isVertical = orientation === "vertical" || orientation === "both";
|
|
627
|
+
const isHorizontal = orientation === "horizontal" || orientation === "both";
|
|
628
|
+
switch (e.key) {
|
|
629
|
+
case "ArrowDown":
|
|
630
|
+
if (isVertical) {
|
|
631
|
+
e.preventDefault();
|
|
632
|
+
focusNext();
|
|
633
|
+
}
|
|
634
|
+
break;
|
|
635
|
+
case "ArrowUp":
|
|
636
|
+
if (isVertical) {
|
|
637
|
+
e.preventDefault();
|
|
638
|
+
focusPrevious();
|
|
639
|
+
}
|
|
640
|
+
break;
|
|
641
|
+
case "ArrowRight":
|
|
642
|
+
if (isHorizontal) {
|
|
643
|
+
e.preventDefault();
|
|
644
|
+
focusNext();
|
|
645
|
+
}
|
|
646
|
+
break;
|
|
647
|
+
case "ArrowLeft":
|
|
648
|
+
if (isHorizontal) {
|
|
649
|
+
e.preventDefault();
|
|
650
|
+
focusPrevious();
|
|
651
|
+
}
|
|
652
|
+
break;
|
|
653
|
+
case "Home":
|
|
654
|
+
e.preventDefault();
|
|
655
|
+
focusFirst();
|
|
656
|
+
break;
|
|
657
|
+
case "End":
|
|
658
|
+
e.preventDefault();
|
|
659
|
+
focusLast();
|
|
660
|
+
break;
|
|
661
|
+
case "PageDown":
|
|
662
|
+
e.preventDefault();
|
|
663
|
+
focusPageDown();
|
|
664
|
+
break;
|
|
665
|
+
case "PageUp":
|
|
666
|
+
e.preventDefault();
|
|
667
|
+
focusPageUp();
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
const containerProps = {
|
|
672
|
+
"aria-activedescendant": () => {
|
|
673
|
+
const key = focusedKey();
|
|
674
|
+
return key ? `item-${key}` : void 0;
|
|
675
|
+
},
|
|
676
|
+
onKeyDown
|
|
677
|
+
};
|
|
678
|
+
const getItemProps = (key) => ({ id: `item-${key}` });
|
|
679
|
+
return {
|
|
680
|
+
focusedKey,
|
|
681
|
+
focusedItem,
|
|
682
|
+
setFocusedKey,
|
|
683
|
+
focusNext,
|
|
684
|
+
focusPrevious,
|
|
685
|
+
focusFirst,
|
|
686
|
+
focusLast,
|
|
687
|
+
focusPageDown,
|
|
688
|
+
focusPageUp,
|
|
689
|
+
isFocused,
|
|
690
|
+
containerProps,
|
|
691
|
+
getItemProps
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
//#endregion
|
|
695
|
+
//#region src/focus/createAutoFocus.ts
|
|
696
|
+
/**
|
|
697
|
+
* Auto-focus management for solidaria
|
|
698
|
+
*
|
|
699
|
+
* Provides priority-based auto-focus with deferred execution
|
|
700
|
+
* and conflict resolution for multiple auto-focus elements.
|
|
701
|
+
*/
|
|
702
|
+
let autoFocusQueue = [];
|
|
703
|
+
let processingTimeout = null;
|
|
704
|
+
/**
|
|
705
|
+
* Process the auto-focus queue and focus the highest priority element.
|
|
706
|
+
*/
|
|
707
|
+
function processAutoFocusQueue() {
|
|
708
|
+
if (processingTimeout) {
|
|
709
|
+
clearTimeout(processingTimeout);
|
|
710
|
+
processingTimeout = null;
|
|
711
|
+
}
|
|
712
|
+
if (autoFocusQueue.length === 0) return;
|
|
713
|
+
autoFocusQueue.sort((a, b) => b.priority - a.priority);
|
|
714
|
+
const winner = autoFocusQueue[0];
|
|
715
|
+
const losers = autoFocusQueue.slice(1);
|
|
716
|
+
autoFocusQueue = [];
|
|
717
|
+
for (const loser of losers) loser.onSkip?.();
|
|
718
|
+
const element = winner.ref();
|
|
719
|
+
if (!element) {
|
|
720
|
+
winner.onSkip?.();
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
const activeElement = document.activeElement;
|
|
724
|
+
if (!(winner.force || !activeElement || activeElement === document.body || activeElement === document.documentElement)) {
|
|
725
|
+
winner.onSkip?.();
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
if (winner.delay > 0) setTimeout(() => {
|
|
729
|
+
const el = winner.ref();
|
|
730
|
+
if (el && document.body.contains(el)) {
|
|
731
|
+
if (winner.preventScroll) focusSafely(el);
|
|
732
|
+
else el.focus();
|
|
733
|
+
winner.onFocus?.(el);
|
|
734
|
+
}
|
|
735
|
+
}, winner.delay);
|
|
736
|
+
else {
|
|
737
|
+
if (winner.preventScroll) focusSafely(element);
|
|
738
|
+
else element.focus();
|
|
739
|
+
winner.onFocus?.(element);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Queue an element for auto-focus.
|
|
744
|
+
*/
|
|
745
|
+
function queueAutoFocus(item) {
|
|
746
|
+
autoFocusQueue.push(item);
|
|
747
|
+
if (processingTimeout === null) processingTimeout = setTimeout(processAutoFocusQueue, 0);
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Remove an item from the auto-focus queue.
|
|
751
|
+
*/
|
|
752
|
+
function removeFromQueue(ref) {
|
|
753
|
+
autoFocusQueue = autoFocusQueue.filter((item) => item.ref !== ref);
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Creates auto-focus behavior for an element.
|
|
757
|
+
*
|
|
758
|
+
* This hook registers the element for auto-focus when mounted. If multiple
|
|
759
|
+
* elements request auto-focus, the one with the highest priority wins.
|
|
760
|
+
*
|
|
761
|
+
* @param ref - Accessor for the element to focus
|
|
762
|
+
* @param options - Auto-focus options
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* ```tsx
|
|
766
|
+
* function Dialog(props) {
|
|
767
|
+
* let contentRef: HTMLDivElement | undefined;
|
|
768
|
+
*
|
|
769
|
+
* createAutoFocus(() => contentRef, {
|
|
770
|
+
* priority: 10, // High priority for dialogs
|
|
771
|
+
* onFocus: () => console.log('Dialog focused'),
|
|
772
|
+
* });
|
|
773
|
+
*
|
|
774
|
+
* return (
|
|
775
|
+
* <div ref={contentRef} tabIndex={-1}>
|
|
776
|
+
* {props.children}
|
|
777
|
+
* </div>
|
|
778
|
+
* );
|
|
779
|
+
* }
|
|
780
|
+
* ```
|
|
781
|
+
*
|
|
782
|
+
* @example
|
|
783
|
+
* ```tsx
|
|
784
|
+
* // With delay for animations
|
|
785
|
+
* function AnimatedPanel() {
|
|
786
|
+
* let panelRef: HTMLDivElement | undefined;
|
|
787
|
+
*
|
|
788
|
+
* createAutoFocus(() => panelRef, {
|
|
789
|
+
* delay: 300, // Wait for animation
|
|
790
|
+
* });
|
|
791
|
+
*
|
|
792
|
+
* return <div ref={panelRef} class="animated-panel">...</div>;
|
|
793
|
+
* }
|
|
794
|
+
* ```
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* ```tsx
|
|
798
|
+
* // Conditional auto-focus
|
|
799
|
+
* function Input(props) {
|
|
800
|
+
* let inputRef: HTMLInputElement | undefined;
|
|
801
|
+
*
|
|
802
|
+
* createAutoFocus(() => inputRef, {
|
|
803
|
+
* isEnabled: props.autoFocus,
|
|
804
|
+
* });
|
|
805
|
+
*
|
|
806
|
+
* return <input ref={inputRef} />;
|
|
807
|
+
* }
|
|
808
|
+
* ```
|
|
809
|
+
*/
|
|
810
|
+
function createAutoFocus(ref, options = {}) {
|
|
811
|
+
const { isEnabled = true, priority = 0, delay = 0, force = false, preventScroll = true, onFocus, onSkip } = options;
|
|
812
|
+
if (isServer) return {
|
|
813
|
+
focus: () => {},
|
|
814
|
+
cancel: () => {}
|
|
815
|
+
};
|
|
816
|
+
let canceled = false;
|
|
817
|
+
onMount(() => {
|
|
818
|
+
if (!isEnabled || canceled) return;
|
|
819
|
+
queueAutoFocus({
|
|
820
|
+
ref,
|
|
821
|
+
priority,
|
|
822
|
+
delay,
|
|
823
|
+
force,
|
|
824
|
+
preventScroll,
|
|
825
|
+
onFocus,
|
|
826
|
+
onSkip
|
|
827
|
+
});
|
|
828
|
+
});
|
|
829
|
+
onCleanup(() => {
|
|
830
|
+
removeFromQueue(ref);
|
|
831
|
+
});
|
|
832
|
+
const focus = () => {
|
|
833
|
+
if (canceled) return;
|
|
834
|
+
const element = ref();
|
|
835
|
+
if (!element) return;
|
|
836
|
+
if (preventScroll) focusSafely(element);
|
|
837
|
+
else element.focus();
|
|
838
|
+
onFocus?.(element);
|
|
839
|
+
};
|
|
840
|
+
const cancel = () => {
|
|
841
|
+
canceled = true;
|
|
842
|
+
removeFromQueue(ref);
|
|
843
|
+
};
|
|
844
|
+
return {
|
|
845
|
+
focus,
|
|
846
|
+
cancel
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Clears all pending auto-focus requests.
|
|
851
|
+
* Useful for testing or when navigating away.
|
|
852
|
+
*/
|
|
853
|
+
function clearAutoFocusQueue() {
|
|
854
|
+
if (processingTimeout) {
|
|
855
|
+
clearTimeout(processingTimeout);
|
|
856
|
+
processingTimeout = null;
|
|
857
|
+
}
|
|
858
|
+
autoFocusQueue = [];
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Gets the current auto-focus queue length.
|
|
862
|
+
* Useful for debugging.
|
|
863
|
+
*/
|
|
864
|
+
function getAutoFocusQueueLength() {
|
|
865
|
+
return autoFocusQueue.length;
|
|
866
|
+
}
|
|
867
|
+
//#endregion
|
|
868
|
+
export { clearFocusStack as a, popFocusStack as c, useFocusManager as d, createVirtualFocus as i, pushFocusStack as l, createAutoFocus as n, createFocusRestore as o, getAutoFocusQueueLength as r, getFocusStackLength as s, clearAutoFocusQueue as t, FocusScope as u };
|
|
869
|
+
|
|
870
|
+
//# sourceMappingURL=focus2.jsx.map
|