@ariakit/react-components 0.1.1 → 0.1.2
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/CHANGELOG.md +51 -0
- package/dist/button/button.d.ts +1 -1
- package/dist/{button-Cp853csH.d.ts → button-CVWcOgxs.d.ts} +3 -3
- package/dist/{button-Cp853csH.d.ts.map → button-CVWcOgxs.d.ts.map} +1 -1
- package/dist/checkbox/checkbox-check.d.ts +1 -1
- package/dist/checkbox/checkbox-check.d.ts.map +1 -1
- package/dist/checkbox/checkbox.d.ts +2 -2
- package/dist/checkbox/checkbox.d.ts.map +1 -1
- package/dist/collection/collection-item-offscreen.d.ts +1 -1
- package/dist/collection/collection-item-offscreen.js +1 -1
- package/dist/collection/collection-item-offscreen.js.map +1 -1
- package/dist/collection/collection-item.d.ts +1 -1
- package/dist/collection/collection-renderer.d.ts +1 -1
- package/dist/collection/collection-renderer.js +1 -1
- package/dist/collection/collection-renderer.js.map +1 -1
- package/dist/collection/collection.d.ts +1 -1
- package/dist/collection/collection.d.ts.map +1 -1
- package/dist/{collection-item-offscreen-DyXa-sqj.d.ts → collection-item-offscreen-B5E5vNFi.d.ts} +2 -2
- package/dist/{collection-item-offscreen-DyXa-sqj.d.ts.map → collection-item-offscreen-B5E5vNFi.d.ts.map} +1 -1
- package/dist/{collection-item-C-g2BwVF.d.ts → collection-item-pvEWNoNs.d.ts} +2 -2
- package/dist/{collection-item-C-g2BwVF.d.ts.map → collection-item-pvEWNoNs.d.ts.map} +1 -1
- package/dist/{collection-renderer-DsPD9ksD.d.ts → collection-renderer-BhzF21Du.d.ts} +29 -15
- package/dist/collection-renderer-BhzF21Du.d.ts.map +1 -0
- package/dist/combobox/combobox-cancel.d.ts +2 -2
- package/dist/combobox/combobox-cancel.d.ts.map +1 -1
- package/dist/combobox/combobox-cancel.js +1 -1
- package/dist/combobox/combobox-cancel.js.map +1 -1
- package/dist/combobox/combobox-disclosure.d.ts +2 -2
- package/dist/combobox/combobox-disclosure.d.ts.map +1 -1
- package/dist/combobox/combobox-disclosure.js +1 -1
- package/dist/combobox/combobox-disclosure.js.map +1 -1
- package/dist/combobox/combobox-group-label.d.ts +1 -1
- package/dist/combobox/combobox-group-label.d.ts.map +1 -1
- package/dist/combobox/combobox-group.d.ts +1 -1
- package/dist/combobox/combobox-group.d.ts.map +1 -1
- package/dist/combobox/combobox-group.js +1 -1
- package/dist/combobox/combobox-group.js.map +1 -1
- package/dist/combobox/combobox-item-check.d.ts +1 -1
- package/dist/combobox/combobox-item-check.d.ts.map +1 -1
- package/dist/combobox/combobox-item-value.d.ts +1 -1
- package/dist/combobox/combobox-item-value.d.ts.map +1 -1
- package/dist/combobox/combobox-item.d.ts +3 -3
- package/dist/combobox/combobox-item.d.ts.map +1 -1
- package/dist/combobox/combobox-item.js +1 -1
- package/dist/combobox/combobox-item.js.map +1 -1
- package/dist/combobox/combobox-label.d.ts +1 -1
- package/dist/combobox/combobox-label.d.ts.map +1 -1
- package/dist/combobox/combobox-label.js +1 -1
- package/dist/combobox/combobox-label.js.map +1 -1
- package/dist/combobox/combobox-list.d.ts +1 -1
- package/dist/combobox/combobox-list.d.ts.map +1 -1
- package/dist/combobox/combobox-list.js +1 -1
- package/dist/combobox/combobox-list.js.map +1 -1
- package/dist/combobox/combobox-popover.d.ts +1 -1
- package/dist/combobox/combobox-popover.js +1 -1
- package/dist/combobox/combobox-popover.js.map +1 -1
- package/dist/combobox/combobox-row.d.ts +1 -1
- package/dist/combobox/combobox-row.d.ts.map +1 -1
- package/dist/combobox/combobox-row.js +1 -1
- package/dist/combobox/combobox-row.js.map +1 -1
- package/dist/combobox/combobox-separator.d.ts +1 -1
- package/dist/combobox/combobox-separator.d.ts.map +1 -1
- package/dist/combobox/combobox-separator.js +1 -1
- package/dist/combobox/combobox-separator.js.map +1 -1
- package/dist/combobox/combobox-value.js +1 -1
- package/dist/combobox/combobox-value.js.map +1 -1
- package/dist/combobox/combobox.d.ts +3 -3
- package/dist/combobox/combobox.d.ts.map +1 -1
- package/dist/combobox/combobox.js +16 -2
- package/dist/combobox/combobox.js.map +1 -1
- package/dist/command/command.d.ts +1 -1
- package/dist/{command-DckndCUK.d.ts → command-B9C8p3_S.d.ts} +3 -3
- package/dist/{command-DckndCUK.d.ts.map → command-B9C8p3_S.d.ts.map} +1 -1
- package/dist/composite/composite-container.d.ts +1 -1
- package/dist/composite/composite-container.d.ts.map +1 -1
- package/dist/composite/composite-container.js +2 -2
- package/dist/composite/composite-container.js.map +1 -1
- package/dist/composite/composite-group-label.d.ts +2 -2
- package/dist/composite/composite-group-label.d.ts.map +1 -1
- package/dist/composite/composite-group.d.ts +2 -2
- package/dist/composite/composite-group.d.ts.map +1 -1
- package/dist/composite/composite-hover.d.ts +1 -1
- package/dist/composite/composite-hover.js +9 -13
- package/dist/composite/composite-hover.js.map +1 -1
- package/dist/composite/composite-input.d.ts +1 -1
- package/dist/composite/composite-input.d.ts.map +1 -1
- package/dist/composite/composite-input.js +1 -1
- package/dist/composite/composite-input.js.map +1 -1
- package/dist/composite/composite-item-offscreen.d.ts +2 -2
- package/dist/composite/composite-item-offscreen.js +2 -2
- package/dist/composite/composite-item-offscreen.js.map +1 -1
- package/dist/composite/composite-item.d.ts +1 -1
- package/dist/composite/composite-item.js +2 -2
- package/dist/composite/composite-item.js.map +1 -1
- package/dist/composite/composite-overflow-disclosure.d.ts +2 -2
- package/dist/composite/composite-overflow-disclosure.d.ts.map +1 -1
- package/dist/composite/composite-overflow.d.ts +2 -2
- package/dist/composite/composite-overflow.d.ts.map +1 -1
- package/dist/composite/composite-renderer.d.ts +28 -14
- package/dist/composite/composite-renderer.d.ts.map +1 -1
- package/dist/composite/composite-renderer.js +2 -2
- package/dist/composite/composite-renderer.js.map +1 -1
- package/dist/composite/composite-row.d.ts +1 -1
- package/dist/composite/composite-row.d.ts.map +1 -1
- package/dist/composite/composite-row.js +3 -3
- package/dist/composite/composite-row.js.map +1 -1
- package/dist/composite/composite-separator.d.ts +2 -2
- package/dist/composite/composite-separator.d.ts.map +1 -1
- package/dist/composite/composite-separator.js +3 -3
- package/dist/composite/composite-separator.js.map +1 -1
- package/dist/composite/composite-typeahead.d.ts +1 -1
- package/dist/composite/composite-typeahead.js +3 -3
- package/dist/composite/composite-typeahead.js.map +1 -1
- package/dist/composite/composite.d.ts +1 -1
- package/dist/composite/composite.js +3 -3
- package/dist/composite/composite.js.map +1 -1
- package/dist/{composite-DLvyFHMq.d.ts → composite-KBhCGLEy.d.ts} +3 -3
- package/dist/{composite-DLvyFHMq.d.ts.map → composite-KBhCGLEy.d.ts.map} +1 -1
- package/dist/{composite-hover-C7ul163w.d.ts → composite-hover-BpXq3T8J.d.ts} +2 -2
- package/dist/{composite-hover-C7ul163w.d.ts.map → composite-hover-BpXq3T8J.d.ts.map} +1 -1
- package/dist/{composite-item-B4WTelVz.d.ts → composite-item-d4UXaZ84.d.ts} +4 -4
- package/dist/{composite-item-B4WTelVz.d.ts.map → composite-item-d4UXaZ84.d.ts.map} +1 -1
- package/dist/{composite-typeahead-DDhpyKqm.d.ts → composite-typeahead-0euW43GU.d.ts} +2 -2
- package/dist/{composite-typeahead-DDhpyKqm.d.ts.map → composite-typeahead-0euW43GU.d.ts.map} +1 -1
- package/dist/dialog/dialog-backdrop.d.ts +1 -1
- package/dist/dialog/dialog-description.d.ts +1 -1
- package/dist/dialog/dialog-disclosure.d.ts +1 -1
- package/dist/dialog/dialog-disclosure.js +1 -1
- package/dist/dialog/dialog-disclosure.js.map +1 -1
- package/dist/dialog/dialog-dismiss.d.ts +1 -1
- package/dist/dialog/dialog-heading.d.ts +1 -1
- package/dist/dialog/dialog.d.ts +1 -1
- package/dist/dialog/dialog.js +18 -6
- package/dist/dialog/dialog.js.map +1 -1
- package/dist/dialog/utils/disable-accessibility-tree-outside.d.ts +1 -3
- package/dist/dialog/utils/disable-accessibility-tree-outside.d.ts.map +1 -1
- package/dist/dialog/utils/disable-accessibility-tree-outside.js +1 -15
- package/dist/dialog/utils/disable-accessibility-tree-outside.js.map +1 -1
- package/dist/dialog/utils/use-hide-on-interact-outside.d.ts +1 -1
- package/dist/dialog/utils/use-hide-on-interact-outside.js +2 -2
- package/dist/dialog/utils/use-hide-on-interact-outside.js.map +1 -1
- package/dist/dialog/utils/use-prevent-body-scroll.js +2 -1
- package/dist/dialog/utils/use-prevent-body-scroll.js.map +1 -1
- package/dist/dialog/utils/use-previous-mouse-down-ref.d.ts +1 -1
- package/dist/dialog/utils/use-previous-mouse-down-ref.d.ts.map +1 -1
- package/dist/{dialog-C__C-zX2.d.ts → dialog-D23r2ZWj.d.ts} +4 -4
- package/dist/{dialog-C__C-zX2.d.ts.map → dialog-D23r2ZWj.d.ts.map} +1 -1
- package/dist/{dialog-description-BCZJ1Kyd.d.ts → dialog-description-CJGxnEvk.d.ts} +2 -2
- package/dist/{dialog-description-BCZJ1Kyd.d.ts.map → dialog-description-CJGxnEvk.d.ts.map} +1 -1
- package/dist/{dialog-disclosure-DLD10zlb.d.ts → dialog-disclosure-DSESk5pv.d.ts} +3 -3
- package/dist/{dialog-disclosure-DLD10zlb.d.ts.map → dialog-disclosure-DSESk5pv.d.ts.map} +1 -1
- package/dist/{dialog-dismiss-CnwEbzc6.d.ts → dialog-dismiss-DW3XQYvp.d.ts} +3 -3
- package/dist/{dialog-dismiss-CnwEbzc6.d.ts.map → dialog-dismiss-DW3XQYvp.d.ts.map} +1 -1
- package/dist/{dialog-heading-DQvnOfZH.d.ts → dialog-heading-DGA5d8VH.d.ts} +3 -3
- package/dist/{dialog-heading-DQvnOfZH.d.ts.map → dialog-heading-DGA5d8VH.d.ts.map} +1 -1
- package/dist/disclosure/disclosure-content.js +1 -1
- package/dist/disclosure/disclosure-content.js.map +1 -1
- package/dist/disclosure/disclosure.d.ts +1 -1
- package/dist/disclosure/disclosure.js +1 -1
- package/dist/disclosure/disclosure.js.map +1 -1
- package/dist/{disclosure-CQ37hPVP.d.ts → disclosure-C4F4sCVZ.d.ts} +3 -3
- package/dist/{disclosure-CQ37hPVP.d.ts.map → disclosure-C4F4sCVZ.d.ts.map} +1 -1
- package/dist/focus-trap/focus-trap-region.d.ts +1 -1
- package/dist/focus-trap/focus-trap-region.d.ts.map +1 -1
- package/dist/focus-trap/focus-trap.d.ts +1 -1
- package/dist/focus-trap/focus-trap.d.ts.map +1 -1
- package/dist/focusable/focusable-container.d.ts +1 -1
- package/dist/focusable/focusable-container.d.ts.map +1 -1
- package/dist/focusable/focusable.d.ts +1 -1
- package/dist/focusable/focusable.js +49 -8
- package/dist/focusable/focusable.js.map +1 -1
- package/dist/{focusable-B00tOxtB.d.ts → focusable-dBZH13-T.d.ts} +2 -2
- package/dist/{focusable-B00tOxtB.d.ts.map → focusable-dBZH13-T.d.ts.map} +1 -1
- package/dist/form/form-checkbox.d.ts +1 -1
- package/dist/form/form-checkbox.d.ts.map +1 -1
- package/dist/form/form-checkbox.js +1 -1
- package/dist/form/form-checkbox.js.map +1 -1
- package/dist/form/form-control.d.ts +2 -2
- package/dist/form/form-control.d.ts.map +1 -1
- package/dist/form/form-control.js +1 -1
- package/dist/form/form-control.js.map +1 -1
- package/dist/form/form-description.d.ts +2 -2
- package/dist/form/form-description.d.ts.map +1 -1
- package/dist/form/form-description.js +1 -1
- package/dist/form/form-description.js.map +1 -1
- package/dist/form/form-error.d.ts +2 -2
- package/dist/form/form-error.d.ts.map +1 -1
- package/dist/form/form-error.js +1 -1
- package/dist/form/form-error.js.map +1 -1
- package/dist/form/form-field.d.ts +1 -1
- package/dist/form/form-field.d.ts.map +1 -1
- package/dist/form/form-group-label.d.ts +2 -2
- package/dist/form/form-group-label.d.ts.map +1 -1
- package/dist/form/form-group.d.ts +2 -2
- package/dist/form/form-group.d.ts.map +1 -1
- package/dist/form/form-input.d.ts +2 -2
- package/dist/form/form-input.d.ts.map +1 -1
- package/dist/form/form-input.js +1 -1
- package/dist/form/form-input.js.map +1 -1
- package/dist/form/form-label.d.ts +2 -2
- package/dist/form/form-label.d.ts.map +1 -1
- package/dist/form/form-label.js +1 -1
- package/dist/form/form-label.js.map +1 -1
- package/dist/form/form-push.d.ts +3 -3
- package/dist/form/form-push.d.ts.map +1 -1
- package/dist/form/form-push.js +1 -1
- package/dist/form/form-push.js.map +1 -1
- package/dist/form/form-radio-group.d.ts +1 -1
- package/dist/form/form-radio-group.d.ts.map +1 -1
- package/dist/form/form-radio.d.ts +1 -1
- package/dist/form/form-radio.d.ts.map +1 -1
- package/dist/form/form-radio.js +1 -1
- package/dist/form/form-radio.js.map +1 -1
- package/dist/form/form-remove.d.ts +16 -12
- package/dist/form/form-remove.d.ts.map +1 -1
- package/dist/form/form-remove.js +15 -11
- package/dist/form/form-remove.js.map +1 -1
- package/dist/form/form-reset.d.ts +2 -2
- package/dist/form/form-reset.d.ts.map +1 -1
- package/dist/form/form-reset.js +1 -1
- package/dist/form/form-reset.js.map +1 -1
- package/dist/form/form-submit.d.ts +2 -2
- package/dist/form/form-submit.d.ts.map +1 -1
- package/dist/form/form-submit.js +1 -1
- package/dist/form/form-submit.js.map +1 -1
- package/dist/form/form.d.ts +1 -1
- package/dist/form/form.d.ts.map +1 -1
- package/dist/form/form.js +1 -1
- package/dist/form/form.js.map +1 -1
- package/dist/group/group-label.d.ts +1 -1
- package/dist/group/group.d.ts +1 -1
- package/dist/{group-label-C16IDs1b.d.ts → group-label-BKYqD4Sj.d.ts} +2 -2
- package/dist/{group-label-C16IDs1b.d.ts.map → group-label-BKYqD4Sj.d.ts.map} +1 -1
- package/dist/{group-CamegDJA.d.ts → group-nGD9e6Dj.d.ts} +2 -2
- package/dist/{group-CamegDJA.d.ts.map → group-nGD9e6Dj.d.ts.map} +1 -1
- package/dist/heading/heading.d.ts +1 -1
- package/dist/heading/heading.js +2 -2
- package/dist/heading/heading.js.map +1 -1
- package/dist/{heading-zY9g_9K-.d.ts → heading-D_AmeqL5.d.ts} +2 -2
- package/dist/{heading-zY9g_9K-.d.ts.map → heading-D_AmeqL5.d.ts.map} +1 -1
- package/dist/hovercard/hovercard-anchor.d.ts +2 -2
- package/dist/hovercard/hovercard-anchor.d.ts.map +1 -1
- package/dist/hovercard/hovercard-anchor.js +1 -1
- package/dist/hovercard/hovercard-anchor.js.map +1 -1
- package/dist/hovercard/hovercard-arrow.d.ts +1 -1
- package/dist/hovercard/hovercard-arrow.d.ts.map +1 -1
- package/dist/hovercard/hovercard-description.d.ts +2 -2
- package/dist/hovercard/hovercard-description.d.ts.map +1 -1
- package/dist/hovercard/hovercard-disclosure.d.ts +2 -2
- package/dist/hovercard/hovercard-disclosure.d.ts.map +1 -1
- package/dist/hovercard/hovercard-disclosure.js +4 -4
- package/dist/hovercard/hovercard-disclosure.js.map +1 -1
- package/dist/hovercard/hovercard-dismiss.d.ts +2 -2
- package/dist/hovercard/hovercard-dismiss.d.ts.map +1 -1
- package/dist/hovercard/hovercard-heading.d.ts +2 -2
- package/dist/hovercard/hovercard-heading.d.ts.map +1 -1
- package/dist/hovercard/hovercard.d.ts +1 -1
- package/dist/hovercard/hovercard.js +2 -2
- package/dist/hovercard/hovercard.js.map +1 -1
- package/dist/menu/menu-arrow.d.ts +2 -2
- package/dist/menu/menu-arrow.d.ts.map +1 -1
- package/dist/menu/menu-bar-provider.js +1 -1
- package/dist/menu/menu-bar-provider.js.map +1 -1
- package/dist/menu/menu-bar-store.d.ts +3 -3
- package/dist/menu/menu-bar-store.js +3 -3
- package/dist/menu/menu-bar-store.js.map +1 -1
- package/dist/menu/menu-bar.d.ts +1 -1
- package/dist/menu/menu-bar.d.ts.map +1 -1
- package/dist/menu/menu-bar.js +1 -1
- package/dist/menu/menu-bar.js.map +1 -1
- package/dist/menu/menu-button-arrow.d.ts +2 -2
- package/dist/menu/menu-button-arrow.d.ts.map +1 -1
- package/dist/menu/menu-button.d.ts +3 -3
- package/dist/menu/menu-button.d.ts.map +1 -1
- package/dist/menu/menu-button.js +1 -1
- package/dist/menu/menu-button.js.map +1 -1
- package/dist/menu/menu-context.d.ts +10 -3
- package/dist/menu/menu-context.d.ts.map +1 -1
- package/dist/menu/menu-context.js +8 -1
- package/dist/menu/menu-context.js.map +1 -1
- package/dist/menu/menu-description.d.ts +2 -2
- package/dist/menu/menu-description.d.ts.map +1 -1
- package/dist/menu/menu-dismiss.d.ts +2 -2
- package/dist/menu/menu-dismiss.d.ts.map +1 -1
- package/dist/menu/menu-group-label.d.ts +2 -2
- package/dist/menu/menu-group-label.d.ts.map +1 -1
- package/dist/menu/menu-group.d.ts +2 -2
- package/dist/menu/menu-group.d.ts.map +1 -1
- package/dist/menu/menu-heading.d.ts +2 -2
- package/dist/menu/menu-heading.d.ts.map +1 -1
- package/dist/menu/menu-item-check.d.ts +2 -2
- package/dist/menu/menu-item-check.d.ts.map +1 -1
- package/dist/menu/menu-item-checkbox.d.ts +2 -2
- package/dist/menu/menu-item-checkbox.d.ts.map +1 -1
- package/dist/menu/menu-item-checkbox.js +1 -1
- package/dist/menu/menu-item-checkbox.js.map +1 -1
- package/dist/menu/menu-item-radio.d.ts +2 -2
- package/dist/menu/menu-item-radio.d.ts.map +1 -1
- package/dist/menu/menu-item-radio.js +1 -1
- package/dist/menu/menu-item-radio.js.map +1 -1
- package/dist/menu/menu-item.d.ts +5 -5
- package/dist/menu/menu-item.d.ts.map +1 -1
- package/dist/menu/menu-item.js +8 -4
- package/dist/menu/menu-item.js.map +1 -1
- package/dist/menu/menu-list.d.ts +4 -4
- package/dist/menu/menu-list.d.ts.map +1 -1
- package/dist/menu/menu-list.js +6 -2
- package/dist/menu/menu-list.js.map +1 -1
- package/dist/menu/menu-provider.d.ts +1 -1
- package/dist/menu/menu-separator.d.ts +2 -2
- package/dist/menu/menu-separator.d.ts.map +1 -1
- package/dist/menu/menu-store.d.ts +1 -1
- package/dist/menu/menu.js +1 -1
- package/dist/menu/menu.js.map +1 -1
- package/dist/{menu-store-0CKKmNek.d.ts → menu-store-BpTJdcL8.d.ts} +2 -2
- package/dist/{menu-store-0CKKmNek.d.ts.map → menu-store-BpTJdcL8.d.ts.map} +1 -1
- package/dist/menubar/menubar-context.d.ts +2 -3
- package/dist/menubar/menubar-context.d.ts.map +1 -1
- package/dist/menubar/menubar-context.js +1 -3
- package/dist/menubar/menubar-context.js.map +1 -1
- package/dist/menubar/menubar-provider.d.ts +1 -1
- package/dist/menubar/menubar-store.d.ts +1 -1
- package/dist/menubar/menubar-store.js +2 -2
- package/dist/menubar/menubar-store.js.map +1 -1
- package/dist/menubar/menubar.d.ts +3 -3
- package/dist/menubar/menubar.d.ts.map +1 -1
- package/dist/{menubar-store-3h0eNIbS.d.ts → menubar-store-C553OKBw.d.ts} +3 -3
- package/dist/{menubar-store-3h0eNIbS.d.ts.map → menubar-store-C553OKBw.d.ts.map} +1 -1
- package/dist/popover/popover-anchor.d.ts +1 -1
- package/dist/popover/popover-arrow.d.ts +1 -1
- package/dist/popover/popover-arrow.d.ts.map +1 -1
- package/dist/popover/popover-arrow.js +4 -4
- package/dist/popover/popover-arrow.js.map +1 -1
- package/dist/popover/popover-description.d.ts +1 -1
- package/dist/popover/popover-disclosure-arrow.d.ts +1 -1
- package/dist/popover/popover-disclosure-arrow.d.ts.map +1 -1
- package/dist/popover/popover-disclosure-arrow.js +1 -1
- package/dist/popover/popover-disclosure-arrow.js.map +1 -1
- package/dist/popover/popover-disclosure.d.ts +3 -3
- package/dist/popover/popover-disclosure.d.ts.map +1 -1
- package/dist/popover/popover-disclosure.js +1 -1
- package/dist/popover/popover-disclosure.js.map +1 -1
- package/dist/popover/popover-dismiss.d.ts +1 -1
- package/dist/popover/popover-heading.d.ts +1 -1
- package/dist/popover/popover.d.ts +1 -1
- package/dist/popover/popover.js +2 -2
- package/dist/popover/popover.js.map +1 -1
- package/dist/{popover-CCqiRKqg.d.ts → popover-B9PxE5iP.d.ts} +10 -2
- package/dist/popover-B9PxE5iP.d.ts.map +1 -0
- package/dist/{popover-anchor-PgfeXyzs.d.ts → popover-anchor-W18KUmuM.d.ts} +2 -2
- package/dist/{popover-anchor-PgfeXyzs.d.ts.map → popover-anchor-W18KUmuM.d.ts.map} +1 -1
- package/dist/{popover-description-DU753dah.d.ts → popover-description-DbW4mVBb.d.ts} +3 -3
- package/dist/{popover-description-DU753dah.d.ts.map → popover-description-DbW4mVBb.d.ts.map} +1 -1
- package/dist/{popover-dismiss-DPeI6Zse.d.ts → popover-dismiss-CQFvuLzJ.d.ts} +3 -3
- package/dist/{popover-dismiss-DPeI6Zse.d.ts.map → popover-dismiss-CQFvuLzJ.d.ts.map} +1 -1
- package/dist/{popover-heading-DGsr6D5W.d.ts → popover-heading-DC8rYnwo.d.ts} +3 -3
- package/dist/{popover-heading-DGsr6D5W.d.ts.map → popover-heading-DC8rYnwo.d.ts.map} +1 -1
- package/dist/portal/portal.d.ts +1 -1
- package/dist/{portal-CMBWiayp.d.ts → portal-CKFTfCWH.d.ts} +2 -2
- package/dist/{portal-CMBWiayp.d.ts.map → portal-CKFTfCWH.d.ts.map} +1 -1
- package/dist/radio/radio-group.d.ts +2 -2
- package/dist/radio/radio-group.d.ts.map +1 -1
- package/dist/radio/radio-group.js +1 -1
- package/dist/radio/radio-group.js.map +1 -1
- package/dist/radio/radio.d.ts +2 -2
- package/dist/radio/radio.d.ts.map +1 -1
- package/dist/select/select-arrow.d.ts +1 -1
- package/dist/select/select-arrow.d.ts.map +1 -1
- package/dist/select/select-dismiss.d.ts +2 -2
- package/dist/select/select-dismiss.d.ts.map +1 -1
- package/dist/select/select-group-label.d.ts +1 -1
- package/dist/select/select-group-label.d.ts.map +1 -1
- package/dist/select/select-group.d.ts +1 -1
- package/dist/select/select-group.d.ts.map +1 -1
- package/dist/select/select-heading.d.ts +2 -2
- package/dist/select/select-heading.d.ts.map +1 -1
- package/dist/select/select-item-check.d.ts +1 -1
- package/dist/select/select-item-check.d.ts.map +1 -1
- package/dist/select/select-item.d.ts +3 -3
- package/dist/select/select-item.d.ts.map +1 -1
- package/dist/select/select-item.js +1 -1
- package/dist/select/select-item.js.map +1 -1
- package/dist/select/select-label.d.ts +1 -1
- package/dist/select/select-label.d.ts.map +1 -1
- package/dist/select/select-label.js +1 -1
- package/dist/select/select-label.js.map +1 -1
- package/dist/select/select-list.d.ts +3 -3
- package/dist/select/select-list.d.ts.map +1 -1
- package/dist/select/select-list.js +1 -1
- package/dist/select/select-list.js.map +1 -1
- package/dist/select/select-popover.d.ts +1 -1
- package/dist/select/select-renderer.d.ts +2 -2
- package/dist/select/select-renderer.d.ts.map +1 -1
- package/dist/select/select-row.d.ts +1 -1
- package/dist/select/select-row.d.ts.map +1 -1
- package/dist/select/select-row.js +1 -1
- package/dist/select/select-row.js.map +1 -1
- package/dist/select/select-separator.d.ts +1 -1
- package/dist/select/select-separator.d.ts.map +1 -1
- package/dist/select/select.d.ts +2 -2
- package/dist/select/select.d.ts.map +1 -1
- package/dist/select/select.js +1 -1
- package/dist/select/select.js.map +1 -1
- package/dist/separator/separator.d.ts +1 -1
- package/dist/{separator--ozQfMcK.d.ts → separator-BnvSVwBa.d.ts} +2 -2
- package/dist/{separator--ozQfMcK.d.ts.map → separator-BnvSVwBa.d.ts.map} +1 -1
- package/dist/tab/tab-list.d.ts +2 -2
- package/dist/tab/tab-list.d.ts.map +1 -1
- package/dist/tab/tab-list.js +1 -1
- package/dist/tab/tab-list.js.map +1 -1
- package/dist/tab/tab-panel.d.ts +3 -3
- package/dist/tab/tab-panel.d.ts.map +1 -1
- package/dist/tab/tab-panel.js +2 -3
- package/dist/tab/tab-panel.js.map +1 -1
- package/dist/tab/tab.d.ts +2 -2
- package/dist/tab/tab.d.ts.map +1 -1
- package/dist/tab/tab.js +1 -1
- package/dist/tab/tab.js.map +1 -1
- package/dist/tag/tag-input.d.ts +2 -2
- package/dist/tag/tag-input.d.ts.map +1 -1
- package/dist/tag/tag-input.js +1 -2
- package/dist/tag/tag-input.js.map +1 -1
- package/dist/tag/tag-list-label.d.ts +2 -2
- package/dist/tag/tag-list-label.d.ts.map +1 -1
- package/dist/tag/tag-list-label.js +1 -1
- package/dist/tag/tag-list-label.js.map +1 -1
- package/dist/tag/tag-list.d.ts +2 -2
- package/dist/tag/tag-list.d.ts.map +1 -1
- package/dist/tag/tag-list.js +1 -1
- package/dist/tag/tag-list.js.map +1 -1
- package/dist/tag/tag-remove.d.ts +1 -1
- package/dist/tag/tag-remove.d.ts.map +1 -1
- package/dist/tag/tag-remove.js +1 -2
- package/dist/tag/tag-remove.js.map +1 -1
- package/dist/tag/tag-value.js +1 -1
- package/dist/tag/tag-value.js.map +1 -1
- package/dist/tag/tag-values.js +1 -1
- package/dist/tag/tag-values.js.map +1 -1
- package/dist/tag/tag.d.ts +2 -2
- package/dist/tag/tag.d.ts.map +1 -1
- package/dist/tag/tag.js +1 -1
- package/dist/tag/tag.js.map +1 -1
- package/dist/toolbar/toolbar-container.d.ts +1 -1
- package/dist/toolbar/toolbar-container.d.ts.map +1 -1
- package/dist/toolbar/toolbar-input.d.ts +1 -1
- package/dist/toolbar/toolbar-input.d.ts.map +1 -1
- package/dist/toolbar/toolbar-item.d.ts +2 -2
- package/dist/toolbar/toolbar-item.d.ts.map +1 -1
- package/dist/toolbar/toolbar-separator.d.ts +1 -1
- package/dist/toolbar/toolbar-separator.d.ts.map +1 -1
- package/dist/toolbar/toolbar.d.ts +2 -2
- package/dist/toolbar/toolbar.d.ts.map +1 -1
- package/dist/tooltip/tooltip-anchor.d.ts +1 -1
- package/dist/tooltip/tooltip-anchor.d.ts.map +1 -1
- package/dist/tooltip/tooltip-anchor.js +15 -4
- package/dist/tooltip/tooltip-anchor.js.map +1 -1
- package/dist/tooltip/tooltip-arrow.d.ts +1 -1
- package/dist/tooltip/tooltip-arrow.d.ts.map +1 -1
- package/dist/tooltip/tooltip-arrow.js +1 -1
- package/dist/tooltip/tooltip-arrow.js.map +1 -1
- package/dist/tooltip/tooltip.js +1 -1
- package/dist/tooltip/tooltip.js.map +1 -1
- package/dist/visually-hidden/visually-hidden.d.ts +1 -1
- package/dist/visually-hidden/visually-hidden.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/collection/collection-item-offscreen.tsx +1 -1
- package/src/combobox/combobox.tsx +47 -1
- package/src/composite/composite-container.tsx +2 -2
- package/src/composite/composite-hover.tsx +8 -14
- package/src/composite/composite-item-offscreen.tsx +2 -2
- package/src/composite/composite-item.tsx +2 -2
- package/src/composite/composite-renderer.tsx +2 -2
- package/src/composite/composite-row.tsx +2 -2
- package/src/composite/composite-separator.tsx +2 -2
- package/src/composite/composite-typeahead.tsx +2 -2
- package/src/composite/composite.tsx +3 -3
- package/src/dialog/dialog.tsx +33 -10
- package/src/dialog/utils/disable-accessibility-tree-outside.ts +0 -25
- package/src/dialog/utils/use-hide-on-interact-outside.ts +3 -2
- package/src/focusable/focusable.tsx +53 -10
- package/src/form/form-remove.tsx +14 -10
- package/src/form/form.tsx +3 -1
- package/src/heading/heading.tsx +2 -5
- package/src/hovercard/hovercard-disclosure.tsx +18 -4
- package/src/hovercard/hovercard.tsx +1 -1
- package/src/menu/menu-bar-store.ts +2 -2
- package/src/menu/menu-context.tsx +8 -0
- package/src/menu/menu-item.tsx +18 -1
- package/src/menu/menu-list.tsx +15 -0
- package/src/menubar/menubar-context.tsx +0 -5
- package/src/menubar/menubar-store.ts +2 -2
- package/src/popover/popover-arrow.tsx +3 -3
- package/src/popover/popover.tsx +8 -0
- package/src/tab/tab-panel.tsx +1 -1
- package/src/tag/tag-input.tsx +0 -1
- package/src/tag/tag-remove.tsx +0 -1
- package/src/tooltip/tooltip-anchor.tsx +23 -8
- package/dist/collection-renderer-DsPD9ksD.d.ts.map +0 -1
- package/dist/popover-CCqiRKqg.d.ts.map +0 -1
- package/src/hovercard/utils/__tests__/polygon-test.ts +0 -66
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disclosure-content.js","names":["timeout"],"sources":["../../src/disclosure/disclosure-content.tsx"],"sourcesContent":["import { useStoreState } from \"@ariakit/react-store\";\nimport {\n useId,\n useMergeRefs,\n useSafeLayoutEffect,\n useWrapElement,\n createElement,\n createHook,\n forwardRef,\n} from \"@ariakit/react-utils\";\nimport type { Options, Props } from \"@ariakit/react-utils\";\nimport { invariant, removeUndefinedValues } from \"@ariakit/utils\";\nimport type { ElementType } from \"react\";\nimport { useMemo, useRef, useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { DialogScopedContextProvider } from \"../dialog/dialog-context.tsx\";\nimport { useDisclosureProviderContext } from \"./disclosure-context.tsx\";\nimport type { DisclosureStore } from \"./disclosure-store.ts\";\n\nconst TagName = \"div\" satisfies ElementType;\ntype TagName = typeof TagName;\ntype HTMLType = HTMLElementTagNameMap[TagName];\ntype TransitionState = \"enter\" | \"leave\" | null;\n\nfunction afterTimeout(timeoutMs: number, cb: () => void) {\n const timeoutId = setTimeout(cb, timeoutMs);\n return () => clearTimeout(timeoutId);\n}\n\nfunction afterPaint(cb: () => void) {\n let raf = requestAnimationFrame(() => {\n raf = requestAnimationFrame(cb);\n });\n return () => cancelAnimationFrame(raf);\n}\n\nfunction parseCSSTime(...times: string[]) {\n return times\n .join(\", \")\n .split(\", \")\n .reduce((longestTime, currentTimeString) => {\n const multiplier = currentTimeString.endsWith(\"ms\") ? 1 : 1000;\n const currentTime =\n Number.parseFloat(currentTimeString || \"0s\") * multiplier;\n // When multiple times are specified, we want to use the longest one so we\n // wait until the longest transition has finished.\n if (currentTime > longestTime) return currentTime;\n return longestTime;\n }, 0);\n}\n\nexport function isHidden(\n mounted: boolean,\n hidden?: boolean | null,\n alwaysVisible?: boolean | null,\n) {\n return !alwaysVisible && hidden !== false && (!mounted || !!hidden);\n}\n\n/**\n * Returns props to create a `DislosureContent` component.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx\n * const store = useDisclosureStore();\n * const props = useDisclosureContent({ store });\n * <Disclosure store={store}>Disclosure</Disclosure>\n * <Role {...props}>Content</Role>\n * ```\n */\nexport const useDisclosureContent = createHook<\n TagName,\n DisclosureContentOptions\n>(function useDisclosureContent({ store, alwaysVisible, ...props }) {\n const context = useDisclosureProviderContext();\n store = store || context;\n\n invariant(\n store,\n process.env.NODE_ENV !== \"production\" &&\n \"DisclosureContent must receive a `store` prop or be wrapped in a DisclosureProvider component.\",\n );\n\n const ref = useRef<HTMLType>(null);\n const id = useId(props.id);\n const [transition, setTransition] = useState<TransitionState>(null);\n const open = useStoreState(store, \"open\");\n const mounted = useStoreState(store, \"mounted\");\n const animated = useStoreState(store, \"animated\");\n const contentElement = useStoreState(store, \"contentElement\");\n const otherElement = useStoreState(store.disclosure, \"contentElement\");\n const hasClosedRef = useRef(false);\n\n // This is a workaround to avoid the content element from being reset to null\n // on fast refresh.\n useSafeLayoutEffect(() => {\n if (!ref.current) return;\n store?.setContentElement(ref.current);\n }, [store]);\n\n // When the disclosure content element is rendered, we automatically set the\n // animated state to true. If there's no enter animation, the animated state\n // will be set to false later on.\n useSafeLayoutEffect(() => {\n let previousAnimated: boolean | number | undefined;\n store?.setState(\"animated\", (animated) => {\n previousAnimated = animated;\n return true;\n });\n return () => {\n if (previousAnimated === undefined) return;\n store?.setState(\"animated\", previousAnimated);\n };\n }, [store]);\n\n useSafeLayoutEffect(() => {\n if (!animated) {\n // When animation detection has disabled animations (e.g., no CSS\n // transition was detected on the content element), manage data-enter\n // so wrapper elements using :has([data-enter]) work correctly even\n // when the content element itself has no transitions.\n if (!open) {\n hasClosedRef.current = true;\n setTransition(null);\n } else if (hasClosedRef.current) {\n // On reopen after animation detection disabled animations, restore\n // data-enter so enter styles are re-applied.\n hasClosedRef.current = false;\n setTransition(\"enter\");\n }\n return;\n }\n // When the disclosure content element is rendered in a portal, we need to\n // wait for the portal to be mounted and connected to the DOM before we\n // can start the animation.\n if (!contentElement?.isConnected) {\n setTransition(null);\n return;\n }\n // Double requestAnimationFrame is necessary here to avoid potential bugs\n // when the data attribute is added before the element is fully rendered\n // in the DOM, which wouldn't trigger the animation.\n return afterPaint(() => {\n setTransition(open ? \"enter\" : mounted ? \"leave\" : null);\n });\n }, [animated, contentElement, open, mounted]);\n\n useSafeLayoutEffect(() => {\n if (!store) return;\n if (!animated) return;\n if (!transition) return;\n if (!contentElement) return;\n const stopAnimation = () => store?.setState(\"animating\", false);\n const stopAnimationSync = () => flushSync(stopAnimation);\n // Ignore transition states that don't match the current open state. This\n // may happen because transitions are updated asynchronously using\n // requestAnimationFrame.\n if (transition === \"leave\" && open) return;\n if (transition === \"enter\" && !open) return;\n // When the animated state is a number, the user has manually set the\n // animation timeout, so we just respect it.\n if (typeof animated === \"number\") {\n const timeout = animated;\n return afterTimeout(timeout, stopAnimationSync);\n }\n // We need to parse the CSS transition/animation duration and delay to know\n // when the animation ends. This is safer than relying on the\n // transitionend/animationend events because it's not guaranteed that these\n // events will fire. For example, if the element is removed from the DOM\n // before the animation ends or if the animation wasn't triggered in the\n // first place, the events won't fire. Besides, there may be multiple\n // transitions or animations with different durations and delays, and we\n // need to consider the longest one.\n const {\n transitionDuration,\n animationDuration,\n transitionDelay,\n animationDelay,\n } = getComputedStyle(contentElement);\n // If we're rendering a dialog backdrop, otherElement will be the dialog\n // element itself. We need to consider both the backdrop and the dialog\n // animation/transition durations and delays because the dialog may be\n // animated while the backdrop is not.\n const {\n transitionDuration: transitionDuration2 = \"0\",\n animationDuration: animationDuration2 = \"0\",\n transitionDelay: transitionDelay2 = \"0\",\n animationDelay: animationDelay2 = \"0\",\n } = otherElement ? getComputedStyle(otherElement) : {};\n const delay = parseCSSTime(\n transitionDelay,\n animationDelay,\n transitionDelay2,\n animationDelay2,\n );\n const duration = parseCSSTime(\n transitionDuration,\n animationDuration,\n transitionDuration2,\n animationDuration2,\n );\n const timeout = delay + duration;\n // If the timeout is zero, there's no animation or transition, either\n // because they weren't defined in the CSS or the duration was explicitly\n // set to zero. In this scenario, we can halt the animation right away\n // and, if we're entering, we can set the animated state to false so\n // the element unmounts immediately on close without waiting for a\n // leave animation.\n if (!timeout) {\n if (transition === \"enter\") {\n store.setState(\"animated\", false);\n }\n stopAnimation();\n return;\n }\n // Since setTimeout may be delayed by a few milliseconds, we need to\n // subtract a frame duration from the timeout to make sure the animation is\n // stopped right after it ends, preventing flickering.\n const frameRate = 1000 / 60;\n const maxTimeout = Math.max(timeout - frameRate, 0);\n return afterTimeout(maxTimeout, stopAnimationSync);\n }, [store, animated, contentElement, otherElement, open, transition]);\n\n props = useWrapElement(\n props,\n (element) => (\n <DialogScopedContextProvider value={store}>\n {element}\n </DialogScopedContextProvider>\n ),\n [store],\n );\n\n const hidden = isHidden(mounted, props.hidden, alwaysVisible);\n const styleProp = props.style;\n const style = useMemo(() => {\n if (hidden) {\n return { ...styleProp, display: \"none\" };\n }\n return styleProp;\n }, [hidden, styleProp]);\n\n props = {\n \"data-open\": open || undefined,\n \"data-enter\": transition === \"enter\" || undefined,\n \"data-leave\": transition === \"leave\" || undefined,\n hidden,\n ...props,\n id,\n ref: useMergeRefs(id ? store.setContentElement : null, ref, props.ref),\n style,\n };\n\n return removeUndefinedValues(props);\n});\n\nconst DisclosureContentImpl = forwardRef(function DisclosureContentImpl(\n props: DisclosureContentProps,\n) {\n const htmlProps = useDisclosureContent(props);\n return createElement(TagName, htmlProps);\n});\n\n/**\n * Renders an element that can be shown or hidden by a\n * [`Disclosure`](https://ariakit.com/components/disclosure) component.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx {3}\n * <DisclosureProvider>\n * <Disclosure>Disclosure</Disclosure>\n * <DisclosureContent>Content</DisclosureContent>\n * </DisclosureProvider>\n * ```\n */\nexport const DisclosureContent = forwardRef(function DisclosureContent({\n unmountOnHide,\n ...props\n}: DisclosureContentProps) {\n const context = useDisclosureProviderContext();\n const store = props.store || context;\n const mounted = useStoreState(\n store,\n (state) => !unmountOnHide || state?.mounted,\n );\n if (mounted === false) return null;\n return <DisclosureContentImpl {...props} />;\n});\n\nexport interface DisclosureContentOptions<\n _T extends ElementType = TagName,\n> extends Options {\n /**\n * Object returned by the\n * [`useDisclosureStore`](https://ariakit.com/reference/use-disclosure-store)\n * hook. If not provided, the closest\n * [`DisclosureProvider`](https://ariakit.com/reference/disclosure-provider)\n * component's context will be used.\n */\n store?: DisclosureStore;\n /**\n * Determines whether the content element should remain visible even when the\n * [`open`](https://ariakit.com/reference/disclosure-provider#open) state is\n * `false`. If this prop is set to `true`, the `hidden` prop and the `display:\n * none` style will not be applied, unless explicitly set otherwise.\n *\n * This prop is particularly useful when using third-party animation libraries\n * such as Motion or React Spring, where the element needs to be\n * visible for exit animations to work.\n *\n * Live examples:\n * - [Dialog with\n * Motion](https://ariakit.com/examples/dialog-framer-motion)\n * - [Menu with\n * Motion](https://ariakit.com/examples/menu-framer-motion)\n * - [Tooltip with\n * Motion](https://ariakit.com/examples/tooltip-framer-motion)\n * - [Dialog with details &\n * summary](https://ariakit.com/examples/dialog-details)\n * @default false\n */\n alwaysVisible?: boolean;\n /**\n * When set to `true`, the content element will be unmounted and removed from\n * the DOM when it's hidden.\n *\n * Live examples:\n * - [Navigation Menubar](https://ariakit.com/examples/menubar-navigation)\n * - [Combobox with integrated\n * filter](https://ariakit.com/examples/combobox-filtering-integrated)\n * - [Textarea with inline\n * Combobox](https://ariakit.com/examples/combobox-textarea)\n * - [Standalone Popover](https://ariakit.com/examples/popover-standalone)\n * - [Animated Select](https://ariakit.com/examples/select-animated)\n * - [Multi-Select](https://ariakit.com/examples/select-multiple)\n * @default false\n */\n unmountOnHide?: boolean;\n}\n\nexport type DisclosureContentProps<T extends ElementType = TagName> = Props<\n T,\n DisclosureContentOptions<T>\n>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"disclosure-content.js","names":["timeout"],"sources":["../../src/disclosure/disclosure-content.tsx"],"sourcesContent":["import { useStoreState } from \"@ariakit/react-store\";\nimport {\n useId,\n useMergeRefs,\n useSafeLayoutEffect,\n useWrapElement,\n createElement,\n createHook,\n forwardRef,\n} from \"@ariakit/react-utils\";\nimport type { Options, Props } from \"@ariakit/react-utils\";\nimport { invariant, removeUndefinedValues } from \"@ariakit/utils\";\nimport type { ElementType } from \"react\";\nimport { useMemo, useRef, useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { DialogScopedContextProvider } from \"../dialog/dialog-context.tsx\";\nimport { useDisclosureProviderContext } from \"./disclosure-context.tsx\";\nimport type { DisclosureStore } from \"./disclosure-store.ts\";\n\nconst TagName = \"div\" satisfies ElementType;\ntype TagName = typeof TagName;\ntype HTMLType = HTMLElementTagNameMap[TagName];\ntype TransitionState = \"enter\" | \"leave\" | null;\n\nfunction afterTimeout(timeoutMs: number, cb: () => void) {\n const timeoutId = setTimeout(cb, timeoutMs);\n return () => clearTimeout(timeoutId);\n}\n\nfunction afterPaint(cb: () => void) {\n let raf = requestAnimationFrame(() => {\n raf = requestAnimationFrame(cb);\n });\n return () => cancelAnimationFrame(raf);\n}\n\nfunction parseCSSTime(...times: string[]) {\n return times\n .join(\", \")\n .split(\", \")\n .reduce((longestTime, currentTimeString) => {\n const multiplier = currentTimeString.endsWith(\"ms\") ? 1 : 1000;\n const currentTime =\n Number.parseFloat(currentTimeString || \"0s\") * multiplier;\n // When multiple times are specified, we want to use the longest one so we\n // wait until the longest transition has finished.\n if (currentTime > longestTime) return currentTime;\n return longestTime;\n }, 0);\n}\n\nexport function isHidden(\n mounted: boolean,\n hidden?: boolean | null,\n alwaysVisible?: boolean | null,\n) {\n return !alwaysVisible && hidden !== false && (!mounted || !!hidden);\n}\n\n/**\n * Returns props to create a `DislosureContent` component.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx\n * const store = useDisclosureStore();\n * const props = useDisclosureContent({ store });\n * <Disclosure store={store}>Disclosure</Disclosure>\n * <Role {...props}>Content</Role>\n * ```\n */\nexport const useDisclosureContent = createHook<\n TagName,\n DisclosureContentOptions\n>(function useDisclosureContent({ store, alwaysVisible, ...props }) {\n const context = useDisclosureProviderContext();\n store = store || context;\n\n invariant(\n store,\n process.env.NODE_ENV !== \"production\" &&\n \"DisclosureContent must receive a `store` prop or be wrapped in a DisclosureProvider component.\",\n );\n\n const ref = useRef<HTMLType>(null);\n const id = useId(props.id);\n const [transition, setTransition] = useState<TransitionState>(null);\n const open = useStoreState(store, \"open\");\n const mounted = useStoreState(store, \"mounted\");\n const animated = useStoreState(store, \"animated\");\n const contentElement = useStoreState(store, \"contentElement\");\n const otherElement = useStoreState(store.disclosure, \"contentElement\");\n const hasClosedRef = useRef(false);\n\n // This is a workaround to avoid the content element from being reset to null\n // on fast refresh.\n useSafeLayoutEffect(() => {\n if (!ref.current) return;\n store?.setContentElement(ref.current);\n }, [store]);\n\n // When the disclosure content element is rendered, we automatically set the\n // animated state to true. If there's no enter animation, the animated state\n // will be set to false later on.\n useSafeLayoutEffect(() => {\n let previousAnimated: boolean | number | undefined;\n store?.setState(\"animated\", (animated) => {\n previousAnimated = animated;\n return true;\n });\n return () => {\n if (previousAnimated === undefined) return;\n store?.setState(\"animated\", previousAnimated);\n };\n }, [store]);\n\n useSafeLayoutEffect(() => {\n if (!animated) {\n // When animation detection has disabled animations (e.g., no CSS\n // transition was detected on the content element), manage data-enter\n // so wrapper elements using :has([data-enter]) work correctly even\n // when the content element itself has no transitions.\n if (!open) {\n hasClosedRef.current = true;\n setTransition(null);\n } else if (hasClosedRef.current) {\n // On reopen after animation detection disabled animations, restore\n // data-enter so enter styles are re-applied.\n hasClosedRef.current = false;\n setTransition(\"enter\");\n }\n return;\n }\n // When the disclosure content element is rendered in a portal, we need to\n // wait for the portal to be mounted and connected to the DOM before we\n // can start the animation.\n if (!contentElement?.isConnected) {\n setTransition(null);\n return;\n }\n // Double requestAnimationFrame is necessary here to avoid potential bugs\n // when the data attribute is added before the element is fully rendered\n // in the DOM, which wouldn't trigger the animation.\n return afterPaint(() => {\n setTransition(open ? \"enter\" : mounted ? \"leave\" : null);\n });\n }, [animated, contentElement, open, mounted]);\n\n useSafeLayoutEffect(() => {\n if (!store) return;\n if (!animated) return;\n if (!transition) return;\n if (!contentElement) return;\n const stopAnimation = () => store?.setState(\"animating\", false);\n const stopAnimationSync = () => flushSync(stopAnimation);\n // Ignore transition states that don't match the current open state. This\n // may happen because transitions are updated asynchronously using\n // requestAnimationFrame.\n if (transition === \"leave\" && open) return;\n if (transition === \"enter\" && !open) return;\n // When the animated state is a number, the user has manually set the\n // animation timeout, so we just respect it.\n if (typeof animated === \"number\") {\n const timeout = animated;\n return afterTimeout(timeout, stopAnimationSync);\n }\n // We need to parse the CSS transition/animation duration and delay to know\n // when the animation ends. This is safer than relying on the\n // transitionend/animationend events because it's not guaranteed that these\n // events will fire. For example, if the element is removed from the DOM\n // before the animation ends or if the animation wasn't triggered in the\n // first place, the events won't fire. Besides, there may be multiple\n // transitions or animations with different durations and delays, and we\n // need to consider the longest one.\n const {\n transitionDuration,\n animationDuration,\n transitionDelay,\n animationDelay,\n } = getComputedStyle(contentElement);\n // If we're rendering a dialog backdrop, otherElement will be the dialog\n // element itself. We need to consider both the backdrop and the dialog\n // animation/transition durations and delays because the dialog may be\n // animated while the backdrop is not.\n const {\n transitionDuration: transitionDuration2 = \"0\",\n animationDuration: animationDuration2 = \"0\",\n transitionDelay: transitionDelay2 = \"0\",\n animationDelay: animationDelay2 = \"0\",\n } = otherElement ? getComputedStyle(otherElement) : {};\n const delay = parseCSSTime(\n transitionDelay,\n animationDelay,\n transitionDelay2,\n animationDelay2,\n );\n const duration = parseCSSTime(\n transitionDuration,\n animationDuration,\n transitionDuration2,\n animationDuration2,\n );\n const timeout = delay + duration;\n // If the timeout is zero, there's no animation or transition, either\n // because they weren't defined in the CSS or the duration was explicitly\n // set to zero. In this scenario, we can halt the animation right away\n // and, if we're entering, we can set the animated state to false so\n // the element unmounts immediately on close without waiting for a\n // leave animation.\n if (!timeout) {\n if (transition === \"enter\") {\n store.setState(\"animated\", false);\n }\n stopAnimation();\n return;\n }\n // Since setTimeout may be delayed by a few milliseconds, we need to\n // subtract a frame duration from the timeout to make sure the animation is\n // stopped right after it ends, preventing flickering.\n const frameRate = 1000 / 60;\n const maxTimeout = Math.max(timeout - frameRate, 0);\n return afterTimeout(maxTimeout, stopAnimationSync);\n }, [store, animated, contentElement, otherElement, open, transition]);\n\n props = useWrapElement(\n props,\n (element) => (\n <DialogScopedContextProvider value={store}>\n {element}\n </DialogScopedContextProvider>\n ),\n [store],\n );\n\n const hidden = isHidden(mounted, props.hidden, alwaysVisible);\n const styleProp = props.style;\n const style = useMemo(() => {\n if (hidden) {\n return { ...styleProp, display: \"none\" };\n }\n return styleProp;\n }, [hidden, styleProp]);\n\n props = {\n \"data-open\": open || undefined,\n \"data-enter\": transition === \"enter\" || undefined,\n \"data-leave\": transition === \"leave\" || undefined,\n hidden,\n ...props,\n id,\n ref: useMergeRefs(id ? store.setContentElement : null, ref, props.ref),\n style,\n };\n\n return removeUndefinedValues(props);\n});\n\nconst DisclosureContentImpl = forwardRef(function DisclosureContentImpl(\n props: DisclosureContentProps,\n) {\n const htmlProps = useDisclosureContent(props);\n return createElement(TagName, htmlProps);\n});\n\n/**\n * Renders an element that can be shown or hidden by a\n * [`Disclosure`](https://ariakit.com/components/disclosure) component.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx {3}\n * <DisclosureProvider>\n * <Disclosure>Disclosure</Disclosure>\n * <DisclosureContent>Content</DisclosureContent>\n * </DisclosureProvider>\n * ```\n */\nexport const DisclosureContent = forwardRef(function DisclosureContent({\n unmountOnHide,\n ...props\n}: DisclosureContentProps) {\n const context = useDisclosureProviderContext();\n const store = props.store || context;\n const mounted = useStoreState(\n store,\n (state) => !unmountOnHide || state?.mounted,\n );\n if (mounted === false) return null;\n return <DisclosureContentImpl {...props} />;\n});\n\nexport interface DisclosureContentOptions<\n _T extends ElementType = TagName,\n> extends Options {\n /**\n * Object returned by the\n * [`useDisclosureStore`](https://ariakit.com/reference/use-disclosure-store)\n * hook. If not provided, the closest\n * [`DisclosureProvider`](https://ariakit.com/reference/disclosure-provider)\n * component's context will be used.\n */\n store?: DisclosureStore;\n /**\n * Determines whether the content element should remain visible even when the\n * [`open`](https://ariakit.com/reference/disclosure-provider#open) state is\n * `false`. If this prop is set to `true`, the `hidden` prop and the `display:\n * none` style will not be applied, unless explicitly set otherwise.\n *\n * This prop is particularly useful when using third-party animation libraries\n * such as Motion or React Spring, where the element needs to be\n * visible for exit animations to work.\n *\n * Live examples:\n * - [Dialog with\n * Motion](https://ariakit.com/examples/dialog-framer-motion)\n * - [Menu with\n * Motion](https://ariakit.com/examples/menu-framer-motion)\n * - [Tooltip with\n * Motion](https://ariakit.com/examples/tooltip-framer-motion)\n * - [Dialog with details &\n * summary](https://ariakit.com/examples/dialog-details)\n * @default false\n */\n alwaysVisible?: boolean;\n /**\n * When set to `true`, the content element will be unmounted and removed from\n * the DOM when it's hidden.\n *\n * Live examples:\n * - [Navigation Menubar](https://ariakit.com/examples/menubar-navigation)\n * - [Combobox with integrated\n * filter](https://ariakit.com/examples/combobox-filtering-integrated)\n * - [Textarea with inline\n * Combobox](https://ariakit.com/examples/combobox-textarea)\n * - [Standalone Popover](https://ariakit.com/examples/popover-standalone)\n * - [Animated Select](https://ariakit.com/examples/select-animated)\n * - [Multi-Select](https://ariakit.com/examples/select-multiple)\n * @default false\n */\n unmountOnHide?: boolean;\n}\n\nexport type DisclosureContentProps<T extends ElementType = TagName> = Props<\n T,\n DisclosureContentOptions<T>\n>;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as useDisclosure, n as DisclosureOptions, r as DisclosureProps, t as Disclosure } from "../disclosure-
|
|
1
|
+
import { i as useDisclosure, n as DisclosureOptions, r as DisclosureProps, t as Disclosure } from "../disclosure-C4F4sCVZ.js";
|
|
2
2
|
export { Disclosure, DisclosureOptions, DisclosureProps, useDisclosure };
|
|
@@ -22,7 +22,7 @@ const symbol = Symbol("disclosure");
|
|
|
22
22
|
const useDisclosure = createHook(function useDisclosure({ store, toggleOnClick = true, ...props }) {
|
|
23
23
|
const context = useDisclosureProviderContext();
|
|
24
24
|
store = store || context;
|
|
25
|
-
invariant(store, "Disclosure must receive a `store` prop or be wrapped in a DisclosureProvider component.");
|
|
25
|
+
invariant(store, process.env.NODE_ENV !== "production" && "Disclosure must receive a `store` prop or be wrapped in a DisclosureProvider component.");
|
|
26
26
|
const ref = useRef(null);
|
|
27
27
|
const [expanded, setExpanded] = useState(false);
|
|
28
28
|
const disclosureElement = useStoreState(store, "disclosureElement");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disclosure.js","names":[],"sources":["../../src/disclosure/disclosure.tsx"],"sourcesContent":["import { useStoreState } from \"@ariakit/react-store\";\nimport {\n useBooleanEvent,\n useEvent,\n useMergeRefs,\n useMetadataProps,\n createElement,\n createHook,\n forwardRef,\n} from \"@ariakit/react-utils\";\nimport type { Props } from \"@ariakit/react-utils\";\nimport { invariant } from \"@ariakit/utils\";\nimport type { BooleanOrCallback } from \"@ariakit/utils\";\nimport type { ElementType, MouseEvent } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { ButtonOptions } from \"../button/button.tsx\";\nimport { useButton } from \"../button/button.tsx\";\nimport { useDisclosureProviderContext } from \"./disclosure-context.tsx\";\nimport type { DisclosureStore } from \"./disclosure-store.ts\";\n\nconst TagName = \"button\" satisfies ElementType;\ntype TagName = typeof TagName;\ntype HTMLType = HTMLElementTagNameMap[TagName];\n\nconst symbol = Symbol(\"disclosure\");\n\n/**\n * Returns props to create a `Disclosure` component.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx\n * const store = useDisclosureStore();\n * const props = useDisclosure({ store });\n * <Role {...props}>Disclosure</Role>\n * <DisclosureContent store={store}>Content</DisclosureContent>\n * ```\n */\nexport const useDisclosure = createHook<TagName, DisclosureOptions>(\n function useDisclosure({ store, toggleOnClick = true, ...props }) {\n const context = useDisclosureProviderContext();\n store = store || context;\n\n invariant(\n store,\n process.env.NODE_ENV !== \"production\" &&\n \"Disclosure must receive a `store` prop or be wrapped in a DisclosureProvider component.\",\n );\n\n const ref = useRef<HTMLType>(null);\n const [expanded, setExpanded] = useState(false);\n const disclosureElement = useStoreState(store, \"disclosureElement\");\n const open = useStoreState(store, \"open\");\n\n // Assigns the disclosure element whenever it's undefined or disconnected\n // from the DOM. If the current element is the disclosure element, it will\n // get the `aria-expanded` attribute set to `true` when the disclosure\n // content is open.\n useEffect(() => {\n let isCurrentDisclosure = disclosureElement === ref.current;\n if (!disclosureElement?.isConnected) {\n store?.setDisclosureElement(ref.current);\n isCurrentDisclosure = true;\n }\n setExpanded(open && isCurrentDisclosure);\n }, [disclosureElement, store, open]);\n\n const onClickProp = props.onClick;\n const toggleOnClickProp = useBooleanEvent(toggleOnClick);\n const [isDuplicate, metadataProps] = useMetadataProps(props, symbol, true);\n\n const onClick = useEvent((event: MouseEvent<HTMLType>) => {\n onClickProp?.(event);\n if (event.defaultPrevented) return;\n if (isDuplicate) return;\n if (!toggleOnClickProp(event)) return;\n store?.setDisclosureElement(event.currentTarget);\n store?.toggle();\n });\n\n const contentElement = useStoreState(store, \"contentElement\");\n\n props = {\n \"aria-expanded\": expanded,\n \"aria-controls\": contentElement?.id,\n ...metadataProps,\n ...props,\n ref: useMergeRefs(ref, props.ref),\n onClick,\n };\n\n props = useButton(props);\n\n return props;\n },\n);\n\n/**\n * Renders an element that controls the visibility of a\n * [`DisclosureContent`](https://ariakit.com/reference/disclosure-content)\n * element.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx {2}\n * <DisclosureProvider>\n * <Disclosure>Disclosure</Disclosure>\n * <DisclosureContent>Content</DisclosureContent>\n * </DisclosureProvider>\n * ```\n */\nexport const Disclosure = forwardRef(function Disclosure(\n props: DisclosureProps,\n) {\n const htmlProps = useDisclosure(props);\n return createElement(TagName, htmlProps);\n});\n\nexport interface DisclosureOptions<\n T extends ElementType = TagName,\n> extends ButtonOptions<T> {\n /**\n * Object returned by the\n * [`useDisclosureStore`](https://ariakit.com/reference/use-disclosure-store)\n * hook. If not provided, the closest\n * [`DisclosureProvider`](https://ariakit.com/reference/disclosure-provider)\n * component's context will be used.\n */\n store?: DisclosureStore;\n /**\n * Determines whether\n * [`toggle`](https://ariakit.com/reference/use-disclosure-store#toggle) will\n * be called on click. This is useful if you want to handle the toggle logic\n * yourself.\n *\n * Live examples:\n * - [Navigation Menubar](https://ariakit.com/examples/menubar-navigation)\n * @default true\n */\n toggleOnClick?: BooleanOrCallback<MouseEvent<HTMLElement>>;\n}\n\nexport type DisclosureProps<T extends ElementType = TagName> = Props<\n T,\n DisclosureOptions<T>\n>;\n"],"mappings":";;;;;;;;AAwBA,MAAM,UAAS;;;;;;;;;;;;;MAeX,gBAAgB,WAAA,SAAA,cAA6B,EAAA,OAAA,gBAAA,MAAA,GAAA,SAAA;CAC7C,MAAA,UAAQ,6BAAS;CAEjB,QAAA,
|
|
1
|
+
{"version":3,"file":"disclosure.js","names":[],"sources":["../../src/disclosure/disclosure.tsx"],"sourcesContent":["import { useStoreState } from \"@ariakit/react-store\";\nimport {\n useBooleanEvent,\n useEvent,\n useMergeRefs,\n useMetadataProps,\n createElement,\n createHook,\n forwardRef,\n} from \"@ariakit/react-utils\";\nimport type { Props } from \"@ariakit/react-utils\";\nimport { invariant } from \"@ariakit/utils\";\nimport type { BooleanOrCallback } from \"@ariakit/utils\";\nimport type { ElementType, MouseEvent } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { ButtonOptions } from \"../button/button.tsx\";\nimport { useButton } from \"../button/button.tsx\";\nimport { useDisclosureProviderContext } from \"./disclosure-context.tsx\";\nimport type { DisclosureStore } from \"./disclosure-store.ts\";\n\nconst TagName = \"button\" satisfies ElementType;\ntype TagName = typeof TagName;\ntype HTMLType = HTMLElementTagNameMap[TagName];\n\nconst symbol = Symbol(\"disclosure\");\n\n/**\n * Returns props to create a `Disclosure` component.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx\n * const store = useDisclosureStore();\n * const props = useDisclosure({ store });\n * <Role {...props}>Disclosure</Role>\n * <DisclosureContent store={store}>Content</DisclosureContent>\n * ```\n */\nexport const useDisclosure = createHook<TagName, DisclosureOptions>(\n function useDisclosure({ store, toggleOnClick = true, ...props }) {\n const context = useDisclosureProviderContext();\n store = store || context;\n\n invariant(\n store,\n process.env.NODE_ENV !== \"production\" &&\n \"Disclosure must receive a `store` prop or be wrapped in a DisclosureProvider component.\",\n );\n\n const ref = useRef<HTMLType>(null);\n const [expanded, setExpanded] = useState(false);\n const disclosureElement = useStoreState(store, \"disclosureElement\");\n const open = useStoreState(store, \"open\");\n\n // Assigns the disclosure element whenever it's undefined or disconnected\n // from the DOM. If the current element is the disclosure element, it will\n // get the `aria-expanded` attribute set to `true` when the disclosure\n // content is open.\n useEffect(() => {\n let isCurrentDisclosure = disclosureElement === ref.current;\n if (!disclosureElement?.isConnected) {\n store?.setDisclosureElement(ref.current);\n isCurrentDisclosure = true;\n }\n setExpanded(open && isCurrentDisclosure);\n }, [disclosureElement, store, open]);\n\n const onClickProp = props.onClick;\n const toggleOnClickProp = useBooleanEvent(toggleOnClick);\n const [isDuplicate, metadataProps] = useMetadataProps(props, symbol, true);\n\n const onClick = useEvent((event: MouseEvent<HTMLType>) => {\n onClickProp?.(event);\n if (event.defaultPrevented) return;\n if (isDuplicate) return;\n if (!toggleOnClickProp(event)) return;\n store?.setDisclosureElement(event.currentTarget);\n store?.toggle();\n });\n\n const contentElement = useStoreState(store, \"contentElement\");\n\n props = {\n \"aria-expanded\": expanded,\n \"aria-controls\": contentElement?.id,\n ...metadataProps,\n ...props,\n ref: useMergeRefs(ref, props.ref),\n onClick,\n };\n\n props = useButton(props);\n\n return props;\n },\n);\n\n/**\n * Renders an element that controls the visibility of a\n * [`DisclosureContent`](https://ariakit.com/reference/disclosure-content)\n * element.\n * @see https://ariakit.com/components/disclosure\n * @example\n * ```jsx {2}\n * <DisclosureProvider>\n * <Disclosure>Disclosure</Disclosure>\n * <DisclosureContent>Content</DisclosureContent>\n * </DisclosureProvider>\n * ```\n */\nexport const Disclosure = forwardRef(function Disclosure(\n props: DisclosureProps,\n) {\n const htmlProps = useDisclosure(props);\n return createElement(TagName, htmlProps);\n});\n\nexport interface DisclosureOptions<\n T extends ElementType = TagName,\n> extends ButtonOptions<T> {\n /**\n * Object returned by the\n * [`useDisclosureStore`](https://ariakit.com/reference/use-disclosure-store)\n * hook. If not provided, the closest\n * [`DisclosureProvider`](https://ariakit.com/reference/disclosure-provider)\n * component's context will be used.\n */\n store?: DisclosureStore;\n /**\n * Determines whether\n * [`toggle`](https://ariakit.com/reference/use-disclosure-store#toggle) will\n * be called on click. This is useful if you want to handle the toggle logic\n * yourself.\n *\n * Live examples:\n * - [Navigation Menubar](https://ariakit.com/examples/menubar-navigation)\n * @default true\n */\n toggleOnClick?: BooleanOrCallback<MouseEvent<HTMLElement>>;\n}\n\nexport type DisclosureProps<T extends ElementType = TagName> = Props<\n T,\n DisclosureOptions<T>\n>;\n"],"mappings":";;;;;;;;AAwBA,MAAM,UAAS;;;;;;;;;;;;;MAeX,gBAAgB,WAAA,SAAA,cAA6B,EAAA,OAAA,gBAAA,MAAA,GAAA,SAAA;CAC7C,MAAA,UAAQ,6BAAS;CAEjB,QAAA,SAEE;CAIF,UAAM,OAAM,QAAqB,IAAA,aAAA,gBAAA,yFAAA;CACjC,MAAM,MAAC,OAAU,IAAA;CACjB,MAAM,CAAA,UAAA,eAAoB,SAAc,KAAA;CACxC,MAAM,oBAAO,cAA2B,OAAA,mBAAA;CAMxC,MAAA,OAAA,cAAgB,OAAA,MAAA;iBACV;EACJ,IAAI,sBAAoB,sBAAa,IAAA;MACnC,CAAA,mBAAO,aAAyB;GAChC,OAAA,qBAAsB,IAAA,OAAA;GACxB,sBAAA;EACA;EACF,YAAG,QAAA,mBAAA;IAAC;EAAmB;EAAO;EAAK;CAEnC,CAAA;CACA,MAAM,cAAA,MAAoB;CAC1B,MAAM,oBAAc,gBAAiB,aAAiB;CAEtD,MAAM,CAAA,aAAU,iBAA0C,iBAAA,OAAA,QAAA,IAAA;OACxD,UAAc,UAAK,UAAA;EACnB,cAAU,KAAA;EACV,IAAI,MAAA,kBAAa;EACjB,IAAI,aAAC;EACL,IAAA,CAAA,kBAAO,KAAqB,GAAA;EAC5B,OAAO,qBAAO,MAAA,aAAA;EACf,OAAA,OAAA;CAID,CAAA;SACE;EACA,iBAJqB;EAKrB,iBAAG,cAAA,OAAA,gBAAA,GAAA;EACH,GAAG;EACH,GAAA;EACA,KAAA,aAAA,KAAA,MAAA,GAAA;EACF;CAEA;CAEA,QAAO,UAAA,KAAA;CAEX,OAAA;;;;;;;;;;;;;;;MAmBE,aAAO,WAAc,SADH,WACoB,OAAC;CACxC,OAAA,cAAA,SAAA,cAAA,KAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ButtonOptions } from "./button-
|
|
1
|
+
import { n as ButtonOptions } from "./button-CVWcOgxs.js";
|
|
2
2
|
import { t as DisclosureStore } from "./disclosure-store-BsaBaRKv.js";
|
|
3
3
|
import { Props } from "@ariakit/react-utils";
|
|
4
4
|
import { ElementType, MouseEvent } from "react";
|
|
@@ -32,7 +32,7 @@ declare const useDisclosure: import("@ariakit/react-utils").Hook<"button", Discl
|
|
|
32
32
|
* </DisclosureProvider>
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
declare const Disclosure: (props: DisclosureProps) => import("react").ReactElement<
|
|
35
|
+
declare const Disclosure: (props: DisclosureProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
36
36
|
interface DisclosureOptions<T extends ElementType = TagName> extends ButtonOptions<T> {
|
|
37
37
|
/**
|
|
38
38
|
* Object returned by the
|
|
@@ -57,4 +57,4 @@ interface DisclosureOptions<T extends ElementType = TagName> extends ButtonOptio
|
|
|
57
57
|
type DisclosureProps<T extends ElementType = TagName> = Props<T, DisclosureOptions<T>>;
|
|
58
58
|
//#endregion
|
|
59
59
|
export { useDisclosure as i, DisclosureOptions as n, DisclosureProps as r, Disclosure as t };
|
|
60
|
-
//# sourceMappingURL=disclosure-
|
|
60
|
+
//# sourceMappingURL=disclosure-C4F4sCVZ.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disclosure-
|
|
1
|
+
{"version":3,"file":"disclosure-C4F4sCVZ.d.ts","names":["Props","BooleanOrCallback","ElementType","MouseEvent","ButtonOptions","DisclosureStore","TagName","useDisclosure","DisclosureOptions","Hook","Disclosure","DisclosureProps","props","ReactElement","JSXElementConstructor","T","HTMLElement","store","toggleOnClick"],"sources":["../src/disclosure/disclosure.d.ts"],"mappings":";;;;;;;cAKcM,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFgC;;;;AACxC;AAAA;;;;AACQ;AAY7B;AAd6D,cAcxCC,aAAAA,iCAA8CE,IAAAA,WAAeD,iBAAiB;;;AAAA;AAcnG;;;;;;;;;AAAiJ;cAA5HE,UAAAA,GAAaE,KAAAA,EAAOD,eAAe,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,UAC3GN,iBAAAA,WAA4BN,WAAAA,GAAcI,OAAAA,UAAiBF,aAAAA,CAAcW,CAAAA;EAAxDA;;;;;;;EAQ9BE,KAAAA,GAAQZ,eAAAA;EARgED;;;;;;;;;;EAmBxEc,aAAAA,GAAgBjB,iBAAAA,CAAkBE,UAAAA,CAAWa,WAAAA;AAAAA;AAAAA,KAErCL,eAAAA,WAA0BT,WAAAA,GAAcI,OAAAA,IAAWN,KAAAA,CAAMe,CAAAA,EAAGP,iBAAAA,CAAkBO,CAAAA"}
|
|
@@ -28,7 +28,7 @@ declare const useFocusTrapRegion: import("@ariakit/react-utils").Hook<"div", Foc
|
|
|
28
28
|
* </FocusTrapRegion>
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
|
-
declare const FocusTrapRegion: (props: FocusTrapRegionProps) => import("react").ReactElement<
|
|
31
|
+
declare const FocusTrapRegion: (props: FocusTrapRegionProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
32
32
|
interface FocusTrapRegionOptions<_T extends ElementType = TagName> extends Options {
|
|
33
33
|
/**
|
|
34
34
|
* If true, it will trap the focus in the region.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus-trap-region.d.ts","names":["Options","Props","ElementType","TagName","useFocusTrapRegion","FocusTrapRegionOptions","Hook","FocusTrapRegion","FocusTrapRegionProps","props","ReactElement","JSXElementConstructor","_T","enabled","T"],"sources":["../../src/focus-trap/focus-trap-region.d.ts"],"mappings":";;;;cAEcG,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFY;;;;AACpB;AAAA;;;;AADoB,cAYpBC,kBAAAA,iCAAmDE,IAAAA,QAAYD,sBAAsB;AAA1G;;;;AAA0G;AAe1G;;;;;;;;;AAfA,cAeqBE,eAAAA,GAAkBE,KAAAA,EAAOD,oBAAoB,qBAAqBE,YAAAA
|
|
1
|
+
{"version":3,"file":"focus-trap-region.d.ts","names":["Options","Props","ElementType","TagName","useFocusTrapRegion","FocusTrapRegionOptions","Hook","FocusTrapRegion","FocusTrapRegionProps","props","ReactElement","JSXElementConstructor","_T","enabled","T"],"sources":["../../src/focus-trap/focus-trap-region.d.ts"],"mappings":";;;;cAEcG,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFY;;;;AACpB;AAAA;;;;AADoB,cAYpBC,kBAAAA,iCAAmDE,IAAAA,QAAYD,sBAAsB;AAA1G;;;;AAA0G;AAe1G;;;;;;;;;AAfA,cAeqBE,eAAAA,GAAkBE,KAAAA,EAAOD,oBAAoB,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,UACrHN,sBAAAA,YAAkCH,WAAAA,GAAcC,OAAAA,UAAiBH,OAAAA;EAA3C;;;;EAKnCa,OAAAA;AAAAA;AAAAA,KAEQL,oBAAAA,WAA+BN,WAAAA,GAAcC,OAAAA,IAAWF,KAAAA,CAAMa,CAAAA,EAAGT,sBAAAA,CAAuBS,CAAAA"}
|
|
@@ -23,7 +23,7 @@ declare const useFocusTrap: import("@ariakit/react-utils").Hook<"span", FocusTra
|
|
|
23
23
|
* <FocusTrap onFocus={focusSomethingElse} />
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
|
-
declare const FocusTrap: (props: FocusTrapProps) => import("react").ReactElement<
|
|
26
|
+
declare const FocusTrap: (props: FocusTrapProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
27
27
|
type FocusTrapOptions<T extends ElementType = TagName> = VisuallyHiddenOptions<T>;
|
|
28
28
|
type FocusTrapProps<T extends ElementType = TagName> = Props<T, FocusTrapOptions<T>>;
|
|
29
29
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus-trap.d.ts","names":["Props","ElementType","VisuallyHiddenOptions","TagName","useFocusTrap","FocusTrapOptions","Hook","FocusTrap","FocusTrapProps","props","ReactElement","JSXElementConstructor","T"],"sources":["../../src/focus-trap/focus-trap.d.ts"],"mappings":";;;;;cAGcG,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFuD;;;;AAC/D;AAAA;;;;AAD+D,cAY/DC,YAAAA,iCAA6CE,IAAAA,SAAaD,gBAAgB;AAA/F;;;;AAA+F;AAS/F;;;AATA,cASqBE,SAAAA,GAAYE,KAAAA,EAAOD,cAAc,qBAAqBE,YAAAA
|
|
1
|
+
{"version":3,"file":"focus-trap.d.ts","names":["Props","ElementType","VisuallyHiddenOptions","TagName","useFocusTrap","FocusTrapOptions","Hook","FocusTrap","FocusTrapProps","props","ReactElement","JSXElementConstructor","T"],"sources":["../../src/focus-trap/focus-trap.d.ts"],"mappings":";;;;;cAGcG,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFuD;;;;AAC/D;AAAA;;;;AAD+D,cAY/DC,YAAAA,iCAA6CE,IAAAA,SAAaD,gBAAgB;AAA/F;;;;AAA+F;AAS/F;;;AATA,cASqBE,SAAAA,GAAYE,KAAAA,EAAOD,cAAc,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,KAC9GN,gBAAAA,WAA2BJ,WAAAA,GAAcE,OAAAA,IAAWD,qBAAAA,CAAsBU,CAAAA;AAAAA,KAC1EJ,cAAAA,WAAyBP,WAAAA,GAAcE,OAAAA,IAAWH,KAAAA,CAAMY,CAAAA,EAAGP,gBAAAA,CAAiBO,CAAAA"}
|
|
@@ -26,7 +26,7 @@ declare const useFocusableContainer: import("@ariakit/react-utils").Hook<"div",
|
|
|
26
26
|
* </FocusableContainer>
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
|
-
declare const FocusableContainer: (props: FocusableContainerProps) => import("react").ReactElement<
|
|
29
|
+
declare const FocusableContainer: (props: FocusableContainerProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
30
30
|
interface FocusableContainerOptions<_T extends ElementType = TagName> extends Options {
|
|
31
31
|
/**
|
|
32
32
|
* Determines whether [`Focusable`](https://ariakit.com/reference/focusable)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focusable-container.d.ts","names":["Options","Props","ElementType","TagName","useFocusableContainer","FocusableContainerOptions","Hook","FocusableContainer","FocusableContainerProps","props","ReactElement","JSXElementConstructor","_T","autoFocusOnShow","T"],"sources":["../../src/focusable/focusable-container.d.ts"],"mappings":";;;;cAEcG,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFY;;;;AACpB;AAAA;;;;AADoB,cAYpBC,qBAAAA,iCAAsDE,IAAAA,QAAYD,yBAAyB;AAAhH;;;;AAAgH;AAahH;;;;;;;AAbA,cAaqBE,kBAAAA,GAAqBE,KAAAA,EAAOD,uBAAuB,qBAAqBE,YAAAA
|
|
1
|
+
{"version":3,"file":"focusable-container.d.ts","names":["Options","Props","ElementType","TagName","useFocusableContainer","FocusableContainerOptions","Hook","FocusableContainer","FocusableContainerProps","props","ReactElement","JSXElementConstructor","_T","autoFocusOnShow","T"],"sources":["../../src/focusable/focusable-container.d.ts"],"mappings":";;;;cAEcG,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFY;;;;AACpB;AAAA;;;;AADoB,cAYpBC,qBAAAA,iCAAsDE,IAAAA,QAAYD,yBAAyB;AAAhH;;;;AAAgH;AAahH;;;;;;;AAbA,cAaqBE,kBAAAA,GAAqBE,KAAAA,EAAOD,uBAAuB,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,UAC3HN,yBAAAA,YAAqCH,WAAAA,GAAcC,OAAAA,UAAiBH,OAAAA;EAD4E;AACjK;;;;;;EAQIa,eAAAA;AAAAA;AAAAA,KAEQL,uBAAAA,WAAkCN,WAAAA,GAAcC,OAAAA,IAAWF,KAAAA,CAAMa,CAAAA,EAAGT,yBAAAA,CAA0BS,CAAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as useFocusable, n as FocusableOptions, r as FocusableProps, t as Focusable } from "../focusable-
|
|
1
|
+
import { i as useFocusable, n as FocusableOptions, r as FocusableProps, t as Focusable } from "../focusable-dBZH13-T.js";
|
|
2
2
|
export { Focusable, FocusableOptions, FocusableProps, useFocusable };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { FocusableContext } from "./focusable-context.js";
|
|
3
3
|
import { createElement, createHook, forwardRef, useEvent, useMergeRefs, useMetadataProps, useTagName } from "@ariakit/react-utils";
|
|
4
|
-
import { addGlobalEventListener, disabledFromProps, hasFocus, isFocusEventOutside, isFocusable, isSafari, isSelfTarget, queueBeforeEvent, removeUndefinedValues } from "@ariakit/utils";
|
|
4
|
+
import { addGlobalEventListener, disabledFromProps, hasFocus, isElement, isFocusEventOutside, isFocusable, isSafari, isSelfTarget, queueBeforeEvent, removeUndefinedValues } from "@ariakit/utils";
|
|
5
5
|
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
//#region src/focusable/focusable.tsx
|
|
7
7
|
const TagName = "div";
|
|
@@ -55,6 +55,17 @@ function needsSafariTabIndex(tagName, inputType) {
|
|
|
55
55
|
}
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
|
+
function isNativeSubmitControl(element) {
|
|
59
|
+
if (element.tagName === "BUTTON") {
|
|
60
|
+
const { type } = element;
|
|
61
|
+
return type === "submit";
|
|
62
|
+
}
|
|
63
|
+
if (element.tagName === "INPUT") {
|
|
64
|
+
const { type } = element;
|
|
65
|
+
return type === "submit" || type === "image";
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
58
69
|
function getTabIndex({ focusable, trulyDisabled, nativeTabbable, supportsDisabled, safariTabIndex, tabIndexProp }) {
|
|
59
70
|
if (!focusable) return tabIndexProp;
|
|
60
71
|
if (trulyDisabled) {
|
|
@@ -81,9 +92,7 @@ let hasInstalledGlobalEventListeners = false;
|
|
|
81
92
|
let isKeyboardModality = true;
|
|
82
93
|
function onGlobalMouseDown(event) {
|
|
83
94
|
const target = event.target;
|
|
84
|
-
if (target &&
|
|
85
|
-
if (!target.hasAttribute("data-focus-visible")) isKeyboardModality = false;
|
|
86
|
-
}
|
|
95
|
+
if (isElement(target) && !target.hasAttribute("data-focus-visible")) isKeyboardModality = false;
|
|
87
96
|
}
|
|
88
97
|
function onGlobalKeyDown(event) {
|
|
89
98
|
if (event.metaKey) return;
|
|
@@ -114,13 +123,24 @@ const useFocusable = createHook(function useFocusable({ focusable = true, access
|
|
|
114
123
|
const disabled = focusable && disabledFromProps(props);
|
|
115
124
|
const trulyDisabled = disabled && !accessibleWhenDisabled;
|
|
116
125
|
const [focusVisible, setFocusVisible] = useState(false);
|
|
126
|
+
const focusVisibleRef = useRef(false);
|
|
127
|
+
const nativeSubmitObserverCleanupRef = useRef(null);
|
|
128
|
+
const cleanupFocusVisible = useEvent((element) => {
|
|
129
|
+
nativeSubmitObserverCleanupRef.current?.();
|
|
130
|
+
nativeSubmitObserverCleanupRef.current = null;
|
|
131
|
+
focusVisibleRef.current = false;
|
|
132
|
+
element?.removeAttribute("data-focus-visible");
|
|
133
|
+
});
|
|
117
134
|
useEffect(() => {
|
|
118
135
|
if (!focusable) return;
|
|
119
|
-
if (trulyDisabled
|
|
136
|
+
if (!trulyDisabled) return;
|
|
137
|
+
cleanupFocusVisible(ref.current);
|
|
138
|
+
if (focusVisible) setFocusVisible(false);
|
|
120
139
|
}, [
|
|
121
140
|
focusable,
|
|
122
141
|
trulyDisabled,
|
|
123
|
-
focusVisible
|
|
142
|
+
focusVisible,
|
|
143
|
+
cleanupFocusVisible
|
|
124
144
|
]);
|
|
125
145
|
useEffect(() => {
|
|
126
146
|
if (!focusable) return;
|
|
@@ -129,11 +149,17 @@ const useFocusable = createHook(function useFocusable({ focusable = true, access
|
|
|
129
149
|
if (!element) return;
|
|
130
150
|
if (typeof IntersectionObserver === "undefined") return;
|
|
131
151
|
const observer = new IntersectionObserver(() => {
|
|
132
|
-
if (!isFocusable(element))
|
|
152
|
+
if (!isFocusable(element)) {
|
|
153
|
+
focusVisibleRef.current = false;
|
|
154
|
+
setFocusVisible(false);
|
|
155
|
+
}
|
|
133
156
|
});
|
|
134
157
|
observer.observe(element);
|
|
135
158
|
return () => observer.disconnect();
|
|
136
159
|
}, [focusable, focusVisible]);
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
return () => nativeSubmitObserverCleanupRef.current?.();
|
|
162
|
+
}, []);
|
|
137
163
|
const onKeyPressCapture = useDisableEvent(props.onKeyPressCapture, disabled);
|
|
138
164
|
const onMouseDownCapture = useDisableEvent(props.onMouseDownCapture, disabled);
|
|
139
165
|
const onClickCapture = useDisableEvent(props.onClickCapture, disabled);
|
|
@@ -146,6 +172,20 @@ const useFocusable = createHook(function useFocusable({ focusable = true, access
|
|
|
146
172
|
onFocusVisible?.(event);
|
|
147
173
|
if (event.defaultPrevented) return;
|
|
148
174
|
element.dataset.focusVisible = "true";
|
|
175
|
+
focusVisibleRef.current = true;
|
|
176
|
+
if (isNativeSubmitControl(element)) {
|
|
177
|
+
nativeSubmitObserverCleanupRef.current?.();
|
|
178
|
+
nativeSubmitObserverCleanupRef.current = null;
|
|
179
|
+
if (typeof IntersectionObserver !== "undefined") {
|
|
180
|
+
const observer = new IntersectionObserver(() => {
|
|
181
|
+
if (isFocusable(element)) return;
|
|
182
|
+
cleanupFocusVisible(element);
|
|
183
|
+
});
|
|
184
|
+
observer.observe(element);
|
|
185
|
+
nativeSubmitObserverCleanupRef.current = () => observer.disconnect();
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
149
189
|
setFocusVisible(true);
|
|
150
190
|
};
|
|
151
191
|
const onKeyDownCaptureProp = props.onKeyDownCapture;
|
|
@@ -154,6 +194,7 @@ const useFocusable = createHook(function useFocusable({ focusable = true, access
|
|
|
154
194
|
if (event.defaultPrevented) return;
|
|
155
195
|
if (!focusable) return;
|
|
156
196
|
if (focusVisible) return;
|
|
197
|
+
if (focusVisibleRef.current) return;
|
|
157
198
|
if (event.metaKey) return;
|
|
158
199
|
if (event.altKey) return;
|
|
159
200
|
if (event.ctrlKey) return;
|
|
@@ -181,7 +222,7 @@ const useFocusable = createHook(function useFocusable({ focusable = true, access
|
|
|
181
222
|
onBlurProp?.(event);
|
|
182
223
|
if (!focusable) return;
|
|
183
224
|
if (!isFocusEventOutside(event)) return;
|
|
184
|
-
event.currentTarget
|
|
225
|
+
cleanupFocusVisible(event.currentTarget);
|
|
185
226
|
setFocusVisible(false);
|
|
186
227
|
});
|
|
187
228
|
const autoFocusOnShow = useContext(FocusableContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focusable.js","names":[],"sources":["../../src/focusable/focusable.tsx"],"sourcesContent":["import {\n useEvent,\n useMergeRefs,\n useMetadataProps,\n useTagName,\n createElement,\n createHook,\n forwardRef,\n} from \"@ariakit/react-utils\";\nimport type { Options, Props } from \"@ariakit/react-utils\";\nimport {\n addGlobalEventListener,\n isFocusEventOutside,\n isSelfTarget,\n queueBeforeEvent,\n hasFocus,\n isFocusable,\n disabledFromProps,\n removeUndefinedValues,\n isSafari,\n} from \"@ariakit/utils\";\nimport type { BivariantCallback } from \"@ariakit/utils\";\nimport type {\n ElementType,\n EventHandler,\n FocusEvent,\n KeyboardEvent as ReactKeyboardEvent,\n SyntheticEvent,\n} from \"react\";\nimport { useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { FocusableContext } from \"./focusable-context.tsx\";\n\nconst TagName = \"div\" satisfies ElementType;\ntype TagName = typeof TagName;\ntype HTMLType = HTMLElementTagNameMap[TagName];\n\nconst accessibleWhenDisabledSymbol = Symbol(\"accessibleWhenDisabled\");\n\nconst isSafariBrowser = isSafari();\n\nconst alwaysFocusVisibleInputTypes = [\n \"text\",\n \"search\",\n \"url\",\n \"tel\",\n \"email\",\n \"password\",\n \"number\",\n \"date\",\n \"month\",\n \"week\",\n \"time\",\n \"datetime\",\n \"datetime-local\",\n];\n\nfunction isAlwaysFocusVisible(element: HTMLElement) {\n const { tagName, readOnly, type } = element as HTMLInputElement;\n if (tagName === \"TEXTAREA\" && !readOnly) return true;\n if (tagName === \"SELECT\" && !readOnly) return true;\n if (tagName === \"INPUT\" && !readOnly) {\n return alwaysFocusVisibleInputTypes.includes(type);\n }\n if (element.isContentEditable) return true;\n // Take into account custom Ariakit Select within a form.\n const role = element.getAttribute(\"role\");\n if (role === \"combobox\" && element.dataset.name) {\n return true;\n }\n return false;\n}\n\nfunction isNativeTabbable(tagName?: string) {\n if (!tagName) return true;\n return (\n tagName === \"button\" ||\n tagName === \"summary\" ||\n tagName === \"input\" ||\n tagName === \"select\" ||\n tagName === \"textarea\" ||\n tagName === \"a\"\n );\n}\n\nfunction supportsDisabledAttribute(tagName?: string) {\n if (!tagName) return true;\n return (\n tagName === \"button\" ||\n tagName === \"input\" ||\n tagName === \"select\" ||\n tagName === \"textarea\"\n );\n}\n\ninterface GetTabIndexParams {\n focusable: boolean;\n trulyDisabled: boolean;\n nativeTabbable: boolean;\n supportsDisabled: boolean;\n safariTabIndex: boolean;\n tabIndexProp?: number;\n}\n\nconst buttonInputTypes = [\n \"button\",\n \"color\",\n \"file\",\n \"image\",\n \"reset\",\n \"submit\",\n];\n\nfunction needsSafariTabIndex(tagName?: string, inputType?: string) {\n if (tagName === \"button\") return true;\n if (tagName === \"input\" && inputType) {\n if (inputType === \"checkbox\" || inputType === \"radio\") return true;\n return buttonInputTypes.includes(inputType);\n }\n return false;\n}\n\nfunction getTabIndex({\n focusable,\n trulyDisabled,\n nativeTabbable,\n supportsDisabled,\n safariTabIndex,\n tabIndexProp,\n}: GetTabIndexParams) {\n if (!focusable) return tabIndexProp;\n if (trulyDisabled) {\n if (nativeTabbable && !supportsDisabled) {\n // Anchor, audio and video tags don't support the `disabled` attribute.\n // We must pass tabIndex={-1} so they don't receive focus on tab.\n return -1;\n }\n // Elements that support the `disabled` attribute don't need tabIndex.\n return;\n }\n if (nativeTabbable) {\n // On Safari, buttons and button-like inputs (checkboxes, radios, submit,\n // reset, etc.) require an explicit tabIndex to receive focus on mousedown.\n if (safariTabIndex && tabIndexProp == null) {\n return 0;\n }\n return tabIndexProp;\n }\n // If the element is enabled and is not natively tabbable, we have to\n // fallback tabIndex={0}.\n return tabIndexProp ?? 0;\n}\n\nfunction useDisableEvent(\n onEvent?: EventHandler<SyntheticEvent>,\n disabled?: boolean,\n) {\n return useEvent((event: SyntheticEvent) => {\n onEvent?.(event);\n if (event.defaultPrevented) return;\n if (disabled) {\n event.stopPropagation();\n event.preventDefault();\n }\n });\n}\n\nlet hasInstalledGlobalEventListeners = false;\n\n// isKeyboardModality should be true by default.\nlet isKeyboardModality = true;\n\nfunction onGlobalMouseDown(event: MouseEvent) {\n const target = event.target as HTMLElement | EventTarget | null;\n if (target && \"hasAttribute\" in target) {\n // If the target element is already focus-visible, we keep the keyboard\n // modality.\n if (!target.hasAttribute(\"data-focus-visible\")) {\n isKeyboardModality = false;\n }\n }\n}\n\nfunction onGlobalKeyDown(event: KeyboardEvent) {\n if (event.metaKey) return;\n if (event.ctrlKey) return;\n if (event.altKey) return;\n isKeyboardModality = true;\n}\n\n/**\n * Returns props to create a `Focusable` component.\n * @see https://ariakit.com/components/focusable\n * @example\n * ```jsx\n * const props = useFocusable();\n * <Role {...props}>Focusable</Role>\n * ```\n */\nexport const useFocusable = createHook<TagName, FocusableOptions>(\n function useFocusable({\n focusable = true,\n accessibleWhenDisabled,\n autoFocus,\n onFocusVisible,\n ...props\n }) {\n const ref = useRef<HTMLType>(null);\n const [parentAccessibleWhenDisabled, metadataProps] = useMetadataProps(\n props,\n accessibleWhenDisabledSymbol,\n accessibleWhenDisabled,\n );\n accessibleWhenDisabled ??= parentAccessibleWhenDisabled;\n\n // Add global event listeners to determine whether the user is using a\n // keyboard to navigate the site or not.\n useEffect(() => {\n if (!focusable) return;\n if (hasInstalledGlobalEventListeners) return;\n addGlobalEventListener(\"mousedown\", onGlobalMouseDown, true);\n addGlobalEventListener(\"keydown\", onGlobalKeyDown, true);\n hasInstalledGlobalEventListeners = true;\n }, [focusable]);\n\n const disabled = focusable && disabledFromProps(props);\n const trulyDisabled = disabled && !accessibleWhenDisabled;\n const [focusVisible, setFocusVisible] = useState(false);\n\n // When the focusable element is disabled, it doesn't trigger a blur event\n // so we can't set focusVisible to false there. Instead, we have to do it\n // here by checking the element's disabled attribute.\n useEffect(() => {\n if (!focusable) return;\n if (trulyDisabled && focusVisible) {\n setFocusVisible(false);\n }\n }, [focusable, trulyDisabled, focusVisible]);\n\n // When an element that has focus becomes hidden, it doesn't trigger a blur\n // event so we can't set focusVisible to false there. We observe the element\n // and check if it's still focusable. Otherwise, we set focusVisible to\n // false.\n useEffect(() => {\n if (!focusable) return;\n if (!focusVisible) return;\n const element = ref.current;\n if (!element) return;\n if (typeof IntersectionObserver === \"undefined\") return;\n const observer = new IntersectionObserver(() => {\n if (!isFocusable(element)) {\n setFocusVisible(false);\n }\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [focusable, focusVisible]);\n\n // Disable events when the element is disabled.\n const onKeyPressCapture = useDisableEvent(\n props.onKeyPressCapture,\n disabled,\n );\n const onMouseDownCapture = useDisableEvent(\n props.onMouseDownCapture,\n disabled,\n );\n const onClickCapture = useDisableEvent(props.onClickCapture, disabled);\n\n const handleFocusVisible = (\n event: SyntheticEvent<HTMLType>,\n currentTarget?: HTMLType,\n ) => {\n if (currentTarget) {\n event.currentTarget = currentTarget;\n }\n if (!focusable) return;\n const element = event.currentTarget;\n if (!element) return;\n // Some extensions like 1password dispatches some keydown events on\n // autofill and immediately moves focus to the next field. That's why we\n // need to check if the current element is still focused.\n if (!hasFocus(element)) return;\n onFocusVisible?.(event);\n if (event.defaultPrevented) return;\n // Make sure data-focus-visible is applied visually at the same time as\n // other data attributes like data-active-item. See\n // https://github.com/ariakit/ariakit/issues/4083\n element.dataset.focusVisible = \"true\";\n setFocusVisible(true);\n };\n\n const onKeyDownCaptureProp = props.onKeyDownCapture;\n\n const onKeyDownCapture = useEvent((event: ReactKeyboardEvent<HTMLType>) => {\n onKeyDownCaptureProp?.(event);\n if (event.defaultPrevented) return;\n if (!focusable) return;\n if (focusVisible) return;\n if (event.metaKey) return;\n if (event.altKey) return;\n if (event.ctrlKey) return;\n if (!isSelfTarget(event)) return;\n const element = event.currentTarget;\n const applyFocusVisible = () => handleFocusVisible(event, element);\n queueBeforeEvent(element, \"focusout\", applyFocusVisible);\n });\n\n const onFocusCaptureProp = props.onFocusCapture;\n\n const onFocusCapture = useEvent((event: FocusEvent<HTMLType>) => {\n onFocusCaptureProp?.(event);\n if (event.defaultPrevented) return;\n if (!focusable) return;\n if (!isSelfTarget(event)) {\n setFocusVisible(false);\n return;\n }\n const element = event.currentTarget;\n const applyFocusVisible = () => handleFocusVisible(event, element);\n if (isKeyboardModality || isAlwaysFocusVisible(event.target)) {\n queueBeforeEvent(event.target, \"focusout\", applyFocusVisible);\n } else {\n setFocusVisible(false);\n }\n });\n\n const onBlurProp = props.onBlur;\n\n // Note: Can't use onBlurCapture here otherwise it will not work with\n // CompositeItem's with the virtualFocus state set to true.\n const onBlur = useEvent((event: FocusEvent<HTMLType>) => {\n onBlurProp?.(event);\n if (!focusable) return;\n if (!isFocusEventOutside(event)) return;\n // Since we set the data-focus-visible attribute on the element in the\n // handleFocusVisible function, we remove it directly here. Otherwise, the\n // attribute might not be removed on lower-end devices.\n event.currentTarget.removeAttribute(\"data-focus-visible\");\n setFocusVisible(false);\n });\n\n const autoFocusOnShow = useContext(FocusableContext);\n\n // The native autoFocus prop is problematic in many ways. For example, when\n // an element has the native autofocus attribute, the focus event will be\n // triggered before React effects (even layout effects) and before refs are\n // assigned. This means we won't have access to the element's ref or\n // anything else that's set up by React effects on the onFocus event. So we\n // don't pass the autoFocus prop to the element and instead manually focus\n // the element when it's mounted. The order in which this effect runs also\n // matters. See\n // https://x.com/diegohaz/status/1408180632933388289\n const autoFocusRef = useEvent((element: HTMLElement | null) => {\n if (!focusable) return;\n if (!autoFocus) return;\n if (!element) return;\n if (!autoFocusOnShow) return;\n // We have to queue focus so other effects and refs can be applied first.\n // See select-animated example.\n queueMicrotask(() => {\n if (hasFocus(element)) return;\n if (!isFocusable(element)) return;\n element.focus();\n });\n });\n\n const tagName = useTagName(ref);\n const nativeTabbable = focusable && isNativeTabbable(tagName);\n const supportsDisabled = focusable && supportsDisabledAttribute(tagName);\n\n // On Safari, buttons and button-like inputs don't receive focus on\n // mousedown. We detect this from the DOM element (not props) so it works\n // with render={<input type=\"submit\" />} and custom components.\n const [safariTabIndex, setSafariTabIndex] = useState(false);\n\n if (isSafariBrowser) {\n useEffect(() => {\n if (!focusable) return;\n const element = ref.current;\n if (!element) return;\n const tag = element.tagName.toLowerCase();\n const type = (element as HTMLInputElement).type;\n setSafariTabIndex(needsSafariTabIndex(tag, type));\n }, [focusable]);\n }\n\n const styleProp = props.style;\n const style = useMemo(() => {\n if (trulyDisabled) {\n return { pointerEvents: \"none\" as const, ...styleProp };\n }\n return styleProp;\n }, [trulyDisabled, styleProp]);\n\n props = {\n \"data-focus-visible\": (focusable && focusVisible) || undefined,\n \"data-autofocus\": autoFocus || undefined,\n \"aria-disabled\": disabled || undefined,\n ...props,\n ...metadataProps,\n ref: useMergeRefs(ref, autoFocusRef, props.ref),\n style,\n tabIndex: getTabIndex({\n focusable,\n trulyDisabled,\n nativeTabbable,\n supportsDisabled,\n safariTabIndex,\n tabIndexProp: props.tabIndex,\n }),\n disabled: supportsDisabled && trulyDisabled ? true : undefined,\n // TODO: Test Focusable contentEditable.\n contentEditable: disabled ? undefined : props.contentEditable,\n onKeyPressCapture,\n onClickCapture,\n onMouseDownCapture,\n onKeyDownCapture,\n onFocusCapture,\n onBlur,\n };\n\n return removeUndefinedValues(props);\n },\n);\n\n/**\n * Renders a focusable element. When this element gains keyboard focus, it gets\n * a\n * [`data-focus-visible`](https://ariakit.com/guide/styling#data-focus-visible)\n * attribute and triggers the\n * [`onFocusVisible`](https://ariakit.com/reference/focusable#onfocusvisible)\n * prop.\n *\n * The `Focusable` component supports the\n * [`disabled`](https://ariakit.com/reference/focusable#disabled) prop for all\n * elements, even those not supporting the native `disabled` attribute. Disabled\n * elements using the `Focusable` component may be still accessible via keyboard\n * by using the the\n * [`accessibleWhenDisabled`](https://ariakit.com/reference/focusable#accessiblewhendisabled)\n * prop.\n * @see https://ariakit.com/components/focusable\n * @example\n * ```jsx\n * <Focusable>Focusable</Focusable>\n * ```\n */\nexport const Focusable = forwardRef(function Focusable(props: FocusableProps) {\n const htmlProps = useFocusable(props);\n return createElement(TagName, htmlProps);\n});\n\nexport interface FocusableOptions<\n _T extends ElementType = TagName,\n> extends Options {\n /**\n * Determines if the element is disabled. This sets the `aria-disabled`\n * attribute accordingly, enabling support for all elements, including those\n * that don't support the native `disabled` attribute.\n *\n * This feature can be combined with the\n * [`accessibleWhenDisabled`](https://ariakit.com/reference/focusable#accessiblewhendisabled)\n * prop to make disabled elements still accessible via keyboard.\n *\n * **Note**: For this prop to work, the\n * [`focusable`](https://ariakit.com/reference/command#focusable) prop must be\n * set to `true`, if it's not set by default.\n *\n * Live examples:\n * - [Submenu](https://ariakit.com/examples/menu-nested)\n * - [Combobox with Tabs](https://ariakit.com/examples/combobox-tabs)\n * - [Context Menu](https://ariakit.com/examples/menu-context-menu)\n * @default false\n */\n disabled?: boolean;\n /**\n * Automatically focuses the element upon mounting, similar to the native\n * `autoFocus` prop. This addresses an issue where the element with the native\n * `autoFocus` attribute might receive focus before React effects are\n * executed.\n *\n * The `autoFocus` prop can also be used with\n * [Focusable](https://ariakit.com/components/focusable) elements within a\n * [Dialog](https://ariakit.com/components/dialog) component, establishing the\n * initial focus as the dialog opens.\n *\n * **Note**: For this prop to work, the\n * [`focusable`](https://ariakit.com/reference/command#focusable) prop must be\n * set to `true`, if it's not set by default.\n *\n * Live examples:\n * - [Warning on Dialog\n * hide](https://ariakit.com/examples/dialog-hide-warning)\n * - [Dialog with React\n * Router](https://ariakit.com/examples/dialog-react-router)\n * - [Nested Dialog](https://ariakit.com/examples/dialog-nested)\n * @default false\n */\n autoFocus?: boolean;\n /**\n * Determines if [Focusable](https://ariakit.com/components/focusable)\n * features should be active on non-native focusable elements.\n *\n * **Note**: This prop only turns off the additional features provided by the\n * [`Focusable`](https://ariakit.com/reference/focusable) component.\n * Non-native focusable elements will lose their focusability entirely.\n * However, native focusable elements will retain their inherent focusability,\n * but without added features such as improved\n * [`autoFocus`](https://ariakit.com/reference/focusable#autofocus),\n * [`accessibleWhenDisabled`](https://ariakit.com/reference/focusable#accessiblewhendisabled),\n * [`onFocusVisible`](https://ariakit.com/reference/focusable#onfocusvisible),\n * etc.\n * @default true\n */\n focusable?: boolean;\n /**\n * Indicates whether the element should be focusable even when it is\n * [`disabled`](https://ariakit.com/reference/focusable#disabled).\n *\n * This is important when discoverability is a concern. For example:\n *\n * > A toolbar in an editor contains a set of special smart paste functions\n * that are disabled when the clipboard is empty or when the function is not\n * applicable to the current content of the clipboard. It could be helpful to\n * keep the disabled buttons focusable if the ability to discover their\n * functionality is primarily via their presence on the toolbar.\n *\n * Learn more on [Focusability of disabled\n * controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols).\n *\n * Live examples:\n * - [Combobox with Tabs](https://ariakit.com/examples/combobox-tabs)\n * - [Command Menu with\n * Tabs](https://ariakit.com/examples/dialog-combobox-tab-command-menu)\n */\n accessibleWhenDisabled?: boolean;\n /**\n * Custom event handler invoked when the element gains focus through keyboard\n * interaction or a key press occurs while the element is in focus. This is\n * the programmatic equivalent of the\n * [`data-focus-visible`](https://ariakit.com/guide/styling#data-focus-visible)\n * attribute.\n *\n * **Note**: For this prop to work, the\n * [`focusable`](https://ariakit.com/reference/command#focusable) prop must be\n * set to `true`, if it's not set by default.\n *\n * Live examples:\n * - [Navigation Menubar](https://ariakit.com/examples/menubar-navigation)\n * - [Custom Checkbox](https://ariakit.com/examples/checkbox-custom)\n */\n onFocusVisible?: BivariantCallback<\n (event: SyntheticEvent<HTMLElement>) => void\n >;\n}\n\nexport type FocusableProps<T extends ElementType = TagName> = Props<\n T,\n FocusableOptions<T>\n>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"focusable.js","names":[],"sources":["../../src/focusable/focusable.tsx"],"sourcesContent":["import {\n useEvent,\n useMergeRefs,\n useMetadataProps,\n useTagName,\n createElement,\n createHook,\n forwardRef,\n} from \"@ariakit/react-utils\";\nimport type { Options, Props } from \"@ariakit/react-utils\";\nimport {\n addGlobalEventListener,\n isElement,\n isFocusEventOutside,\n isSelfTarget,\n queueBeforeEvent,\n hasFocus,\n isFocusable,\n disabledFromProps,\n removeUndefinedValues,\n isSafari,\n} from \"@ariakit/utils\";\nimport type { BivariantCallback } from \"@ariakit/utils\";\nimport type {\n ElementType,\n EventHandler,\n FocusEvent,\n KeyboardEvent as ReactKeyboardEvent,\n SyntheticEvent,\n} from \"react\";\nimport { useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { FocusableContext } from \"./focusable-context.tsx\";\n\nconst TagName = \"div\" satisfies ElementType;\ntype TagName = typeof TagName;\ntype HTMLType = HTMLElementTagNameMap[TagName];\n\nconst accessibleWhenDisabledSymbol = Symbol(\"accessibleWhenDisabled\");\n\nconst isSafariBrowser = isSafari();\n\nconst alwaysFocusVisibleInputTypes = [\n \"text\",\n \"search\",\n \"url\",\n \"tel\",\n \"email\",\n \"password\",\n \"number\",\n \"date\",\n \"month\",\n \"week\",\n \"time\",\n \"datetime\",\n \"datetime-local\",\n];\n\nfunction isAlwaysFocusVisible(element: HTMLElement) {\n const { tagName, readOnly, type } = element as HTMLInputElement;\n if (tagName === \"TEXTAREA\" && !readOnly) return true;\n if (tagName === \"SELECT\" && !readOnly) return true;\n if (tagName === \"INPUT\" && !readOnly) {\n return alwaysFocusVisibleInputTypes.includes(type);\n }\n if (element.isContentEditable) return true;\n // Take into account custom Ariakit Select within a form.\n const role = element.getAttribute(\"role\");\n if (role === \"combobox\" && element.dataset.name) {\n return true;\n }\n return false;\n}\n\nfunction isNativeTabbable(tagName?: string) {\n if (!tagName) return true;\n return (\n tagName === \"button\" ||\n tagName === \"summary\" ||\n tagName === \"input\" ||\n tagName === \"select\" ||\n tagName === \"textarea\" ||\n tagName === \"a\"\n );\n}\n\nfunction supportsDisabledAttribute(tagName?: string) {\n if (!tagName) return true;\n return (\n tagName === \"button\" ||\n tagName === \"input\" ||\n tagName === \"select\" ||\n tagName === \"textarea\"\n );\n}\n\ninterface GetTabIndexParams {\n focusable: boolean;\n trulyDisabled: boolean;\n nativeTabbable: boolean;\n supportsDisabled: boolean;\n safariTabIndex: boolean;\n tabIndexProp?: number;\n}\n\nconst buttonInputTypes = [\n \"button\",\n \"color\",\n \"file\",\n \"image\",\n \"reset\",\n \"submit\",\n];\n\nfunction needsSafariTabIndex(tagName?: string, inputType?: string) {\n if (tagName === \"button\") return true;\n if (tagName === \"input\" && inputType) {\n if (inputType === \"checkbox\" || inputType === \"radio\") return true;\n return buttonInputTypes.includes(inputType);\n }\n return false;\n}\n\nfunction isNativeSubmitControl(element: HTMLElement) {\n if (element.tagName === \"BUTTON\") {\n const { type } = element as HTMLButtonElement;\n return type === \"submit\";\n }\n if (element.tagName === \"INPUT\") {\n const { type } = element as HTMLInputElement;\n return type === \"submit\" || type === \"image\";\n }\n return false;\n}\n\nfunction getTabIndex({\n focusable,\n trulyDisabled,\n nativeTabbable,\n supportsDisabled,\n safariTabIndex,\n tabIndexProp,\n}: GetTabIndexParams) {\n if (!focusable) return tabIndexProp;\n if (trulyDisabled) {\n if (nativeTabbable && !supportsDisabled) {\n // Anchor, audio and video tags don't support the `disabled` attribute.\n // We must pass tabIndex={-1} so they don't receive focus on tab.\n return -1;\n }\n // Elements that support the `disabled` attribute don't need tabIndex.\n return;\n }\n if (nativeTabbable) {\n // On Safari, buttons and button-like inputs (checkboxes, radios, submit,\n // reset, etc.) require an explicit tabIndex to receive focus on mousedown.\n if (safariTabIndex && tabIndexProp == null) {\n return 0;\n }\n return tabIndexProp;\n }\n // If the element is enabled and is not natively tabbable, we have to\n // fallback tabIndex={0}.\n return tabIndexProp ?? 0;\n}\n\nfunction useDisableEvent(\n onEvent?: EventHandler<SyntheticEvent>,\n disabled?: boolean,\n) {\n return useEvent((event: SyntheticEvent) => {\n onEvent?.(event);\n if (event.defaultPrevented) return;\n if (disabled) {\n event.stopPropagation();\n event.preventDefault();\n }\n });\n}\n\nlet hasInstalledGlobalEventListeners = false;\n\n// isKeyboardModality should be true by default.\nlet isKeyboardModality = true;\n\nfunction onGlobalMouseDown(event: MouseEvent) {\n const target = event.target;\n // If the target element is already focus-visible, we keep the keyboard\n // modality.\n if (isElement(target) && !target.hasAttribute(\"data-focus-visible\")) {\n isKeyboardModality = false;\n }\n}\n\nfunction onGlobalKeyDown(event: KeyboardEvent) {\n if (event.metaKey) return;\n if (event.ctrlKey) return;\n if (event.altKey) return;\n isKeyboardModality = true;\n}\n\n/**\n * Returns props to create a `Focusable` component.\n * @see https://ariakit.com/components/focusable\n * @example\n * ```jsx\n * const props = useFocusable();\n * <Role {...props}>Focusable</Role>\n * ```\n */\nexport const useFocusable = createHook<TagName, FocusableOptions>(\n function useFocusable({\n focusable = true,\n accessibleWhenDisabled,\n autoFocus,\n onFocusVisible,\n ...props\n }) {\n const ref = useRef<HTMLType>(null);\n const [parentAccessibleWhenDisabled, metadataProps] = useMetadataProps(\n props,\n accessibleWhenDisabledSymbol,\n accessibleWhenDisabled,\n );\n accessibleWhenDisabled ??= parentAccessibleWhenDisabled;\n\n // Add global event listeners to determine whether the user is using a\n // keyboard to navigate the site or not.\n useEffect(() => {\n if (!focusable) return;\n if (hasInstalledGlobalEventListeners) return;\n addGlobalEventListener(\"mousedown\", onGlobalMouseDown, true);\n addGlobalEventListener(\"keydown\", onGlobalKeyDown, true);\n hasInstalledGlobalEventListeners = true;\n }, [focusable]);\n\n const disabled = focusable && disabledFromProps(props);\n const trulyDisabled = disabled && !accessibleWhenDisabled;\n const [focusVisible, setFocusVisible] = useState(false);\n const focusVisibleRef = useRef(false);\n const nativeSubmitObserverCleanupRef = useRef<(() => void) | null>(null);\n const cleanupFocusVisible = useEvent((element: HTMLElement | null) => {\n nativeSubmitObserverCleanupRef.current?.();\n nativeSubmitObserverCleanupRef.current = null;\n focusVisibleRef.current = false;\n element?.removeAttribute(\"data-focus-visible\");\n });\n\n // When the focusable element is disabled, it doesn't trigger a blur event\n // so we can't set focusVisible to false there. Instead, we have to do it\n // here by checking the element's disabled attribute.\n useEffect(() => {\n if (!focusable) return;\n if (!trulyDisabled) return;\n cleanupFocusVisible(ref.current);\n if (focusVisible) {\n setFocusVisible(false);\n }\n }, [focusable, trulyDisabled, focusVisible, cleanupFocusVisible]);\n\n // When an element that has focus becomes hidden, it doesn't trigger a blur\n // event so we can't set focusVisible to false there. We observe the element\n // and check if it's still focusable. Otherwise, we set focusVisible to\n // false.\n useEffect(() => {\n if (!focusable) return;\n if (!focusVisible) return;\n const element = ref.current;\n if (!element) return;\n if (typeof IntersectionObserver === \"undefined\") return;\n const observer = new IntersectionObserver(() => {\n if (!isFocusable(element)) {\n focusVisibleRef.current = false;\n setFocusVisible(false);\n }\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [focusable, focusVisible]);\n\n useEffect(() => {\n return () => nativeSubmitObserverCleanupRef.current?.();\n }, []);\n\n // Disable events when the element is disabled.\n const onKeyPressCapture = useDisableEvent(\n props.onKeyPressCapture,\n disabled,\n );\n const onMouseDownCapture = useDisableEvent(\n props.onMouseDownCapture,\n disabled,\n );\n const onClickCapture = useDisableEvent(props.onClickCapture, disabled);\n\n const handleFocusVisible = (\n event: SyntheticEvent<HTMLType>,\n currentTarget?: HTMLType,\n ) => {\n if (currentTarget) {\n event.currentTarget = currentTarget;\n }\n if (!focusable) return;\n const element = event.currentTarget;\n if (!element) return;\n // Some extensions like 1password dispatches some keydown events on\n // autofill and immediately moves focus to the next field. That's why we\n // need to check if the current element is still focused.\n if (!hasFocus(element)) return;\n onFocusVisible?.(event);\n if (event.defaultPrevented) return;\n // Make sure data-focus-visible is applied visually at the same time as\n // other data attributes like data-active-item. See\n // https://github.com/ariakit/ariakit/issues/4083\n element.dataset.focusVisible = \"true\";\n focusVisibleRef.current = true;\n // React 19's useFormStatus may lose the pending state when local\n // component state changes while a native submit control is pending.\n if (isNativeSubmitControl(element)) {\n nativeSubmitObserverCleanupRef.current?.();\n nativeSubmitObserverCleanupRef.current = null;\n if (typeof IntersectionObserver !== \"undefined\") {\n const observer = new IntersectionObserver(() => {\n if (isFocusable(element)) return;\n cleanupFocusVisible(element);\n });\n observer.observe(element);\n nativeSubmitObserverCleanupRef.current = () => observer.disconnect();\n }\n return;\n }\n setFocusVisible(true);\n };\n\n const onKeyDownCaptureProp = props.onKeyDownCapture;\n\n const onKeyDownCapture = useEvent((event: ReactKeyboardEvent<HTMLType>) => {\n onKeyDownCaptureProp?.(event);\n if (event.defaultPrevented) return;\n if (!focusable) return;\n if (focusVisible) return;\n if (focusVisibleRef.current) return;\n if (event.metaKey) return;\n if (event.altKey) return;\n if (event.ctrlKey) return;\n if (!isSelfTarget(event)) return;\n const element = event.currentTarget;\n const applyFocusVisible = () => handleFocusVisible(event, element);\n queueBeforeEvent(element, \"focusout\", applyFocusVisible);\n });\n\n const onFocusCaptureProp = props.onFocusCapture;\n\n const onFocusCapture = useEvent((event: FocusEvent<HTMLType>) => {\n onFocusCaptureProp?.(event);\n if (event.defaultPrevented) return;\n if (!focusable) return;\n if (!isSelfTarget(event)) {\n setFocusVisible(false);\n return;\n }\n const element = event.currentTarget;\n const applyFocusVisible = () => handleFocusVisible(event, element);\n if (isKeyboardModality || isAlwaysFocusVisible(event.target)) {\n queueBeforeEvent(event.target, \"focusout\", applyFocusVisible);\n } else {\n setFocusVisible(false);\n }\n });\n\n const onBlurProp = props.onBlur;\n\n // Note: Can't use onBlurCapture here otherwise it will not work with\n // CompositeItem's with the virtualFocus state set to true.\n const onBlur = useEvent((event: FocusEvent<HTMLType>) => {\n onBlurProp?.(event);\n if (!focusable) return;\n if (!isFocusEventOutside(event)) return;\n // Since we set the data-focus-visible attribute on the element in the\n // handleFocusVisible function, we remove it directly here. Otherwise, the\n // attribute might not be removed on lower-end devices.\n cleanupFocusVisible(event.currentTarget);\n setFocusVisible(false);\n });\n\n const autoFocusOnShow = useContext(FocusableContext);\n\n // The native autoFocus prop is problematic in many ways. For example, when\n // an element has the native autofocus attribute, the focus event will be\n // triggered before React effects (even layout effects) and before refs are\n // assigned. This means we won't have access to the element's ref or\n // anything else that's set up by React effects on the onFocus event. So we\n // don't pass the autoFocus prop to the element and instead manually focus\n // the element when it's mounted. The order in which this effect runs also\n // matters. See\n // https://x.com/diegohaz/status/1408180632933388289\n const autoFocusRef = useEvent((element: HTMLElement | null) => {\n if (!focusable) return;\n if (!autoFocus) return;\n if (!element) return;\n if (!autoFocusOnShow) return;\n // We have to queue focus so other effects and refs can be applied first.\n // See select-animated example.\n queueMicrotask(() => {\n if (hasFocus(element)) return;\n if (!isFocusable(element)) return;\n element.focus();\n });\n });\n\n const tagName = useTagName(ref);\n const nativeTabbable = focusable && isNativeTabbable(tagName);\n const supportsDisabled = focusable && supportsDisabledAttribute(tagName);\n\n // On Safari, buttons and button-like inputs don't receive focus on\n // mousedown. We detect this from the DOM element (not props) so it works\n // with render={<input type=\"submit\" />} and custom components.\n const [safariTabIndex, setSafariTabIndex] = useState(false);\n\n if (isSafariBrowser) {\n useEffect(() => {\n if (!focusable) return;\n const element = ref.current;\n if (!element) return;\n const tag = element.tagName.toLowerCase();\n const type = (element as HTMLInputElement).type;\n setSafariTabIndex(needsSafariTabIndex(tag, type));\n }, [focusable]);\n }\n\n const styleProp = props.style;\n const style = useMemo(() => {\n if (trulyDisabled) {\n return { pointerEvents: \"none\" as const, ...styleProp };\n }\n return styleProp;\n }, [trulyDisabled, styleProp]);\n\n props = {\n \"data-focus-visible\": (focusable && focusVisible) || undefined,\n \"data-autofocus\": autoFocus || undefined,\n \"aria-disabled\": disabled || undefined,\n ...props,\n ...metadataProps,\n ref: useMergeRefs(ref, autoFocusRef, props.ref),\n style,\n tabIndex: getTabIndex({\n focusable,\n trulyDisabled,\n nativeTabbable,\n supportsDisabled,\n safariTabIndex,\n tabIndexProp: props.tabIndex,\n }),\n disabled: supportsDisabled && trulyDisabled ? true : undefined,\n // TODO: Test Focusable contentEditable.\n contentEditable: disabled ? undefined : props.contentEditable,\n onKeyPressCapture,\n onClickCapture,\n onMouseDownCapture,\n onKeyDownCapture,\n onFocusCapture,\n onBlur,\n };\n\n return removeUndefinedValues(props);\n },\n);\n\n/**\n * Renders a focusable element. When this element gains keyboard focus, it gets\n * a\n * [`data-focus-visible`](https://ariakit.com/guide/styling#data-focus-visible)\n * attribute and triggers the\n * [`onFocusVisible`](https://ariakit.com/reference/focusable#onfocusvisible)\n * prop.\n *\n * The `Focusable` component supports the\n * [`disabled`](https://ariakit.com/reference/focusable#disabled) prop for all\n * elements, even those not supporting the native `disabled` attribute. Disabled\n * elements using the `Focusable` component may be still accessible via keyboard\n * by using the the\n * [`accessibleWhenDisabled`](https://ariakit.com/reference/focusable#accessiblewhendisabled)\n * prop.\n * @see https://ariakit.com/components/focusable\n * @example\n * ```jsx\n * <Focusable>Focusable</Focusable>\n * ```\n */\nexport const Focusable = forwardRef(function Focusable(props: FocusableProps) {\n const htmlProps = useFocusable(props);\n return createElement(TagName, htmlProps);\n});\n\nexport interface FocusableOptions<\n _T extends ElementType = TagName,\n> extends Options {\n /**\n * Determines if the element is disabled. This sets the `aria-disabled`\n * attribute accordingly, enabling support for all elements, including those\n * that don't support the native `disabled` attribute.\n *\n * This feature can be combined with the\n * [`accessibleWhenDisabled`](https://ariakit.com/reference/focusable#accessiblewhendisabled)\n * prop to make disabled elements still accessible via keyboard.\n *\n * **Note**: For this prop to work, the\n * [`focusable`](https://ariakit.com/reference/command#focusable) prop must be\n * set to `true`, if it's not set by default.\n *\n * Live examples:\n * - [Submenu](https://ariakit.com/examples/menu-nested)\n * - [Combobox with Tabs](https://ariakit.com/examples/combobox-tabs)\n * - [Context Menu](https://ariakit.com/examples/menu-context-menu)\n * @default false\n */\n disabled?: boolean;\n /**\n * Automatically focuses the element upon mounting, similar to the native\n * `autoFocus` prop. This addresses an issue where the element with the native\n * `autoFocus` attribute might receive focus before React effects are\n * executed.\n *\n * The `autoFocus` prop can also be used with\n * [Focusable](https://ariakit.com/components/focusable) elements within a\n * [Dialog](https://ariakit.com/components/dialog) component, establishing the\n * initial focus as the dialog opens.\n *\n * **Note**: For this prop to work, the\n * [`focusable`](https://ariakit.com/reference/command#focusable) prop must be\n * set to `true`, if it's not set by default.\n *\n * Live examples:\n * - [Warning on Dialog\n * hide](https://ariakit.com/examples/dialog-hide-warning)\n * - [Dialog with React\n * Router](https://ariakit.com/examples/dialog-react-router)\n * - [Nested Dialog](https://ariakit.com/examples/dialog-nested)\n * @default false\n */\n autoFocus?: boolean;\n /**\n * Determines if [Focusable](https://ariakit.com/components/focusable)\n * features should be active on non-native focusable elements.\n *\n * **Note**: This prop only turns off the additional features provided by the\n * [`Focusable`](https://ariakit.com/reference/focusable) component.\n * Non-native focusable elements will lose their focusability entirely.\n * However, native focusable elements will retain their inherent focusability,\n * but without added features such as improved\n * [`autoFocus`](https://ariakit.com/reference/focusable#autofocus),\n * [`accessibleWhenDisabled`](https://ariakit.com/reference/focusable#accessiblewhendisabled),\n * [`onFocusVisible`](https://ariakit.com/reference/focusable#onfocusvisible),\n * etc.\n * @default true\n */\n focusable?: boolean;\n /**\n * Indicates whether the element should be focusable even when it is\n * [`disabled`](https://ariakit.com/reference/focusable#disabled).\n *\n * This is important when discoverability is a concern. For example:\n *\n * > A toolbar in an editor contains a set of special smart paste functions\n * that are disabled when the clipboard is empty or when the function is not\n * applicable to the current content of the clipboard. It could be helpful to\n * keep the disabled buttons focusable if the ability to discover their\n * functionality is primarily via their presence on the toolbar.\n *\n * Learn more on [Focusability of disabled\n * controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols).\n *\n * Live examples:\n * - [Combobox with Tabs](https://ariakit.com/examples/combobox-tabs)\n * - [Command Menu with\n * Tabs](https://ariakit.com/examples/dialog-combobox-tab-command-menu)\n */\n accessibleWhenDisabled?: boolean;\n /**\n * Custom event handler invoked when the element gains focus through keyboard\n * interaction or a key press occurs while the element is in focus. This is\n * the programmatic equivalent of the\n * [`data-focus-visible`](https://ariakit.com/guide/styling#data-focus-visible)\n * attribute.\n *\n * **Note**: For this prop to work, the\n * [`focusable`](https://ariakit.com/reference/command#focusable) prop must be\n * set to `true`, if it's not set by default.\n *\n * Live examples:\n * - [Navigation Menubar](https://ariakit.com/examples/menubar-navigation)\n * - [Custom Checkbox](https://ariakit.com/examples/checkbox-custom)\n */\n onFocusVisible?: BivariantCallback<\n (event: SyntheticEvent<HTMLElement>) => void\n >;\n}\n\nexport type FocusableProps<T extends ElementType = TagName> = Props<\n T,\n FocusableOptions<T>\n>;\n"],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@ declare const useFocusable: import("@ariakit/react-utils").Hook<"div", Focusable
|
|
|
36
36
|
* <Focusable>Focusable</Focusable>
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
|
-
declare const Focusable: (props: FocusableProps) => import("react").ReactElement<
|
|
39
|
+
declare const Focusable: (props: FocusableProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
40
40
|
interface FocusableOptions<_T extends ElementType = TagName> extends Options {
|
|
41
41
|
/**
|
|
42
42
|
* Determines if the element is disabled. This sets the `aria-disabled`
|
|
@@ -139,4 +139,4 @@ interface FocusableOptions<_T extends ElementType = TagName> extends Options {
|
|
|
139
139
|
type FocusableProps<T extends ElementType = TagName> = Props<T, FocusableOptions<T>>;
|
|
140
140
|
//#endregion
|
|
141
141
|
export { useFocusable as i, FocusableOptions as n, FocusableProps as r, Focusable as t };
|
|
142
|
-
//# sourceMappingURL=focusable-
|
|
142
|
+
//# sourceMappingURL=focusable-dBZH13-T.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focusable-
|
|
1
|
+
{"version":3,"file":"focusable-dBZH13-T.d.ts","names":["Options","Props","BivariantCallback","ElementType","SyntheticEvent","TagName","useFocusable","FocusableOptions","Hook","Focusable","FocusableProps","props","ReactElement","JSXElementConstructor","_T","HTMLElement","disabled","autoFocus","focusable","accessibleWhenDisabled","onFocusVisible","event","T"],"sources":["../src/focusable/focusable.d.ts"],"mappings":";;;;;cAGcK,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAF4B;;;;AACpC;AAAA;;;;AADoC,cAYpCC,YAAAA,iCAA6CE,IAAAA,QAAYD,gBAAgB;AAA9F;;;;AAA8F;AAsB9F;;;;;;;;;AAA+I;AAC/I;;;;;;AAvBA,cAsBqBE,SAAAA,GAAYE,KAAAA,EAAOD,cAAc,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,UACzGN,gBAAAA,YAA4BJ,WAAAA,GAAcE,OAAAA,UAAiBL,OAAAA;EAAAA;;;;;;;;;;;;;;;;;AAiGF;AAE1E;EA/EIgB,QAAAA;EA+EsBM;;;;;;;;;;;;;;;;;AAA+D;;;;;;EAvDrFL,SAAAA;;;;;;;;;;;;;;;;EAgBAC,SAAAA;;;;;;;;;;;;;;;;;;;;;EAqBAC,sBAAAA;;;;;;;;;;;;;;;;EAgBAC,cAAAA,GAAiBlB,iBAAAA,EAAmBmB,KAAAA,EAAOjB,cAAAA,CAAeW,WAAAA;AAAAA;AAAAA,KAElDL,cAAAA,WAAyBP,WAAAA,GAAcE,OAAAA,IAAWJ,KAAAA,CAAMqB,CAAAA,EAAGf,gBAAAA,CAAiBe,CAAAA"}
|
|
@@ -42,7 +42,7 @@ declare const useFormCheckbox: import("@ariakit/react-utils").Hook<"input", Form
|
|
|
42
42
|
* </Form>
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
|
-
declare const FormCheckbox: (props: FormCheckboxProps) => import("react").ReactElement<
|
|
45
|
+
declare const FormCheckbox: (props: FormCheckboxProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
46
46
|
interface FormCheckboxOptions<T extends ElementType = TagName> extends FormControlOptions<T>, Omit<CheckboxOptions<T>, "store" | "name"> {}
|
|
47
47
|
type FormCheckboxProps<T extends ElementType = TagName> = Props<T, FormCheckboxOptions<T>>;
|
|
48
48
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-checkbox.d.ts","names":["Props","ElementType","CheckboxOptions","FormControlOptions","TagName","useFormCheckbox","FormCheckboxOptions","Hook","FormCheckbox","FormCheckboxProps","props","ReactElement","JSXElementConstructor","T","Omit"],"sources":["../../src/form/form-checkbox.d.ts"],"mappings":";;;;;;cAIcI,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFgC;;;;AACxC;AAAA;;;;AACQ;AAgB7B;;;;AAAsG;AAlBzC,cAkBxCC,eAAAA,iCAAgDE,IAAAA,UAAcD,mBAAmB;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"form-checkbox.d.ts","names":["Props","ElementType","CheckboxOptions","FormControlOptions","TagName","useFormCheckbox","FormCheckboxOptions","Hook","FormCheckbox","FormCheckboxProps","props","ReactElement","JSXElementConstructor","T","Omit"],"sources":["../../src/form/form-checkbox.d.ts"],"mappings":";;;;;;cAIcI,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFgC;;;;AACxC;AAAA;;;;AACQ;AAgB7B;;;;AAAsG;AAlBzC,cAkBxCC,eAAAA,iCAAgDE,IAAAA,UAAcD,mBAAmB;;;;;;;;;AAqB+C;AACrJ;;;;;;;;;;;cADqBE,YAAAA,GAAeE,KAAAA,EAAOD,iBAAiB,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,UAC/GN,mBAAAA,WAA8BL,WAAAA,GAAcG,OAAAA,UAAiBD,kBAAAA,CAAmBU,CAAAA,GAAIC,IAAAA,CAAKZ,eAAAA,CAAgBW,CAAAA;AAAAA,KAE9GJ,iBAAAA,WAA4BR,WAAAA,GAAcG,OAAAA,IAAWJ,KAAAA,CAAMa,CAAAA,EAAGP,mBAAAA,CAAoBO,CAAAA"}
|
|
@@ -25,7 +25,7 @@ const TagName = "input";
|
|
|
25
25
|
const useFormCheckbox = createHook(function useFormCheckbox({ store, name: nameProp, value, checked, defaultChecked, ...props }) {
|
|
26
26
|
const context = useFormContext();
|
|
27
27
|
store = store || context;
|
|
28
|
-
invariant(store, "FormCheckbox must be wrapped in a Form component.");
|
|
28
|
+
invariant(store, process.env.NODE_ENV !== "production" && "FormCheckbox must be wrapped in a Form component.");
|
|
29
29
|
const name = String(nameProp);
|
|
30
30
|
props = useCheckbox({
|
|
31
31
|
store: useCheckboxStore({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-checkbox.js","names":[],"sources":["../../src/form/form-checkbox.tsx"],"sourcesContent":["import {\n createElement,\n createHook,\n forwardRef,\n memo,\n} from \"@ariakit/react-utils\";\nimport type { Props } from \"@ariakit/react-utils\";\nimport { invariant } from \"@ariakit/utils\";\nimport type { ElementType } from \"react\";\nimport { useCheckboxStore } from \"../checkbox/checkbox-store.ts\";\nimport type { CheckboxOptions } from \"../checkbox/checkbox.tsx\";\nimport { useCheckbox } from \"../checkbox/checkbox.tsx\";\nimport { useFormContext } from \"./form-context.tsx\";\nimport type { FormControlOptions } from \"./form-control.tsx\";\nimport { useFormControl } from \"./form-control.tsx\";\n\nconst TagName = \"input\" satisfies ElementType;\ntype TagName = typeof TagName;\n\n/**\n * Returns props to create a `FormCheckbox` component.\n * @see https://ariakit.com/components/form\n * @example\n * ```jsx\n * const store = useFormStore({ defaultValues: { acceptTerms: false } });\n * const props = useFormCheckbox({ store, name: store.names.acceptTerms });\n * <Form store={store}>\n * <label>\n * <Role {...props} />\n * Accept terms\n * </label>\n * </Form>\n * ```\n */\nexport const useFormCheckbox = createHook<TagName, FormCheckboxOptions>(\n function useFormCheckbox({\n store,\n name: nameProp,\n value,\n checked,\n defaultChecked,\n ...props\n }) {\n const context = useFormContext();\n store = store || context;\n\n invariant(\n store,\n process.env.NODE_ENV !== \"production\" &&\n \"FormCheckbox must be wrapped in a Form component.\",\n );\n\n const name = String(nameProp);\n\n const checkboxStore = useCheckboxStore({\n value: store.useValue(name),\n setValue: (value) => store?.setValue(name, value),\n });\n\n props = useCheckbox({ store: checkboxStore, value, checked, ...props });\n\n props = useFormControl({\n store,\n name,\n \"aria-labelledby\": undefined,\n ...props,\n });\n\n return props;\n },\n);\n\n/**\n * Renders a checkbox input as a form control, representing a boolean, string,\n * number, or array value.\n * @see https://ariakit.com/components/form\n * @example\n * ```jsx {9}\n * const form = useFormStore({\n * defaultValues: {\n * acceptTerms: false,\n * },\n * });\n *\n * <Form store={form}>\n * <label>\n * <FormCheckbox name={form.names.acceptTerms} />\n * Accept terms\n * </label>\n * </Form>\n * ```\n */\nexport const FormCheckbox = memo(\n forwardRef(function FormCheckbox(props: FormCheckboxProps) {\n const htmlProps = useFormCheckbox(props);\n return createElement(TagName, htmlProps);\n }),\n);\n\nexport interface FormCheckboxOptions<T extends ElementType = TagName>\n extends FormControlOptions<T>, Omit<CheckboxOptions<T>, \"store\" | \"name\"> {}\n\nexport type FormCheckboxProps<T extends ElementType = TagName> = Props<\n T,\n FormCheckboxOptions<T>\n>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;MA2CI,kBAAgB,WAAe,SAAA,gBAAA,EAAA,OAAA,MAAA,UAAA,OAAA,SAAA,gBAAA,GAAA,SAAA;CAC/B,MAAA,UAAQ,eAAS;CAEjB,QAAA,
|
|
1
|
+
{"version":3,"file":"form-checkbox.js","names":[],"sources":["../../src/form/form-checkbox.tsx"],"sourcesContent":["import {\n createElement,\n createHook,\n forwardRef,\n memo,\n} from \"@ariakit/react-utils\";\nimport type { Props } from \"@ariakit/react-utils\";\nimport { invariant } from \"@ariakit/utils\";\nimport type { ElementType } from \"react\";\nimport { useCheckboxStore } from \"../checkbox/checkbox-store.ts\";\nimport type { CheckboxOptions } from \"../checkbox/checkbox.tsx\";\nimport { useCheckbox } from \"../checkbox/checkbox.tsx\";\nimport { useFormContext } from \"./form-context.tsx\";\nimport type { FormControlOptions } from \"./form-control.tsx\";\nimport { useFormControl } from \"./form-control.tsx\";\n\nconst TagName = \"input\" satisfies ElementType;\ntype TagName = typeof TagName;\n\n/**\n * Returns props to create a `FormCheckbox` component.\n * @see https://ariakit.com/components/form\n * @example\n * ```jsx\n * const store = useFormStore({ defaultValues: { acceptTerms: false } });\n * const props = useFormCheckbox({ store, name: store.names.acceptTerms });\n * <Form store={store}>\n * <label>\n * <Role {...props} />\n * Accept terms\n * </label>\n * </Form>\n * ```\n */\nexport const useFormCheckbox = createHook<TagName, FormCheckboxOptions>(\n function useFormCheckbox({\n store,\n name: nameProp,\n value,\n checked,\n defaultChecked,\n ...props\n }) {\n const context = useFormContext();\n store = store || context;\n\n invariant(\n store,\n process.env.NODE_ENV !== \"production\" &&\n \"FormCheckbox must be wrapped in a Form component.\",\n );\n\n const name = String(nameProp);\n\n const checkboxStore = useCheckboxStore({\n value: store.useValue(name),\n setValue: (value) => store?.setValue(name, value),\n });\n\n props = useCheckbox({ store: checkboxStore, value, checked, ...props });\n\n props = useFormControl({\n store,\n name,\n \"aria-labelledby\": undefined,\n ...props,\n });\n\n return props;\n },\n);\n\n/**\n * Renders a checkbox input as a form control, representing a boolean, string,\n * number, or array value.\n * @see https://ariakit.com/components/form\n * @example\n * ```jsx {9}\n * const form = useFormStore({\n * defaultValues: {\n * acceptTerms: false,\n * },\n * });\n *\n * <Form store={form}>\n * <label>\n * <FormCheckbox name={form.names.acceptTerms} />\n * Accept terms\n * </label>\n * </Form>\n * ```\n */\nexport const FormCheckbox = memo(\n forwardRef(function FormCheckbox(props: FormCheckboxProps) {\n const htmlProps = useFormCheckbox(props);\n return createElement(TagName, htmlProps);\n }),\n);\n\nexport interface FormCheckboxOptions<T extends ElementType = TagName>\n extends FormControlOptions<T>, Omit<CheckboxOptions<T>, \"store\" | \"name\"> {}\n\nexport type FormCheckboxProps<T extends ElementType = TagName> = Props<\n T,\n FormCheckboxOptions<T>\n>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;MA2CI,kBAAgB,WAAe,SAAA,gBAAA,EAAA,OAAA,MAAA,UAAA,OAAA,SAAA,gBAAA,GAAA,SAAA;CAC/B,MAAA,UAAQ,eAAS;CAEjB,QAAA,SAEE;CAIF,UAAM,OAAO,QAAO,IAAQ,aAAA,gBAAA,mDAAA;CAO5B,MAAA,OAAQ,OAAY,QAAA;SALE,YAAA;SACpB,iBAAsB;GACtB,OAAA,MAAW,SAAU,IAAA;GAGkB,WAAA,UAAA,OAAA,SAAA,MAAA,KAAA;EAAG,CAAA;EAAO;EAAS;EAAU,GAAA;CAEtE,CAAA;SACE,eAAA;EACA;EACA;EACA,mBAAG,KAAA;EACJ,GAAA;CAED,CAAA;CAEJ,OAAA;;;;;;;;;;;;;;;;;;;;;;MAyBI,eAAO,KAAc,WADH,SAAA,aACqB,OAAA;CACxC,OACH,cAAA,SAAA,gBAAA,KAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as CollectionItemOptions } from "../collection-item-
|
|
1
|
+
import { n as CollectionItemOptions } from "../collection-item-pvEWNoNs.js";
|
|
2
2
|
import { t as FormStore } from "../form-store-C4Kf5QHm.js";
|
|
3
3
|
import { Props } from "@ariakit/react-utils";
|
|
4
4
|
import { ElementType, FocusEvent } from "react";
|
|
@@ -65,7 +65,7 @@ declare const useFormControl: import("@ariakit/react-utils").Hook<"input", FormC
|
|
|
65
65
|
* </Form>
|
|
66
66
|
* ```
|
|
67
67
|
*/
|
|
68
|
-
declare const FormControl: (props: FormControlProps) => import("react").ReactElement<
|
|
68
|
+
declare const FormControl: (props: FormControlProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
69
69
|
interface FormControlOptions<T extends ElementType = TagName> extends CollectionItemOptions<T> {
|
|
70
70
|
/**
|
|
71
71
|
* Object returned by the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-control.d.ts","names":["StringLike","Props","BooleanOrCallback","ElementType","FocusEvent","CollectionItemOptions","FormStore","TagName","useFormControl","FormControlOptions","Hook","FormControl","FormControlProps","props","ReactElement","JSXElementConstructor","T","store","name","touchOnBlur"],"sources":["../../src/form/form-control.d.ts"],"mappings":";;;;;;;;cAMcO,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFoB;;;;AAC5B;AAAA;;;;AACQ;AAyB7B;;;;AAAoG;AAiCpG;;;;;;;;;AA5DiD,cA2B5BC,cAAAA,iCAA+CE,IAAAA,UAAcD,kBAAkB;AAkCpG;;;;;;;;;;;;;;;;;;;;;;;;;;AA0B8C;AAE9C;;;;;AA5BA,cADqBE,WAAAA,GAAcE,KAAAA,EAAOD,gBAAgB,qBAAqBE,YAAAA
|
|
1
|
+
{"version":3,"file":"form-control.d.ts","names":["StringLike","Props","BooleanOrCallback","ElementType","FocusEvent","CollectionItemOptions","FormStore","TagName","useFormControl","FormControlOptions","Hook","FormControl","FormControlProps","props","ReactElement","JSXElementConstructor","T","store","name","touchOnBlur"],"sources":["../../src/form/form-control.d.ts"],"mappings":";;;;;;;;cAMcO,OAAAA;AAAAA,KACTA,OAAAA,UAAiBA,OAAO;AAFoB;;;;AAC5B;AAAA;;;;AACQ;AAyB7B;;;;AAAoG;AAiCpG;;;;;;;;;AA5DiD,cA2B5BC,cAAAA,iCAA+CE,IAAAA,UAAcD,kBAAkB;AAkCpG;;;;;;;;;;;;;;;;;;;;;;;;;;AA0B8C;AAE9C;;;;;AA5BA,cADqBE,WAAAA,GAAcE,KAAAA,EAAOD,gBAAgB,qBAAqBE,YAAAA,mCAA+CC,qBAAAA;AAAAA,UAC7GN,kBAAAA,WAA6BN,WAAAA,GAAcI,OAAAA,UAAiBF,qBAAAA,CAAsBW,CAAAA;EA4B1BP;;;;;;;EApBrEQ,KAAAA,GAAQX,SAAAA;EAoB0DU;;;;AAAuB;;;;;;;;EAPzFE,IAAAA,EAAMlB,UAAAA;;;;;EAKNmB,WAAAA,GAAcjB,iBAAAA,CAAkBE,UAAAA;AAAAA;AAAAA,KAExBQ,gBAAAA,WAA2BT,WAAAA,GAAcI,OAAAA,IAAWN,KAAAA,CAAMe,CAAAA,EAAGP,kBAAAA,CAAmBO,CAAAA"}
|
|
@@ -44,7 +44,7 @@ function useItem(store, name, type) {
|
|
|
44
44
|
const useFormControl = createHook(function useFormControl({ store, name: nameProp, getItem: getItemProp, touchOnBlur = true, ...props }) {
|
|
45
45
|
const context = useFormContext();
|
|
46
46
|
store = store || context;
|
|
47
|
-
invariant(store, "FormControl must be wrapped in a Form component.");
|
|
47
|
+
invariant(store, process.env.NODE_ENV !== "production" && "FormControl must be wrapped in a Form component.");
|
|
48
48
|
const name = String(nameProp);
|
|
49
49
|
const id = useId(props.id);
|
|
50
50
|
const ref = useRef(null);
|