@allxsmith/bestax-bulma 5.26.6 → 5.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/columns/Column.js +48 -0
- package/dist/esm/columns/Column.js.map +1 -0
- package/dist/esm/columns/Columns.js +53 -0
- package/dist/esm/columns/Columns.js.map +1 -0
- package/dist/esm/components/Avatar.js +299 -0
- package/dist/esm/components/Avatar.js.map +1 -0
- package/dist/esm/components/Avatars.js +81 -0
- package/dist/esm/components/Avatars.js.map +1 -0
- package/dist/esm/components/Badge.js +105 -0
- package/dist/esm/components/Badge.js.map +1 -0
- package/dist/esm/components/Breadcrumb.js +36 -0
- package/dist/esm/components/Breadcrumb.js.map +1 -0
- package/dist/esm/components/Card.js +252 -0
- package/dist/esm/components/Card.js.map +1 -0
- package/dist/esm/components/Carousel.js +351 -0
- package/dist/esm/components/Carousel.js.map +1 -0
- package/dist/esm/components/Collapse.js +193 -0
- package/dist/esm/components/Collapse.js.map +1 -0
- package/dist/esm/components/Collapses.js +99 -0
- package/dist/esm/components/Collapses.js.map +1 -0
- package/dist/esm/components/Dialog.js +230 -0
- package/dist/esm/components/Dialog.js.map +1 -0
- package/dist/esm/components/Dropdown.js +362 -0
- package/dist/esm/components/Dropdown.js.map +1 -0
- package/dist/esm/components/Loading.js +87 -0
- package/dist/esm/components/Loading.js.map +1 -0
- package/dist/esm/components/Menu.js +117 -0
- package/dist/esm/components/Menu.js.map +1 -0
- package/dist/esm/components/Message.js +56 -0
- package/dist/esm/components/Message.js.map +1 -0
- package/dist/esm/components/Modal.js +354 -0
- package/dist/esm/components/Modal.js.map +1 -0
- package/dist/esm/components/Navbar.js +287 -0
- package/dist/esm/components/Navbar.js.map +1 -0
- package/dist/esm/components/Pagination.js +191 -0
- package/dist/esm/components/Pagination.js.map +1 -0
- package/dist/esm/components/Panel.js +100 -0
- package/dist/esm/components/Panel.js.map +1 -0
- package/dist/esm/components/Popover.js +298 -0
- package/dist/esm/components/Popover.js.map +1 -0
- package/dist/esm/components/Reveal.js +157 -0
- package/dist/esm/components/Reveal.js.map +1 -0
- package/dist/esm/components/Sidebar.js +209 -0
- package/dist/esm/components/Sidebar.js.map +1 -0
- package/dist/esm/components/Steps.js +128 -0
- package/dist/esm/components/Steps.js.map +1 -0
- package/dist/esm/components/Tabs.js +335 -0
- package/dist/esm/components/Tabs.js.map +1 -0
- package/dist/esm/components/Toast.js +322 -0
- package/dist/esm/components/Toast.js.map +1 -0
- package/dist/esm/components/Tooltip.js +202 -0
- package/dist/esm/components/Tooltip.js.map +1 -0
- package/dist/esm/components/collapsesContext.js +12 -0
- package/dist/esm/components/collapsesContext.js.map +1 -0
- package/dist/esm/elements/Block.js +29 -0
- package/dist/esm/elements/Block.js.map +1 -0
- package/dist/esm/elements/Box.js +32 -0
- package/dist/esm/elements/Box.js.map +1 -0
- package/dist/esm/elements/Button.js +139 -0
- package/dist/esm/elements/Button.js.map +1 -0
- package/dist/esm/elements/Buttons.js +42 -0
- package/dist/esm/elements/Buttons.js.map +1 -0
- package/dist/esm/elements/Code.js +25 -0
- package/dist/esm/elements/Code.js.map +1 -0
- package/dist/esm/elements/Content.js +33 -0
- package/dist/esm/elements/Content.js.map +1 -0
- package/dist/esm/elements/Delete.js +35 -0
- package/dist/esm/elements/Delete.js.map +1 -0
- package/dist/esm/elements/Divider.js +27 -0
- package/dist/esm/elements/Divider.js.map +1 -0
- package/dist/esm/elements/Emphasis.js +25 -0
- package/dist/esm/elements/Emphasis.js.map +1 -0
- package/dist/esm/elements/Figure.js +58 -0
- package/dist/esm/elements/Figure.js.map +1 -0
- package/dist/esm/elements/Icon.js +256 -0
- package/dist/esm/elements/Icon.js.map +1 -0
- package/dist/esm/elements/IconText.js +36 -0
- package/dist/esm/elements/IconText.js.map +1 -0
- package/dist/esm/elements/Image.js +46 -0
- package/dist/esm/elements/Image.js.map +1 -0
- package/dist/esm/elements/Link.js +36 -0
- package/dist/esm/elements/Link.js.map +1 -0
- package/dist/esm/elements/LinkButton.js +37 -0
- package/dist/esm/elements/LinkButton.js.map +1 -0
- package/dist/esm/elements/ListItem.js +28 -0
- package/dist/esm/elements/ListItem.js.map +1 -0
- package/dist/esm/elements/Loader.js +37 -0
- package/dist/esm/elements/Loader.js.map +1 -0
- package/dist/esm/elements/Notification.js +316 -0
- package/dist/esm/elements/Notification.js.map +1 -0
- package/dist/esm/elements/OrderedList.js +31 -0
- package/dist/esm/elements/OrderedList.js.map +1 -0
- package/dist/esm/elements/Paragraph.js +28 -0
- package/dist/esm/elements/Paragraph.js.map +1 -0
- package/dist/esm/elements/Pre.js +25 -0
- package/dist/esm/elements/Pre.js.map +1 -0
- package/dist/esm/elements/Progress.js +33 -0
- package/dist/esm/elements/Progress.js.map +1 -0
- package/dist/esm/elements/Skeleton.js +30 -0
- package/dist/esm/elements/Skeleton.js.map +1 -0
- package/dist/esm/elements/Span.js +28 -0
- package/dist/esm/elements/Span.js.map +1 -0
- package/dist/esm/elements/Strong.js +25 -0
- package/dist/esm/elements/Strong.js.map +1 -0
- package/dist/esm/elements/SubTitle.js +51 -0
- package/dist/esm/elements/SubTitle.js.map +1 -0
- package/dist/esm/elements/Table.js +51 -0
- package/dist/esm/elements/Table.js.map +1 -0
- package/dist/esm/elements/Tag.js +49 -0
- package/dist/esm/elements/Tag.js.map +1 -0
- package/dist/esm/elements/Tags.js +34 -0
- package/dist/esm/elements/Tags.js.map +1 -0
- package/dist/esm/elements/Tbody.js +26 -0
- package/dist/esm/elements/Tbody.js.map +1 -0
- package/dist/esm/elements/Td.js +61 -0
- package/dist/esm/elements/Td.js.map +1 -0
- package/dist/esm/elements/Tfoot.js +26 -0
- package/dist/esm/elements/Tfoot.js.map +1 -0
- package/dist/esm/elements/Th.js +34 -0
- package/dist/esm/elements/Th.js.map +1 -0
- package/dist/esm/elements/Thead.js +26 -0
- package/dist/esm/elements/Thead.js.map +1 -0
- package/dist/esm/elements/Title.js +44 -0
- package/dist/esm/elements/Title.js.map +1 -0
- package/dist/esm/elements/Tr.js +31 -0
- package/dist/esm/elements/Tr.js.map +1 -0
- package/dist/esm/elements/UnorderedList.js +31 -0
- package/dist/esm/elements/UnorderedList.js.map +1 -0
- package/dist/esm/elements/iconProps.js +49 -0
- package/dist/esm/elements/iconProps.js.map +1 -0
- package/dist/esm/form/Autocomplete.js +279 -0
- package/dist/esm/form/Autocomplete.js.map +1 -0
- package/dist/esm/form/Checkbox.js +111 -0
- package/dist/esm/form/Checkbox.js.map +1 -0
- package/dist/esm/form/Checkboxes.js +89 -0
- package/dist/esm/form/Checkboxes.js.map +1 -0
- package/dist/esm/form/Control.js +79 -0
- package/dist/esm/form/Control.js.map +1 -0
- package/dist/esm/form/DateInput.js +87 -0
- package/dist/esm/form/DateInput.js.map +1 -0
- package/dist/esm/form/DateInputBase.js +263 -0
- package/dist/esm/form/DateInputBase.js.map +1 -0
- package/dist/esm/form/DateRangeInput.js +76 -0
- package/dist/esm/form/DateRangeInput.js.map +1 -0
- package/dist/esm/form/DateRangeInputBase.js +301 -0
- package/dist/esm/form/DateRangeInputBase.js.map +1 -0
- package/dist/esm/form/DateTimeInput.js +87 -0
- package/dist/esm/form/DateTimeInput.js.map +1 -0
- package/dist/esm/form/DateTimeInputBase.js +333 -0
- package/dist/esm/form/DateTimeInputBase.js.map +1 -0
- package/dist/esm/form/Field.js +153 -0
- package/dist/esm/form/Field.js.map +1 -0
- package/dist/esm/form/File.js +109 -0
- package/dist/esm/form/File.js.map +1 -0
- package/dist/esm/form/FormContext.js +170 -0
- package/dist/esm/form/FormContext.js.map +1 -0
- package/dist/esm/form/Input.js +88 -0
- package/dist/esm/form/Input.js.map +1 -0
- package/dist/esm/form/InputBase.js +40 -0
- package/dist/esm/form/InputBase.js.map +1 -0
- package/dist/esm/form/Numberinput.js +199 -0
- package/dist/esm/form/Numberinput.js.map +1 -0
- package/dist/esm/form/Radio.js +108 -0
- package/dist/esm/form/Radio.js.map +1 -0
- package/dist/esm/form/Radios.js +91 -0
- package/dist/esm/form/Radios.js.map +1 -0
- package/dist/esm/form/Rate.js +279 -0
- package/dist/esm/form/Rate.js.map +1 -0
- package/dist/esm/form/Select.js +81 -0
- package/dist/esm/form/Select.js.map +1 -0
- package/dist/esm/form/SelectBase.js +54 -0
- package/dist/esm/form/SelectBase.js.map +1 -0
- package/dist/esm/form/Slider.js +459 -0
- package/dist/esm/form/Slider.js.map +1 -0
- package/dist/esm/form/Switch.js +96 -0
- package/dist/esm/form/Switch.js.map +1 -0
- package/dist/esm/form/Taginput.js +352 -0
- package/dist/esm/form/Taginput.js.map +1 -0
- package/dist/esm/form/TextArea.js +77 -0
- package/dist/esm/form/TextArea.js.map +1 -0
- package/dist/esm/form/TextAreaBase.js +45 -0
- package/dist/esm/form/TextAreaBase.js.map +1 -0
- package/dist/esm/form/TimeInput.js +83 -0
- package/dist/esm/form/TimeInput.js.map +1 -0
- package/dist/esm/form/TimeInputBase.js +246 -0
- package/dist/esm/form/TimeInputBase.js.map +1 -0
- package/dist/esm/form/_pickerInternals/Calendar.js +760 -0
- package/dist/esm/form/_pickerInternals/Calendar.js.map +1 -0
- package/dist/esm/form/_pickerInternals/PickerPopover.js +95 -0
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -0
- package/dist/esm/form/_pickerInternals/TimeWheels.js +721 -0
- package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -0
- package/dist/esm/form/_pickerInternals/audioTick.js +109 -0
- package/dist/esm/form/_pickerInternals/audioTick.js.map +1 -0
- package/dist/esm/form/_pickerInternals/dateUtils.js +267 -0
- package/dist/esm/form/_pickerInternals/dateUtils.js.map +1 -0
- package/dist/esm/form/_pickerInternals/formatters.js +322 -0
- package/dist/esm/form/_pickerInternals/formatters.js.map +1 -0
- package/dist/esm/form/_pickerInternals/haptics.js +38 -0
- package/dist/esm/form/_pickerInternals/haptics.js.map +1 -0
- package/dist/esm/form/_pickerInternals/nativeInputSupport.js +25 -0
- package/dist/esm/form/_pickerInternals/nativeInputSupport.js.map +1 -0
- package/dist/esm/form/_pickerInternals/pickerTypes.js +50 -0
- package/dist/esm/form/_pickerInternals/pickerTypes.js.map +1 -0
- package/dist/esm/form/_pickerInternals/segmentMap.js +315 -0
- package/dist/esm/form/_pickerInternals/segmentMap.js.map +1 -0
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js +49 -0
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js.map +1 -0
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js +427 -0
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js.map +1 -0
- package/dist/esm/form/controlLoading.js +18 -0
- package/dist/esm/form/controlLoading.js.map +1 -0
- package/dist/esm/form/useAutoLabelId.js +54 -0
- package/dist/esm/form/useAutoLabelId.js.map +1 -0
- package/dist/esm/grid/Cell.js +35 -0
- package/dist/esm/grid/Cell.js.map +1 -0
- package/dist/esm/grid/Grid.js +51 -0
- package/dist/esm/grid/Grid.js.map +1 -0
- package/dist/esm/helpers/ClientOnly.js +33 -0
- package/dist/esm/helpers/ClientOnly.js.map +1 -0
- package/dist/esm/helpers/Config.js +60 -0
- package/dist/esm/helpers/Config.js.map +1 -0
- package/dist/esm/helpers/Theme.js +947 -0
- package/dist/esm/helpers/Theme.js.map +1 -0
- package/dist/esm/helpers/anchorAttrs.js +72 -0
- package/dist/esm/helpers/anchorAttrs.js.map +1 -0
- package/dist/esm/helpers/bulmaClassHelpers.js +415 -0
- package/dist/esm/helpers/bulmaClassHelpers.js.map +1 -0
- package/dist/esm/helpers/buttonType.js +24 -0
- package/dist/esm/helpers/buttonType.js.map +1 -0
- package/dist/esm/helpers/classNames.js +137 -0
- package/dist/esm/helpers/classNames.js.map +1 -0
- package/dist/esm/helpers/colorDeprecations.js +50 -0
- package/dist/esm/helpers/colorDeprecations.js.map +1 -0
- package/dist/esm/helpers/devWarnings.js +27 -0
- package/dist/esm/helpers/devWarnings.js.map +1 -0
- package/dist/esm/helpers/inertProps.js +27 -0
- package/dist/esm/helpers/inertProps.js.map +1 -0
- package/dist/esm/helpers/mergeBulmaStyles.js +20 -0
- package/dist/esm/helpers/mergeBulmaStyles.js.map +1 -0
- package/dist/esm/helpers/polymorphic.js +18 -0
- package/dist/esm/helpers/polymorphic.js.map +1 -0
- package/dist/esm/helpers/portal.js +76 -0
- package/dist/esm/helpers/portal.js.map +1 -0
- package/dist/esm/helpers/positionStacks.js +45 -0
- package/dist/esm/helpers/positionStacks.js.map +1 -0
- package/dist/esm/helpers/scrollLock.js +38 -0
- package/dist/esm/helpers/scrollLock.js.map +1 -0
- package/dist/esm/helpers/shadowDom.js +71 -0
- package/dist/esm/helpers/shadowDom.js.map +1 -0
- package/dist/esm/helpers/statusRegion.js +282 -0
- package/dist/esm/helpers/statusRegion.js.map +1 -0
- package/dist/esm/helpers/useAnchoredPosition.js +86 -0
- package/dist/esm/helpers/useAnchoredPosition.js.map +1 -0
- package/dist/esm/helpers/useBulmaClasses.js +158 -0
- package/dist/esm/helpers/useBulmaClasses.js.map +1 -0
- package/dist/esm/helpers/useClientLayoutEffect.js +13 -0
- package/dist/esm/helpers/useClientLayoutEffect.js.map +1 -0
- package/dist/esm/helpers/useColorClasses.js +84 -0
- package/dist/esm/helpers/useColorClasses.js.map +1 -0
- package/dist/esm/helpers/useFlexboxClasses.js +92 -0
- package/dist/esm/helpers/useFlexboxClasses.js.map +1 -0
- package/dist/esm/helpers/useFocusTrap.js +470 -0
- package/dist/esm/helpers/useFocusTrap.js.map +1 -0
- package/dist/esm/helpers/useIsHydrated.js +31 -0
- package/dist/esm/helpers/useIsHydrated.js.map +1 -0
- package/dist/esm/helpers/useOtherClasses.js +115 -0
- package/dist/esm/helpers/useOtherClasses.js.map +1 -0
- package/dist/esm/helpers/useSpacingClasses.js +82 -0
- package/dist/esm/helpers/useSpacingClasses.js.map +1 -0
- package/dist/esm/helpers/useTypographyClasses.js +93 -0
- package/dist/esm/helpers/useTypographyClasses.js.map +1 -0
- package/dist/esm/helpers/useVisibilityClasses.js +134 -0
- package/dist/esm/helpers/useVisibilityClasses.js.map +1 -0
- package/dist/esm/helpers/withSubComponents.js +24 -0
- package/dist/esm/helpers/withSubComponents.js.map +1 -0
- package/dist/esm/layout/Container.js +48 -0
- package/dist/esm/layout/Container.js.map +1 -0
- package/dist/esm/layout/Footer.js +33 -0
- package/dist/esm/layout/Footer.js.map +1 -0
- package/dist/esm/layout/Hero.js +90 -0
- package/dist/esm/layout/Hero.js.map +1 -0
- package/dist/esm/layout/Level.js +110 -0
- package/dist/esm/layout/Level.js.map +1 -0
- package/dist/esm/layout/Media.js +86 -0
- package/dist/esm/layout/Media.js.map +1 -0
- package/dist/esm/layout/Section.js +30 -0
- package/dist/esm/layout/Section.js.map +1 -0
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +821 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +115 -16845
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Tabs.d.ts +25 -3
- package/dist/types/elements/Icon.d.ts +10 -7
- package/dist/types/form/DateInputBase.d.ts +8 -6
- package/dist/types/form/DateRangeInput.d.ts +91 -0
- package/dist/types/form/DateRangeInputBase.d.ts +172 -0
- package/dist/types/form/DateTimeInputBase.d.ts +10 -6
- package/dist/types/form/File.d.ts +18 -5
- package/dist/types/form/FormContext.d.ts +11 -0
- package/dist/types/form/TimeInputBase.d.ts +1 -1
- package/dist/types/form/_pickerInternals/PickerPopover.d.ts +1 -0
- package/dist/types/form/_pickerInternals/dateUtils.d.ts +7 -0
- package/dist/types/form/_pickerInternals/formatters.d.ts +14 -0
- package/dist/types/form/_pickerInternals/pickerTypes.d.ts +13 -0
- package/dist/types/form/_pickerInternals/useSegmentedEntry.d.ts +12 -3
- package/dist/types/index.d.ts +4 -0
- package/dist/types-cjs/components/Tabs.d.ts +25 -3
- package/dist/types-cjs/elements/Icon.d.ts +10 -7
- package/dist/types-cjs/form/DateInputBase.d.ts +8 -6
- package/dist/types-cjs/form/DateRangeInput.d.ts +91 -0
- package/dist/types-cjs/form/DateRangeInputBase.d.ts +172 -0
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +10 -6
- package/dist/types-cjs/form/File.d.ts +18 -5
- package/dist/types-cjs/form/FormContext.d.ts +11 -0
- package/dist/types-cjs/form/TimeInputBase.d.ts +1 -1
- package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +1 -0
- package/dist/types-cjs/form/_pickerInternals/dateUtils.d.ts +7 -0
- package/dist/types-cjs/form/_pickerInternals/formatters.d.ts +14 -0
- package/dist/types-cjs/form/_pickerInternals/pickerTypes.d.ts +13 -0
- package/dist/types-cjs/form/_pickerInternals/useSegmentedEntry.d.ts +12 -3
- package/dist/types-cjs/index.d.ts +4 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/components/_tabs.scss +44 -0
- package/src/scss/form/_dateinput.scss +87 -8
- package/src/scss/form/_daterangeinput.scss +63 -0
- package/src/scss/form/_datetimeinput.scss +7 -2
- package/src/scss/form/_file.scss +37 -0
- package/src/scss/form/_index.scss +2 -0
- package/src/scss/form/_picker-popover.scss +1 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulmaClassHelpers.js","sources":["../../../src/helpers/bulmaClassHelpers.ts"],"sourcesContent":["/**\n * Valid Bulma color classes.\n * @example 'primary', 'link', 'info'\n */\nexport const validColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n 'black',\n 'black-bis',\n 'black-ter',\n 'grey-darker',\n 'grey-dark',\n 'grey',\n 'grey-light',\n 'grey-lighter',\n 'white',\n 'white-bis',\n 'white-ter',\n 'light',\n 'dark',\n] as const;\n\n/**\n * Valid Bulma color shade suffixes.\n * @example '00', '05', 'invert', 'light', 'dark', 'soft', 'bold', 'on-scheme'\n */\nexport const validColorShades = [\n '00',\n '05',\n '10',\n '15',\n '20',\n '25',\n '30',\n '35',\n '40',\n '45',\n '50',\n '55',\n '60',\n '65',\n '70',\n '75',\n '80',\n '85',\n '90',\n '95',\n 'invert',\n 'light',\n 'dark',\n 'soft',\n 'bold',\n 'on-scheme',\n] as const;\n\n/**\n * Valid Bulma scheme color names for scheme-aware backgrounds.\n *\n * Bulma ships no `has-background-scheme-*` helper classes, so these values\n * never emit a class — components render them as a dark-mode-safe inline\n * `background-color: var(--bulma-<value>)` style instead.\n * @example 'scheme-main', 'scheme-main-bis', 'scheme-invert'\n */\nexport const validSchemeColors = [\n 'scheme-main',\n 'scheme-main-bis',\n 'scheme-main-ter',\n 'scheme-invert',\n 'scheme-invert-bis',\n 'scheme-invert-ter',\n] as const;\n\n/**\n * Valid Bulma size classes for margins and paddings.\n * @example '0', '1', 'auto'\n */\nexport const validSizes = ['0', '1', '2', '3', '4', '5', '6', 'auto'] as const;\n\n/**\n * Valid Bulma gap steps, taken by `gap`, `columnGap` and `rowGap`. Each whole\n * step is 0.5rem, so `2` is 1rem and `8` is 4rem, and the half steps sit\n * between them. They render `is-gap-<value>`, `is-column-gap-<value>` and\n * `is-row-gap-<value>`.\n *\n * This is a different scale from `validSizes`: `gap=\"2\"` is 1rem where\n * `m=\"2\"` is 0.5rem.\n * @example '0', '0.5', '2', '8'\n */\nexport const validGaps = [\n '0',\n '0.5',\n '1',\n '1.5',\n '2',\n '2.5',\n '3',\n '3.5',\n '4',\n '4.5',\n '5',\n '5.5',\n '6',\n '6.5',\n '7',\n '7.5',\n '8',\n] as const;\n\n// Spelled out rather than built from `validGaps` so the API docs can print\n// it; a type test in useSpacingClasses.test.tsx holds both halves to the\n// tuple.\n/**\n * A gap step as `gap`, `columnGap` and `rowGap` take it: a value from\n * `validGaps`, or the same step written as a number (`gap={2}`,\n * `gap={1.5}`). `Grid` took its gaps as numbers before the gap helpers were\n * shared, so every gap prop still does.\n */\nexport type BulmaGapStep =\n | '0'\n | '0.5'\n | '1'\n | '1.5'\n | '2'\n | '2.5'\n | '3'\n | '3.5'\n | '4'\n | '4.5'\n | '5'\n | '5.5'\n | '6'\n | '6.5'\n | '7'\n | '7.5'\n | '8'\n | 0\n | 0.5\n | 1\n | 1.5\n | 2\n | 2.5\n | 3\n | 3.5\n | 4\n | 4.5\n | 5\n | 5.5\n | 6\n | 6.5\n | 7\n | 7.5\n | 8;\n\n/**\n * Valid Bulma text size classes.\n * @example '1', '2', '3'\n */\nexport const validTextSizes = ['1', '2', '3', '4', '5', '6', '7'] as const;\n\n/**\n * Valid Bulma text alignment classes.\n * @example 'centered', 'left', 'right'\n */\nexport const validAlignments = [\n 'centered',\n 'justified',\n 'left',\n 'right',\n] as const;\n\n/**\n * Valid Bulma text transformation classes.\n * @example 'capitalized', 'uppercase', 'italic'\n */\nexport const validTextTransforms = [\n 'capitalized',\n 'lowercase',\n 'uppercase',\n 'italic',\n] as const;\n\n/**\n * Valid Bulma text weight classes.\n * @example 'light', 'normal', 'bold'\n */\nexport const validTextWeights = [\n 'light',\n 'normal',\n 'medium',\n 'semibold',\n 'bold',\n] as const;\n\n/**\n * Valid Bulma font family classes.\n * @example 'sans-serif', 'monospace', 'code'\n */\nexport const validFontFamilies = [\n 'sans-serif',\n 'monospace',\n 'primary',\n 'secondary',\n 'code',\n] as const;\n\n/**\n * Valid Bulma display classes.\n * @example 'block', 'flex', 'inline'\n */\nexport const validDisplays = [\n 'block',\n 'flex',\n 'inline',\n 'inline-block',\n 'inline-flex',\n 'grid',\n] as const;\n\n/**\n * Valid Bulma visibility classes.\n * These are all the valid visibility options available in Bulma.\n * @example 'hidden', 'sr-only', 'invisible'\n */\nexport const validVisibilities = ['hidden', 'sr-only', 'invisible'] as const;\n\n/**\n * Valid Bulma flex direction classes.\n * @example 'row', 'column', 'row-reverse'\n */\nexport const validFlexDirections = [\n 'row',\n 'row-reverse',\n 'column',\n 'column-reverse',\n] as const;\n\n/**\n * Valid Bulma flex wrap classes.\n * @example 'nowrap', 'wrap', 'wrap-reverse'\n */\nexport const validFlexWraps = ['nowrap', 'wrap', 'wrap-reverse'] as const;\n\n/**\n * Valid Bulma justify-content classes.\n * @example 'flex-start', 'center', 'space-between'\n */\nexport const validJustifyContents = [\n 'flex-start',\n 'flex-end',\n 'center',\n 'space-between',\n 'space-around',\n 'space-evenly',\n 'start',\n 'end',\n 'left',\n 'right',\n] as const;\n\n/**\n * Valid Bulma align-content classes.\n * @example 'flex-start', 'center', 'stretch'\n */\nexport const validAlignContents = [\n 'flex-start',\n 'flex-end',\n 'center',\n 'space-between',\n 'space-around',\n 'space-evenly',\n 'stretch',\n] as const;\n\n/**\n * Valid Bulma align-items classes.\n * @example 'stretch', 'flex-start', 'center'\n */\nexport const validAlignItems = [\n 'stretch',\n 'flex-start',\n 'flex-end',\n 'center',\n 'baseline',\n 'start',\n 'end',\n] as const;\n\n/**\n * Valid Bulma align-self classes.\n * @example 'auto', 'flex-start', 'center'\n */\nexport const validAlignSelfs = [\n 'auto',\n 'flex-start',\n 'flex-end',\n 'center',\n 'baseline',\n 'stretch',\n] as const;\n\n/**\n * Valid Bulma flex grow and shrink values.\n * @example '0', '1', '2', '3', '4', '5'\n */\nexport const validFlexGrowShrink = ['0', '1', '2', '3', '4', '5'] as const;\n\n/**\n * Valid Bulma viewport classes for responsive design.\n * @example 'mobile', 'tablet', 'desktop'\n */\nexport const validViewports = [\n 'mobile',\n 'tablet',\n 'tablet-only',\n 'touch',\n 'desktop',\n 'desktop-only',\n 'widescreen',\n 'widescreen-only',\n 'fullhd',\n] as const;\n\n/**\n * Valid Bulma float classes.\n * @example 'left', 'right'\n */\nexport const validFloats = ['left', 'right'] as const;\n\n/**\n * Valid Bulma overflow values for one axis, taken by `overflowX` and\n * `overflowY`. Each renders `is-overflow-x-<value>` or `is-overflow-y-<value>`.\n * @example 'auto', 'hidden', 'scroll'\n */\nexport const validAxisOverflows = [\n 'auto',\n 'clip',\n 'hidden',\n 'scroll',\n 'visible',\n] as const;\n\n/**\n * Valid Bulma overflow values for `overflow`.\n *\n * `clipped` renders `is-clipped`, the helper `overflow` started with. Every\n * other value renders `is-overflow-<value>`.\n * @example 'clipped', 'auto', 'hidden'\n */\nexport const validOverflows = ['clipped', ...validAxisOverflows] as const;\n\n/**\n * Valid Bulma position values, taken by `pos`. Each renders\n * `is-position-<value>`.\n * @example 'relative', 'absolute', 'sticky'\n */\nexport const validPositions = [\n 'absolute',\n 'fixed',\n 'relative',\n 'static',\n 'sticky',\n] as const;\n\n/**\n * Valid Bulma aspect ratios, taken by `aspectRatio`. Each renders\n * `is-aspect-ratio-<value>`.\n * @example '1by1', '4by3', '16by9'\n */\nexport const validAspectRatios = [\n '1by1',\n '5by4',\n '4by3',\n '3by2',\n '5by3',\n '16by9',\n '2by1',\n '3by1',\n '4by5',\n '3by4',\n '2by3',\n '3by5',\n '9by16',\n '1by2',\n '1by3',\n] as const;\n\n/**\n * Valid Bulma interaction classes.\n * @example 'unselectable', 'clickable'\n */\nexport const validInteractions = ['unselectable', 'clickable'] as const;\n\n/**\n * Valid Bulma cursor helper values.\n *\n * These share no class stem: `pointer` renders `is-clickable` and `help`\n * renders `is-cursor-help`, so the class each one emits lives in\n * `cursorClasses` rather than being built from the value.\n * @example 'pointer', 'help'\n */\nexport const validCursors = ['pointer', 'help'] as const;\n\n/**\n * Cursor helper value to the class it renders.\n *\n * A `Record` over `validCursors` on purpose: TypeScript then rejects a value\n * added to the tuple with no class for it, and a class for a value the tuple\n * does not carry, so the accepted set and the rendered classes cannot drift\n * apart.\n */\nexport const cursorClasses: Record<(typeof validCursors)[number], string> = {\n pointer: 'is-clickable',\n help: 'is-cursor-help',\n};\n\n/**\n * Valid Bulma border-radius helper values.\n *\n * `radiusless` renders `is-radiusless` and removes the radius. The sizes\n * render `has-radius-<value>` and set one from Bulma's radius scale.\n * @example 'radiusless', 'small', 'rounded'\n */\nexport const validRadii = [\n 'radiusless',\n 'small',\n 'normal',\n 'large',\n 'rounded',\n] as const;\n\n/**\n * Valid Bulma shadow helper classes.\n * @example 'shadowless'\n */\nexport const validShadows = ['shadowless'] as const;\n\n/**\n * Valid Bulma responsive helper classes.\n * @example 'mobile', 'narrow'\n */\nexport const validResponsives = ['mobile', 'narrow'] as const;\n\n/**\n * Props for applying a Bulma viewport modifier to viewport-aware helper classes.\n */\nexport interface BulmaViewportProps {\n /** Viewport for responsive classes (e.g., 'mobile', 'desktop'). */\n viewport?: (typeof validViewports)[number];\n}\n\n/**\n * Props for applying Bulma display helper classes, including viewport-specific\n * display variants.\n */\nexport interface BulmaDisplayProps {\n /** Display type (e.g., 'block', 'flex'). */\n display?: (typeof validDisplays)[number] | 'none';\n /** Display type for mobile viewport (up to 768px). */\n displayMobile?: (typeof validDisplays)[number] | 'none';\n /** Display type for tablet viewport (769px - 1023px). */\n displayTablet?: (typeof validDisplays)[number] | 'none';\n /** Display type for tablet-only viewport (769px - 1023px, excludes desktop+). */\n displayTabletOnly?: (typeof validDisplays)[number] | 'none';\n /** Display type for touch viewport (up to 1023px; mobile + tablet). */\n displayTouch?: (typeof validDisplays)[number] | 'none';\n /** Display type for desktop viewport (1024px - 1215px). */\n displayDesktop?: (typeof validDisplays)[number] | 'none';\n /** Display type for desktop-only viewport (1024px - 1215px, excludes widescreen+). */\n displayDesktopOnly?: (typeof validDisplays)[number] | 'none';\n /** Display type for widescreen viewport (1216px - 1407px). */\n displayWidescreen?: (typeof validDisplays)[number] | 'none';\n /** Display type for widescreen-only viewport (1216px - 1407px, excludes fullhd). */\n displayWidescreenOnly?: (typeof validDisplays)[number] | 'none';\n /** Display type for fullhd viewport (1408px and above). */\n displayFullhd?: (typeof validDisplays)[number] | 'none';\n}\n\n/**\n * Creates the shared class-building helpers used by the Bulma helper hooks.\n *\n * Returns a mutable `classes` array along with the helper functions that push\n * (optionally prefixed, optionally viewport-suffixed) class names onto it.\n *\n * @internal\n * @param classPrefix - Optional prefix applied to all generated class names.\n * @param viewport - Optional viewport modifier for viewport-aware classes.\n */\nexport const createBulmaClassHelpers = (\n classPrefix?: string,\n viewport?: (typeof validViewports)[number]\n) => {\n const classes: string[] = [];\n\n // Helper function to add class with prefix support\n const addPrefixedClass = (className: string) => {\n classes.push(classPrefix ? `${classPrefix}${className}` : className);\n };\n\n // Helper to add class with optional viewport\n //\n // `supportedViewports` narrows which viewports may be suffixed onto this\n // class. It defaults to every viewport, but a few Bulma helper families\n // (notably `is-size-*`, which ships no `-only` bands) support only a subset,\n // so passing the emitting set keeps us from producing dead classes.\n const addClass = (\n prefix: string,\n value: string | undefined,\n validValues: readonly string[],\n supportsViewport = false,\n supportedViewports: readonly string[] = validViewports\n ) => {\n if (value && validValues.includes(value)) {\n const className =\n supportsViewport &&\n viewport &&\n validViewports.includes(viewport) &&\n supportedViewports.includes(viewport)\n ? `${prefix}-${value}-${viewport}`\n : `${prefix}-${value}`;\n addPrefixedClass(className);\n }\n };\n\n // Helper specifically for classes that never support viewport modifiers\n const addClassNoViewport = (\n prefix: string,\n value: string | undefined,\n validValues: readonly string[]\n ) => {\n if (value && (!validValues.length || validValues.includes(value))) {\n addPrefixedClass(`${prefix}-${value}`);\n }\n };\n\n return { classes, addPrefixedClass, addClass, addClassNoViewport };\n};\n"],"names":["validSizes","validAlignments"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
/**
|
|
3
|
+
* The `type` to render on a `<button>` a component defaults to `button`: the
|
|
4
|
+
* caller's own value when it is `button`, `submit` or `reset`, and `button`
|
|
5
|
+
* otherwise.
|
|
6
|
+
*
|
|
7
|
+
* A missing `type` is not the only way a button ends up submitting the form
|
|
8
|
+
* around it. HTML reads an invalid value, such as the anchor's MIME-type
|
|
9
|
+
* `type="text/html"`, as submit too, and a props spread carrying
|
|
10
|
+
* `type: undefined` removes the attribute outright. Both can arrive through a
|
|
11
|
+
* spread or an untyped caller the component's own types never see, so this
|
|
12
|
+
* checks the value rather than trusting where it came from.
|
|
13
|
+
*
|
|
14
|
+
* Call it AFTER the forwarded props are spread and pass it the forwarded
|
|
15
|
+
* `type`, so its result is the attribute that renders.
|
|
16
|
+
*/
|
|
17
|
+
function buttonType(given) {
|
|
18
|
+
return given === 'submit' || given === 'reset' || given === 'button'
|
|
19
|
+
? given
|
|
20
|
+
: 'button';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { buttonType };
|
|
24
|
+
//# sourceMappingURL=buttonType.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buttonType.js","sources":["../../../src/helpers/buttonType.ts"],"sourcesContent":["import type React from 'react';\n\n/** The values HTML defines for a `<button>`'s `type`. */\nexport type ButtonType = NonNullable<\n React.ButtonHTMLAttributes<HTMLButtonElement>['type']\n>;\n\n/**\n * The `type` to render on a `<button>` a component defaults to `button`: the\n * caller's own value when it is `button`, `submit` or `reset`, and `button`\n * otherwise.\n *\n * A missing `type` is not the only way a button ends up submitting the form\n * around it. HTML reads an invalid value, such as the anchor's MIME-type\n * `type=\"text/html\"`, as submit too, and a props spread carrying\n * `type: undefined` removes the attribute outright. Both can arrive through a\n * spread or an untyped caller the component's own types never see, so this\n * checks the value rather than trusting where it came from.\n *\n * Call it AFTER the forwarded props are spread and pass it the forwarded\n * `type`, so its result is the attribute that renders.\n */\nexport function buttonType(given: unknown): ButtonType {\n return given === 'submit' || given === 'reset' || given === 'button'\n ? given\n : 'button';\n}\n"],"names":[],"mappings":";AAOA;;;;;;;;;;;;;;AAcG;AACG,SAAU,UAAU,CAAC,KAAc,EAAA;IACvC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK;AAC1D,UAAE;UACA,QAAQ;AACd;;"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { useConfig } from './Config.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns a space-separated string of class names based on input arguments.
|
|
6
|
+
*
|
|
7
|
+
* Accepts any mix of strings, numbers, arrays, or objects. Falsy values are ignored.
|
|
8
|
+
* Array and object values are recursively flattened, and object keys are included
|
|
9
|
+
* if their value is truthy. Duplicate class names are removed.
|
|
10
|
+
*
|
|
11
|
+
* @param {...(string | number | undefined | null | false | Record<string, unknown> | unknown[])} args - Class values to join.
|
|
12
|
+
* @returns {string} A space-separated string of unique class names.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* classNames('foo', ['bar', { baz: true }], { qux: false, quux: true });
|
|
16
|
+
* // => 'foo bar baz quux'
|
|
17
|
+
*/
|
|
18
|
+
function classNames(...args) {
|
|
19
|
+
const classSet = new Set();
|
|
20
|
+
function process(item) {
|
|
21
|
+
if (item === undefined || item === null || item === false || item === '') {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (typeof item === 'string' || typeof item === 'number') {
|
|
25
|
+
for (const cls of String(item).split(/\s+/)) {
|
|
26
|
+
if (cls)
|
|
27
|
+
classSet.add(cls);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else if (Array.isArray(item)) {
|
|
31
|
+
for (const sub of item)
|
|
32
|
+
process(sub);
|
|
33
|
+
}
|
|
34
|
+
else if (typeof item === 'object') {
|
|
35
|
+
for (const key in item) {
|
|
36
|
+
if (Object.prototype.hasOwnProperty.call(item, key) && item[key]) {
|
|
37
|
+
for (const cls of key.split(/\s+/)) {
|
|
38
|
+
if (cls)
|
|
39
|
+
classSet.add(cls);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const arg of args) {
|
|
46
|
+
process(arg);
|
|
47
|
+
}
|
|
48
|
+
return Array.from(classSet).join(' ');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a prefixed version of classNames that automatically applies a prefix to all class names.
|
|
52
|
+
*
|
|
53
|
+
* @param {string} classPrefix - The prefix to apply to all class names.
|
|
54
|
+
* @returns {Function} A classNames function that applies the prefix.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* const prefixedClassNames = createPrefixedClassNames('bulma-');
|
|
58
|
+
* prefixedClassNames('button', { 'is-primary': true });
|
|
59
|
+
* // => 'bulma-button bulma-is-primary'
|
|
60
|
+
*/
|
|
61
|
+
function createPrefixedClassNames(classPrefix) {
|
|
62
|
+
return function prefixedClassNames(...args) {
|
|
63
|
+
const classSet = new Set();
|
|
64
|
+
function process(item) {
|
|
65
|
+
if (item === undefined ||
|
|
66
|
+
item === null ||
|
|
67
|
+
item === false ||
|
|
68
|
+
item === '') {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (typeof item === 'string' || typeof item === 'number') {
|
|
72
|
+
for (const cls of String(item).split(/\s+/)) {
|
|
73
|
+
if (cls) {
|
|
74
|
+
classSet.add(`${classPrefix}${cls}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else if (Array.isArray(item)) {
|
|
79
|
+
for (const sub of item)
|
|
80
|
+
process(sub);
|
|
81
|
+
}
|
|
82
|
+
else if (typeof item === 'object') {
|
|
83
|
+
for (const key in item) {
|
|
84
|
+
if (Object.prototype.hasOwnProperty.call(item, key) && item[key]) {
|
|
85
|
+
for (const cls of key.split(/\s+/)) {
|
|
86
|
+
if (cls) {
|
|
87
|
+
classSet.add(`${classPrefix}${cls}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const arg of args) {
|
|
95
|
+
process(arg);
|
|
96
|
+
}
|
|
97
|
+
return Array.from(classSet).join(' ');
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* A simple wrapper around classNames that applies an optional prefix to all class names.
|
|
102
|
+
*
|
|
103
|
+
* @param {string | undefined} prefix - The prefix to apply to all class names. If undefined, no prefix is applied.
|
|
104
|
+
* @param {...(string | number | undefined | null | false | Record<string, unknown> | unknown[])} args - Class values to join.
|
|
105
|
+
* @returns {string} A space-separated string of unique class names, with prefix applied if provided.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* prefixedClassNames('bulma-', 'button', { 'is-primary': true });
|
|
109
|
+
* // => 'bulma-button bulma-is-primary'
|
|
110
|
+
*
|
|
111
|
+
* prefixedClassNames(undefined, 'button', { 'is-primary': true });
|
|
112
|
+
* // => 'button is-primary'
|
|
113
|
+
*/
|
|
114
|
+
function prefixedClassNames(prefix, ...args) {
|
|
115
|
+
if (!prefix) {
|
|
116
|
+
return classNames(...args);
|
|
117
|
+
}
|
|
118
|
+
return createPrefixedClassNames(prefix)(...args);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Hook that automatically applies the classPrefix from Config context to class names.
|
|
122
|
+
*
|
|
123
|
+
* @param {...(string | number | undefined | null | false | Record<string, unknown> | unknown[])} args - Class values to join.
|
|
124
|
+
* @returns {string} A space-separated string of unique class names with prefix applied from context.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* // With ConfigProvider providing classPrefix="bulma-"
|
|
128
|
+
* const classes = usePrefixedClassNames('button', { 'is-primary': true });
|
|
129
|
+
* // => 'bulma-button bulma-is-primary'
|
|
130
|
+
*/
|
|
131
|
+
function usePrefixedClassNames(...args) {
|
|
132
|
+
const { classPrefix } = useConfig();
|
|
133
|
+
return prefixedClassNames(classPrefix, ...args);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { classNames, createPrefixedClassNames, classNames as default, prefixedClassNames, usePrefixedClassNames };
|
|
137
|
+
//# sourceMappingURL=classNames.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classNames.js","sources":["../../../src/helpers/classNames.ts"],"sourcesContent":["import { useConfig } from './Config';\n\n/**\n * Returns a space-separated string of class names based on input arguments.\n *\n * Accepts any mix of strings, numbers, arrays, or objects. Falsy values are ignored.\n * Array and object values are recursively flattened, and object keys are included\n * if their value is truthy. Duplicate class names are removed.\n *\n * @param {...(string | number | undefined | null | false | Record<string, unknown> | unknown[])} args - Class values to join.\n * @returns {string} A space-separated string of unique class names.\n *\n * @example\n * classNames('foo', ['bar', { baz: true }], { qux: false, quux: true });\n * // => 'foo bar baz quux'\n */\nexport function classNames(\n ...args: (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[]\n): string {\n const classSet = new Set<string>();\n\n function process(\n item:\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n ) {\n if (item === undefined || item === null || item === false || item === '') {\n return;\n }\n if (typeof item === 'string' || typeof item === 'number') {\n for (const cls of String(item).split(/\\s+/)) {\n if (cls) classSet.add(cls);\n }\n } else if (Array.isArray(item)) {\n for (const sub of item as (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[])\n process(sub);\n } else if (typeof item === 'object') {\n for (const key in item) {\n if (Object.prototype.hasOwnProperty.call(item, key) && item[key]) {\n for (const cls of key.split(/\\s+/)) {\n if (cls) classSet.add(cls);\n }\n }\n }\n }\n }\n\n for (const arg of args) {\n process(arg);\n }\n return Array.from(classSet).join(' ');\n}\n\n/**\n * Creates a prefixed version of classNames that automatically applies a prefix to all class names.\n *\n * @param {string} classPrefix - The prefix to apply to all class names.\n * @returns {Function} A classNames function that applies the prefix.\n *\n * @example\n * const prefixedClassNames = createPrefixedClassNames('bulma-');\n * prefixedClassNames('button', { 'is-primary': true });\n * // => 'bulma-button bulma-is-primary'\n */\nexport function createPrefixedClassNames(classPrefix: string) {\n return function prefixedClassNames(\n ...args: (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[]\n ): string {\n const classSet = new Set<string>();\n\n function process(\n item:\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n ) {\n if (\n item === undefined ||\n item === null ||\n item === false ||\n item === ''\n ) {\n return;\n }\n if (typeof item === 'string' || typeof item === 'number') {\n for (const cls of String(item).split(/\\s+/)) {\n if (cls) {\n classSet.add(`${classPrefix}${cls}`);\n }\n }\n } else if (Array.isArray(item)) {\n for (const sub of item as (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[])\n process(sub);\n } else if (typeof item === 'object') {\n for (const key in item) {\n if (Object.prototype.hasOwnProperty.call(item, key) && item[key]) {\n for (const cls of key.split(/\\s+/)) {\n if (cls) {\n classSet.add(`${classPrefix}${cls}`);\n }\n }\n }\n }\n }\n }\n\n for (const arg of args) {\n process(arg);\n }\n return Array.from(classSet).join(' ');\n };\n}\n\nexport default classNames;\n\n/**\n * A simple wrapper around classNames that applies an optional prefix to all class names.\n *\n * @param {string | undefined} prefix - The prefix to apply to all class names. If undefined, no prefix is applied.\n * @param {...(string | number | undefined | null | false | Record<string, unknown> | unknown[])} args - Class values to join.\n * @returns {string} A space-separated string of unique class names, with prefix applied if provided.\n *\n * @example\n * prefixedClassNames('bulma-', 'button', { 'is-primary': true });\n * // => 'bulma-button bulma-is-primary'\n *\n * prefixedClassNames(undefined, 'button', { 'is-primary': true });\n * // => 'button is-primary'\n */\nexport function prefixedClassNames(\n prefix: string | undefined,\n ...args: (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[]\n): string {\n if (!prefix) {\n return classNames(...args);\n }\n\n return createPrefixedClassNames(prefix)(...args);\n}\n\n/**\n * Hook that automatically applies the classPrefix from Config context to class names.\n *\n * @param {...(string | number | undefined | null | false | Record<string, unknown> | unknown[])} args - Class values to join.\n * @returns {string} A space-separated string of unique class names with prefix applied from context.\n *\n * @example\n * // With ConfigProvider providing classPrefix=\"bulma-\"\n * const classes = usePrefixedClassNames('button', { 'is-primary': true });\n * // => 'bulma-button bulma-is-primary'\n */\nexport function usePrefixedClassNames(\n ...args: (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[]\n): string {\n const { classPrefix } = useConfig();\n\n return prefixedClassNames(classPrefix, ...args);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { warnOnce } from './devWarnings.js';
|
|
3
|
+
|
|
4
|
+
// INTERNAL — deliberately not exported from src/index.ts.
|
|
5
|
+
/**
|
|
6
|
+
* Color values that emit an `is-<color>` modifier no shipped Bulma 1.0.4 rule
|
|
7
|
+
* matches on `.progress`/`.notification`/`.hero`. The `has-text-*` and
|
|
8
|
+
* `has-background-*` helpers DO cover these values — only the
|
|
9
|
+
* component-modifier form is dead.
|
|
10
|
+
*/
|
|
11
|
+
const UNSTYLED_MODIFIER_COLORS = [
|
|
12
|
+
'black-bis',
|
|
13
|
+
'black-ter',
|
|
14
|
+
'white-bis',
|
|
15
|
+
'white-ter',
|
|
16
|
+
'grey-darker',
|
|
17
|
+
'grey-dark',
|
|
18
|
+
'grey',
|
|
19
|
+
'grey-light',
|
|
20
|
+
'grey-lighter',
|
|
21
|
+
];
|
|
22
|
+
const CSS_BACKED = 'primary, link, info, success, warning, danger, black, white, light, dark';
|
|
23
|
+
/**
|
|
24
|
+
* Dev warning for a `color` value whose `is-<color>` modifier has no shipped
|
|
25
|
+
* CSS. `extraUnstyled` covers per-component dead values beyond the shared
|
|
26
|
+
* list (e.g. Hero's `inherit`/`current`).
|
|
27
|
+
*/
|
|
28
|
+
const warnUnstyledColor = (component, value, extraUnstyled = []) => {
|
|
29
|
+
if (!value)
|
|
30
|
+
return;
|
|
31
|
+
if (!UNSTYLED_MODIFIER_COLORS.includes(value) &&
|
|
32
|
+
!extraUnstyled.includes(value)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
warnOnce(`${component}:${value}`, `[bestax-bulma] <${component} color="${value}">: Bulma ships no ` +
|
|
36
|
+
`"is-${value}" CSS for ${component}, so it renders unstyled. This ` +
|
|
37
|
+
`value is deprecated and will be removed from the ${component} color ` +
|
|
38
|
+
`union in the next major version. CSS-backed values: ${CSS_BACKED}.`);
|
|
39
|
+
};
|
|
40
|
+
/** Dev warning for a `color` prop that has no shipped CSS for any value. */
|
|
41
|
+
const warnDeprecatedColorProp = (component, value, hint) => {
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
return;
|
|
44
|
+
warnOnce(`${component}:color-prop`, `[bestax-bulma] The ${component} "color" prop is deprecated: Bulma ` +
|
|
45
|
+
`ships no ${component.toLowerCase()} color CSS, so it has never had ` +
|
|
46
|
+
`a visual effect. It will be removed in the next major version. ${hint}`);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { UNSTYLED_MODIFIER_COLORS, warnDeprecatedColorProp, warnUnstyledColor };
|
|
50
|
+
//# sourceMappingURL=colorDeprecations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorDeprecations.js","sources":["../../../src/helpers/colorDeprecations.ts"],"sourcesContent":["// INTERNAL — deliberately not exported from src/index.ts.\n\nimport { resetDevWarnings, warnOnce } from './devWarnings';\n\n/**\n * Color values that emit an `is-<color>` modifier no shipped Bulma 1.0.4 rule\n * matches on `.progress`/`.notification`/`.hero`. The `has-text-*` and\n * `has-background-*` helpers DO cover these values — only the\n * component-modifier form is dead.\n */\nexport const UNSTYLED_MODIFIER_COLORS = [\n 'black-bis',\n 'black-ter',\n 'white-bis',\n 'white-ter',\n 'grey-darker',\n 'grey-dark',\n 'grey',\n 'grey-light',\n 'grey-lighter',\n] as const;\n\nconst CSS_BACKED =\n 'primary, link, info, success, warning, danger, black, white, light, dark';\n\n/**\n * Test-only: re-arm the warn-once registry. The registry lives in\n * `devWarnings`, shared with the other dev warnings, so this re-arms those too.\n */\nexport const resetColorDeprecationWarnings = resetDevWarnings;\n\n/**\n * Dev warning for a `color` value whose `is-<color>` modifier has no shipped\n * CSS. `extraUnstyled` covers per-component dead values beyond the shared\n * list (e.g. Hero's `inherit`/`current`).\n */\nexport const warnUnstyledColor = (\n component: string,\n value: string | undefined,\n extraUnstyled: readonly string[] = []\n): void => {\n if (!value) return;\n if (\n !(UNSTYLED_MODIFIER_COLORS as readonly string[]).includes(value) &&\n !extraUnstyled.includes(value)\n ) {\n return;\n }\n warnOnce(\n `${component}:${value}`,\n `[bestax-bulma] <${component} color=\"${value}\">: Bulma ships no ` +\n `\"is-${value}\" CSS for ${component}, so it renders unstyled. This ` +\n `value is deprecated and will be removed from the ${component} color ` +\n `union in the next major version. CSS-backed values: ${CSS_BACKED}.`\n );\n};\n\n/** Dev warning for a `color` prop that has no shipped CSS for any value. */\nexport const warnDeprecatedColorProp = (\n component: string,\n value: string | undefined,\n hint: string\n): void => {\n if (value === undefined) return;\n warnOnce(\n `${component}:color-prop`,\n `[bestax-bulma] The ${component} \"color\" prop is deprecated: Bulma ` +\n `ships no ${component.toLowerCase()} color CSS, so it has never had ` +\n `a visual effect. It will be removed in the next major version. ${hint}`\n );\n};\n"],"names":[],"mappings":";;;AAAA;AAIA;;;;;AAKG;AACI,MAAM,wBAAwB,GAAG;IACtC,WAAW;IACX,WAAW;IACX,WAAW;IACX,WAAW;IACX,aAAa;IACb,WAAW;IACX,MAAM;IACN,YAAY;IACZ,cAAc;;AAGhB,MAAM,UAAU,GACd,0EAA0E;AAQ5E;;;;AAIG;AACI,MAAM,iBAAiB,GAAG,CAC/B,SAAiB,EACjB,KAAyB,EACzB,aAAA,GAAmC,EAAE,KAC7B;AACR,IAAA,IAAI,CAAC,KAAK;QAAE;AACZ,IAAA,IACE,CAAE,wBAA8C,CAAC,QAAQ,CAAC,KAAK,CAAC;AAChE,QAAA,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC9B;QACA;IACF;IACA,QAAQ,CACN,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,EACvB,CAAA,gBAAA,EAAmB,SAAS,CAAA,QAAA,EAAW,KAAK,CAAA,mBAAA,CAAqB;QAC/D,CAAA,IAAA,EAAO,KAAK,CAAA,UAAA,EAAa,SAAS,CAAA,+BAAA,CAAiC;AACnE,QAAA,CAAA,iDAAA,EAAoD,SAAS,CAAA,OAAA,CAAS;QACtE,CAAA,oDAAA,EAAuD,UAAU,CAAA,CAAA,CAAG,CACvE;AACH;AAEA;AACO,MAAM,uBAAuB,GAAG,CACrC,SAAiB,EACjB,KAAyB,EACzB,IAAY,KACJ;IACR,IAAI,KAAK,KAAK,SAAS;QAAE;AACzB,IAAA,QAAQ,CACN,CAAA,EAAG,SAAS,aAAa,EACzB,CAAA,mBAAA,EAAsB,SAAS,CAAA,mCAAA,CAAqC;AAClE,QAAA,CAAA,SAAA,EAAY,SAAS,CAAC,WAAW,EAAE,CAAA,gCAAA,CAAkC;QACrE,CAAA,+DAAA,EAAkE,IAAI,CAAA,CAAE,CAC3E;AACH;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
// INTERNAL: deliberately not exported from src/index.ts.
|
|
3
|
+
const warnedKeys = new Set();
|
|
4
|
+
// Fail closed: with no bundler and no Node (raw CDN ESM), reading `process`
|
|
5
|
+
// throws and warnings stay off, so production can never warn by accident.
|
|
6
|
+
const isDev = () => {
|
|
7
|
+
try {
|
|
8
|
+
return process.env.NODE_ENV !== 'production';
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Logs a console warning in development, once per `key` for the life of the
|
|
16
|
+
* page. Safe to call during render: a re-render, or a second instance hitting
|
|
17
|
+
* the same case, finds the key already recorded and stays quiet.
|
|
18
|
+
*/
|
|
19
|
+
const warnOnce = (key, message) => {
|
|
20
|
+
if (!isDev() || warnedKeys.has(key))
|
|
21
|
+
return;
|
|
22
|
+
warnedKeys.add(key);
|
|
23
|
+
console.warn(message);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { warnOnce };
|
|
27
|
+
//# sourceMappingURL=devWarnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devWarnings.js","sources":["../../../src/helpers/devWarnings.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\n\nconst warnedKeys = new Set<string>();\n\n/** Test-only: re-arm the warn-once registry. */\nexport const resetDevWarnings = (): void => {\n warnedKeys.clear();\n};\n\n// Local declaration because the library tsconfig has no Node types. The\n// reference must stay a bare `process.env.NODE_ENV` so bundlers can replace\n// it statically.\ndeclare const process: { env: { NODE_ENV?: string } };\n\n// Fail closed: with no bundler and no Node (raw CDN ESM), reading `process`\n// throws and warnings stay off, so production can never warn by accident.\nconst isDev = (): boolean => {\n try {\n return process.env.NODE_ENV !== 'production';\n } catch {\n return false;\n }\n};\n\n/**\n * Logs a console warning in development, once per `key` for the life of the\n * page. Safe to call during render: a re-render, or a second instance hitting\n * the same case, finds the key already recorded and stays quiet.\n */\nexport const warnOnce = (key: string, message: string): void => {\n if (!isDev() || warnedKeys.has(key)) return;\n warnedKeys.add(key);\n console.warn(message);\n};\n"],"names":[],"mappings":";AAAA;AAEA,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU;AAYpC;AACA;AACA,MAAM,KAAK,GAAG,MAAc;AAC1B,IAAA,IAAI;AACF,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;IAC9C;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACF,CAAC;AAED;;;;AAIG;MACU,QAAQ,GAAG,CAAC,GAAW,EAAE,OAAe,KAAU;IAC7D,IAAI,CAAC,KAAK,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE;AACrC,IAAA,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;AACnB,IAAA,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AACvB;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
// INTERNAL: deliberately not exported from src/index.ts.
|
|
5
|
+
/** The major version of the React this bundle is running against. */
|
|
6
|
+
const runningMajor = () => Number(React.version.split('.')[0]);
|
|
7
|
+
/**
|
|
8
|
+
* The prop that makes an element inert, spelled for the React in use, or
|
|
9
|
+
* nothing when `inert` is false.
|
|
10
|
+
*
|
|
11
|
+
* Both majors must render `inert=""`, and each warns on the other's spelling
|
|
12
|
+
* and then drops the attribute. React 19 treats `inert` as a boolean and
|
|
13
|
+
* rejects the empty string. React 18 does not know the attribute, so it
|
|
14
|
+
* passes a string through and rejects `true`.
|
|
15
|
+
*/
|
|
16
|
+
const inertProps = (inert, major = runningMajor()) => {
|
|
17
|
+
if (!inert)
|
|
18
|
+
return {};
|
|
19
|
+
// The cast is for React 18's spelling: this package's types are React 19's,
|
|
20
|
+
// where `inert` is a boolean.
|
|
21
|
+
return (major >= 19
|
|
22
|
+
? { inert: true }
|
|
23
|
+
: { inert: '' });
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { inertProps };
|
|
27
|
+
//# sourceMappingURL=inertProps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inertProps.js","sources":["../../../src/helpers/inertProps.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport React from 'react';\n\n/** The major version of the React this bundle is running against. */\nconst runningMajor = (): number => Number(React.version.split('.')[0]);\n\n/**\n * The prop that makes an element inert, spelled for the React in use, or\n * nothing when `inert` is false.\n *\n * Both majors must render `inert=\"\"`, and each warns on the other's spelling\n * and then drops the attribute. React 19 treats `inert` as a boolean and\n * rejects the empty string. React 18 does not know the attribute, so it\n * passes a string through and rejects `true`.\n */\nexport const inertProps = (\n inert: boolean,\n major: number = runningMajor()\n): React.HTMLAttributes<HTMLElement> => {\n if (!inert) return {};\n // The cast is for React 18's spelling: this package's types are React 19's,\n // where `inert` is a boolean.\n return (major >= 19\n ? { inert: true }\n : { inert: '' }) as unknown as React.HTMLAttributes<HTMLElement>;\n};\n"],"names":[],"mappings":";;;AAAA;AAGA;AACA,MAAM,YAAY,GAAG,MAAc,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtE;;;;;;;;AAQG;AACI,MAAM,UAAU,GAAG,CACxB,KAAc,EACd,KAAA,GAAgB,YAAY,EAAE,KACO;AACrC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;;;IAGrB,QAAQ,KAAK,IAAI;AACf,UAAE,EAAE,KAAK,EAAE,IAAI;AACf,UAAE,EAAE,KAAK,EAAE,EAAE,EAAE;AACnB;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
/**
|
|
3
|
+
* Merges helper-emitted inline styles (e.g., `bulmaHelperStyles` from
|
|
4
|
+
* `useBulmaClasses`) with a user-supplied `style` prop.
|
|
5
|
+
*
|
|
6
|
+
* The user's `style` wins on conflicting properties, and when both inputs are
|
|
7
|
+
* absent the result is `undefined` — so components that receive neither
|
|
8
|
+
* render with no `style` attribute at all, exactly as before.
|
|
9
|
+
*
|
|
10
|
+
* @function mergeBulmaStyles
|
|
11
|
+
* @param helperStyles - Inline styles emitted by the Bulma helper hooks.
|
|
12
|
+
* @param style - The component consumer's `style` prop.
|
|
13
|
+
* @returns The merged style object, or `undefined` when both are absent.
|
|
14
|
+
* @example
|
|
15
|
+
* <section style={mergeBulmaStyles(bulmaHelperStyles, style)} />
|
|
16
|
+
*/
|
|
17
|
+
const mergeBulmaStyles = (helperStyles, style) => helperStyles || style ? { ...helperStyles, ...style } : undefined;
|
|
18
|
+
|
|
19
|
+
export { mergeBulmaStyles };
|
|
20
|
+
//# sourceMappingURL=mergeBulmaStyles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeBulmaStyles.js","sources":["../../../src/helpers/mergeBulmaStyles.ts"],"sourcesContent":["import type { CSSProperties } from 'react';\n\n/**\n * Merges helper-emitted inline styles (e.g., `bulmaHelperStyles` from\n * `useBulmaClasses`) with a user-supplied `style` prop.\n *\n * The user's `style` wins on conflicting properties, and when both inputs are\n * absent the result is `undefined` — so components that receive neither\n * render with no `style` attribute at all, exactly as before.\n *\n * @function mergeBulmaStyles\n * @param helperStyles - Inline styles emitted by the Bulma helper hooks.\n * @param style - The component consumer's `style` prop.\n * @returns The merged style object, or `undefined` when both are absent.\n * @example\n * <section style={mergeBulmaStyles(bulmaHelperStyles, style)} />\n */\nexport const mergeBulmaStyles = (\n helperStyles?: CSSProperties,\n style?: CSSProperties\n): CSSProperties | undefined =>\n helperStyles || style ? { ...helperStyles, ...style } : undefined;\n"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;AAcG;AACI,MAAM,gBAAgB,GAAG,CAC9B,YAA4B,EAC5B,KAAqB,KAErB,YAAY,IAAI,KAAK,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,EAAE,GAAG;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
/**
|
|
3
|
+
* Whether an `as` target is a custom element rather than a built-in tag.
|
|
4
|
+
*
|
|
5
|
+
* HTML requires a custom element's name to contain a hyphen, and no built-in
|
|
6
|
+
* element name has one, so this is exact rather than a heuristic. It matters
|
|
7
|
+
* because a custom element is an intrinsic STRING — `typeof as === 'string'` is
|
|
8
|
+
* true — while its props are whatever a consumer declared through
|
|
9
|
+
* `React.JSX.IntrinsicElements`, the way this package declares `<ion-icon>`.
|
|
10
|
+
* A runtime backstop that filters built-in attributes must leave those alone,
|
|
11
|
+
* or it strips props the derived type just promised to forward.
|
|
12
|
+
*/
|
|
13
|
+
function isCustomElement(as) {
|
|
14
|
+
return typeof as === 'string' && as.includes('-');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { isCustomElement };
|
|
18
|
+
//# sourceMappingURL=polymorphic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polymorphic.js","sources":["../../../src/helpers/polymorphic.ts"],"sourcesContent":["import type React from 'react';\n\n/**\n * Whether an `as` target is a custom element rather than a built-in tag.\n *\n * HTML requires a custom element's name to contain a hyphen, and no built-in\n * element name has one, so this is exact rather than a heuristic. It matters\n * because a custom element is an intrinsic STRING — `typeof as === 'string'` is\n * true — while its props are whatever a consumer declared through\n * `React.JSX.IntrinsicElements`, the way this package declares `<ion-icon>`.\n * A runtime backstop that filters built-in attributes must leave those alone,\n * or it strips props the derived type just promised to forward.\n */\nexport function isCustomElement(as: unknown): as is string {\n return typeof as === 'string' && as.includes('-');\n}\n\n/**\n * The ref type of whatever element `as` renders.\n *\n * Derived from `ComponentPropsWithRef` rather than `React.ComponentRef` so it\n * resolves on every `@types/react` a consumer may be on: this package supports\n * React 18 and 19, and the CI matrix pins only `react`/`react-dom`, never the\n * types, so a types-only regression here would not be caught.\n *\n * `never` when the target takes no ref. A plain function component has no `ref`\n * key at all, and React's own types reject `<PlainFC ref={…} />`; without the\n * guard the indexed access degraded to `unknown` and we accepted a ref that\n * silently does nothing — `ref.current` stays null and a later `.focus()`\n * throws. Matching React's strictness is the point.\n */\nexport type PolymorphicRef<T extends React.ElementType> =\n 'ref' extends keyof React.ComponentPropsWithRef<T>\n ? React.ComponentPropsWithRef<T>['ref']\n : never;\n\n/**\n * A component's own props, plus the attributes of the element `as` names.\n *\n * `Own` wins a collision by default — a component that declares\n * `color` as a Bulma variant keeps it, rather than inheriting the DOM attribute\n * of the same name. `color` used to be dropped here as well, to stop the\n * deprecated presentational HTML attribute reaching the components whose own\n * props do not declare one — but doing it in the shared type also stripped\n * `color` from a CUSTOM target that legitimately has one. Those components\n * declare `color?: never` themselves instead, which lands in `keyof Own` and\n * reaches the same result without a special case here.\n *\n * `Forwarded` names the own props the component hands STRAIGHT to the target\n * instead of consuming, and the subtraction runs the other way for them: the\n * TARGET's declaration wins, and the own one is what covers a target that has\n * no such prop. Subtracting them threw the target's declaration away, so an\n * OPTIONAL own prop hid a REQUIRED one — `<Avatar as={NextLink} name=\"Ada\" />`\n * compiled because Avatar's `href?: string` survived while `next/link`'s\n * required `href` was omitted, and the target threw on what it never received\n * (#665). The target wins rather than both declarations applying at once,\n * because for a prop the component only passes along its own type has no\n * standing: `next/link` accepts a URL object as well as a string, and\n * intersecting Avatar's `string` with that would refuse the object.\n *\n * `Forwarded` defaults to `never`, so a prop the component CONSUMES stays\n * subtracted — the common case, and the one `color` needs. What that costs is\n * that a target REQUIRING a consumed prop is still satisfiable with the prop\n * omitted, and the value goes wherever the component sends it: `Menu.Item`\n * spends several of its own props on its wrapping `<li>`, `title` and `style`\n * among them, so a target requiring one of those never sees it. Erroring on\n * that needs a category this pair cannot express, since `className` is consumed\n * too and yet every component composes one and passes it on. It is pinned as a\n * limitation in `__typetests__/polymorphic.tsx` rather than guessed at here.\n *\n * `Own` is returned untouched when nothing is forwarded, rather than run through\n * an `Omit` that names no keys. `Omit` is not the identity it looks like: it\n * keys off `keyof Own`, which for a UNION `Own` is only what the members share,\n * so `PolymorphicProps<'div', A | B>` lost every prop of both. It is public API\n * and a consumer's wrapper can pass a union; the untouched branch also keeps\n * each own prop's TSDoc reaching an IDE, which a mapped type drops. The\n * forwarded branch distributes over `Own` for the same reason.\n *\n * Distributive over `T` on purpose. `Omit<A | B, K>` keys off `keyof (A | B)`,\n * which is only what A and B share — so a union-typed `as` (a ternary, or a\n * variable typed `'a' | 'button'`) silently lost every prop that belongs to\n * just one member, `href` among them. Distributing produces a union of prop\n * shapes instead, and each member keeps its own.\n *\n * Each component writes this intersection out in its own `*Props` alias rather\n * than referring to this type: the API-docs extractor\n * (`scripts/lib/props-extract.mjs`) walks heritage syntactically, and a generic\n * alias leaves it resolving a type parameter it cannot see through.\n * This type is here for the component's cast target and for consumers writing\n * wrappers.\n */\nexport type PolymorphicProps<\n T extends React.ElementType,\n Own,\n Forwarded extends keyof Own = never,\n> = T extends unknown\n ? ([Forwarded] extends [never]\n ? Own\n : Own extends unknown\n ? Omit<Own, Extract<Forwarded, keyof React.ComponentPropsWithoutRef<T>>>\n : never) &\n Omit<\n React.ComponentPropsWithoutRef<T>,\n Exclude<keyof Own, Forwarded> | 'as'\n > & {\n /** The element or component to render. */\n as?: T;\n }\n : never;\n\n/**\n * A component whose props and forwarded ref both follow `as`.\n *\n * `forwardRef` cannot express a generic component, so the implementation is\n * cast to this. `displayName` is part of the type because the library sets it\n * on every `forwardRef` component, and `withSubComponents` constrains its base\n * to `{ displayName?: string }`.\n *\n * The second, non-generic signature exists for type DERIVATION rather than for\n * calls. `React.ComponentProps<typeof Button>` infers from the last overload;\n * with only the generic one it instantiated at the constraint and collapsed to\n * `any`, so a consumer building their own prop type on ours lost every check.\n * Calls still resolve against the generic signature first, so ordering here is\n * load-bearing — swapping the two puts the collapse back.\n *\n * **A wrapping HOC erases the genericity.** `React.memo(Button)`,\n * `React.lazy`, a `styled()` wrapper — anything that infers its props through\n * `ComponentProps<T>` — instantiates the type parameter once and hands back a\n * component with a single prop type. It takes the LAST call signature, which is\n * the derivation overload, so the wrapper is pinned to the DEFAULT element:\n * `React.memo(Button)` rejects `as=\"div\"` outright, and `React.memo(Dropdown.Item)`\n * renders neither a `<div>` nor a `<button>`, though both components accept those\n * directly. Stricter, not looser — the checks do not stop, they collapse onto one\n * element, and a `Dropdown.Item` memoized for a long menu list is the case that\n * meets it. This is inherent to polymorphic components in TypeScript, not\n * something this library can fix. Re-assert the type to get the rest back:\n *\n * ```tsx\n * const MemoButton = React.memo(Button) as typeof Button;\n * ```\n */\nexport interface PolymorphicComponent<\n Own,\n Default extends React.ElementType,\n Forwarded extends keyof Own = never,\n> {\n <T extends React.ElementType = Default>(\n props: PolymorphicProps<T, Own, Forwarded> & { ref?: PolymorphicRef<T> }\n ): React.ReactElement | null;\n (\n props: PolymorphicProps<Default, Own, Forwarded> & {\n ref?: PolymorphicRef<Default>;\n }\n ): React.ReactElement | null;\n displayName?: string;\n}\n\n/**\n * A component whose props follow `as` but which forwards no ref.\n *\n * For components that own the node they observe — `Reveal` keeps its own ref on\n * the element it watches for scroll intersection, which is not always the\n * element `as` names.\n *\n * It carries `Forwarded` even with no component passing one today: the default\n * is the behaviour without it, and a component that grows a forwarded own prop\n * would otherwise reintroduce #665 here with nothing to say so.\n */\nexport interface PolymorphicComponentWithoutRef<\n Own,\n Default extends React.ElementType,\n Forwarded extends keyof Own = never,\n> {\n <T extends React.ElementType = Default>(\n props: PolymorphicProps<T, Own, Forwarded>\n ): React.ReactElement | null;\n // The same derivation overload `PolymorphicComponent` carries, for the same\n // reason: without it `React.ComponentProps<typeof Reveal>` instantiates at the\n // constraint and collapses to `any`.\n (props: PolymorphicProps<Default, Own, Forwarded>): React.ReactElement | null;\n displayName?: string;\n}\n\n/**\n * A component whose props follow `as`, where `as` is a closed set of tags.\n *\n * `PolymorphicComponentWithoutRef` lets `as` name anything; this narrows it to\n * `Allowed`. Bulma pins some elements by its own markup contract — a dropdown\n * item is an `<a>`, a `<div>` or a `<button>` and nothing else — and the\n * constraint keeps that promise while still deriving props from whichever of\n * the three a caller picks.\n *\n * Genericity is what makes the derivation exact for a LITERAL `as`, and it is\n * worth the extra type parameter. Typing such a component as `React.FC<Union>`\n * instead — a union of the three prop shapes — reads as equivalent but is not:\n * against a union target, an object literal's excess-property check passes if\n * the property exists in ANY member, so `<Item as=\"div\" href=\"/x\" />` slips\n * through. Inferring `T` from the literal checks against that one member.\n *\n * A UNION-typed `as` — a ternary, or a variable typed as the whole set — infers\n * `T` as the union and lands back in that same permissive check, so\n * `<Item as={tag} href=\"/x\" />` compiles whatever `tag` turns out to be. That is\n * the open `as` behaviour too, and deliberate there: `PolymorphicProps`\n * distributes precisely so a union-typed `as` KEEPS each member's props rather\n * than losing every prop the members do not share. Narrowing it is not a\n * constrained-component question; it would have to change for `Button` first.\n */\nexport interface ConstrainedPolymorphicComponentWithoutRef<\n Own,\n Allowed extends React.ElementType,\n Default extends Allowed,\n Forwarded extends keyof Own = never,\n> {\n <T extends Allowed = Default>(\n props: PolymorphicProps<T, Own, Forwarded>\n ): React.ReactElement | null;\n // The derivation overload `PolymorphicComponent` documents, for the same\n // reason: without it `React.ComponentProps<typeof DropdownItem>` instantiates\n // at the constraint and collapses to `any`.\n (props: PolymorphicProps<Default, Own, Forwarded>): React.ReactElement | null;\n displayName?: string;\n}\n"],"names":[],"mappings":";AAEA;;;;;;;;;;AAUG;AACG,SAAU,eAAe,CAAC,EAAW,EAAA;IACzC,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;AACnD;;"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { useIsHydrated } from './useIsHydrated.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolves a portal target: an `HTMLElement` is used directly, a non-empty
|
|
8
|
+
* `string` is treated as a `document.querySelector` selector (falling back to
|
|
9
|
+
* `document.body` when it matches nothing), and any falsy value — `undefined`
|
|
10
|
+
* or the empty string — resolves to `document.body`.
|
|
11
|
+
*
|
|
12
|
+
* The empty string is deliberately treated as "no target" rather than passed
|
|
13
|
+
* through: `document.querySelector('')` throws a `SyntaxError`, and callers
|
|
14
|
+
* building a selector from state can easily hand us `''`.
|
|
15
|
+
*
|
|
16
|
+
* @function resolvePortalContainer
|
|
17
|
+
* @param container - The requested portal target, if any.
|
|
18
|
+
* @returns The resolved DOM node to portal into.
|
|
19
|
+
*/
|
|
20
|
+
function resolvePortalContainer(container) {
|
|
21
|
+
if (!container) {
|
|
22
|
+
return document.body;
|
|
23
|
+
}
|
|
24
|
+
if (typeof container === 'string') {
|
|
25
|
+
return (document.querySelector(container) ?? document.body);
|
|
26
|
+
}
|
|
27
|
+
return container;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Renders its children into another part of the page, `document.body` unless `container` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.
|
|
31
|
+
*
|
|
32
|
+
* React's server renderer can't render a portal, so `Portal` renders nothing
|
|
33
|
+
* on the server and during hydration, and mounts its children in the commit
|
|
34
|
+
* that follows. The first client render then matches the server markup. In an app
|
|
35
|
+
* without server rendering it portals on the first render.
|
|
36
|
+
*
|
|
37
|
+
* React context, such as `ConfigProvider`'s class prefix, reaches the
|
|
38
|
+
* portaled children, and their React events bubble through the React tree.
|
|
39
|
+
* CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`
|
|
40
|
+
* sets its variables on a wrapper element the portaled content has left, so
|
|
41
|
+
* that content sees the page-level theme. Point `container` at an element
|
|
42
|
+
* inside the themed area to keep it.
|
|
43
|
+
*
|
|
44
|
+
* Tab order and focus follow the DOM too. Content portaled from inside a
|
|
45
|
+
* focus trap is no longer inside the trapped element, so the trap neither
|
|
46
|
+
* reaches it nor holds focus there: render nested overlays inside the
|
|
47
|
+
* trapped element, or give them a trap of their own. To trap portaled
|
|
48
|
+
* content, put `useFocusTrap`'s ref on the element inside the `Portal`.
|
|
49
|
+
*
|
|
50
|
+
* @function
|
|
51
|
+
* @param {PortalProps} props - Props for the Portal component.
|
|
52
|
+
* @returns The portal, the children in place when `disabled`, or nothing
|
|
53
|
+
* before hydration.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* <Portal>
|
|
57
|
+
* <div className="box">Rendered at the end of document.body</div>
|
|
58
|
+
* </Portal>
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Into a dedicated overlay root
|
|
62
|
+
* <Portal container="#overlays">
|
|
63
|
+
* <CommandPalette />
|
|
64
|
+
* </Portal>
|
|
65
|
+
*/
|
|
66
|
+
function Portal({ children, container, disabled = false }) {
|
|
67
|
+
const hydrated = useIsHydrated();
|
|
68
|
+
if (disabled)
|
|
69
|
+
return jsx(Fragment, { children: children });
|
|
70
|
+
if (!hydrated)
|
|
71
|
+
return null;
|
|
72
|
+
return createPortal(children, resolvePortalContainer(container));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { Portal, resolvePortalContainer };
|
|
76
|
+
//# sourceMappingURL=portal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.js","sources":["../../../src/helpers/portal.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIsHydrated } from './useIsHydrated';\n\n/**\n * Resolves a portal target: an `HTMLElement` is used directly, a non-empty\n * `string` is treated as a `document.querySelector` selector (falling back to\n * `document.body` when it matches nothing), and any falsy value — `undefined`\n * or the empty string — resolves to `document.body`.\n *\n * The empty string is deliberately treated as \"no target\" rather than passed\n * through: `document.querySelector('')` throws a `SyntaxError`, and callers\n * building a selector from state can easily hand us `''`.\n *\n * @function resolvePortalContainer\n * @param container - The requested portal target, if any.\n * @returns The resolved DOM node to portal into.\n */\nexport function resolvePortalContainer(\n container?: string | HTMLElement\n): HTMLElement {\n if (!container) {\n return document.body;\n }\n if (typeof container === 'string') {\n return (\n (document.querySelector(container) as HTMLElement | null) ?? document.body\n );\n }\n return container;\n}\n\n/**\n * Props for the Portal component.\n */\nexport interface PortalProps {\n /** Content to render into the container. */\n children?: React.ReactNode;\n /**\n * Where the content goes: an element, or a `document.querySelector`\n * selector. Omitted, empty, or a selector that matches nothing, it goes to\n * `document.body`. A selector is looked up again on each render, so the\n * content follows the target when it changes. Moving to another target\n * remounts the children and resets their state, which includes a selector\n * that only starts matching after the content has shown in `document.body`.\n * Render the target first, or pass the element once you have it.\n */\n container?: string | HTMLElement;\n /**\n * Render the children in place instead, on the server as well as the\n * client. Lets a component that portals only sometimes keep a single code\n * path.\n * @defaultValue false\n */\n disabled?: boolean;\n}\n\n/**\n * Renders its children into another part of the page, `document.body` unless `container` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.\n *\n * React's server renderer can't render a portal, so `Portal` renders nothing\n * on the server and during hydration, and mounts its children in the commit\n * that follows. The first client render then matches the server markup. In an app\n * without server rendering it portals on the first render.\n *\n * React context, such as `ConfigProvider`'s class prefix, reaches the\n * portaled children, and their React events bubble through the React tree.\n * CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`\n * sets its variables on a wrapper element the portaled content has left, so\n * that content sees the page-level theme. Point `container` at an element\n * inside the themed area to keep it.\n *\n * Tab order and focus follow the DOM too. Content portaled from inside a\n * focus trap is no longer inside the trapped element, so the trap neither\n * reaches it nor holds focus there: render nested overlays inside the\n * trapped element, or give them a trap of their own. To trap portaled\n * content, put `useFocusTrap`'s ref on the element inside the `Portal`.\n *\n * @function\n * @param {PortalProps} props - Props for the Portal component.\n * @returns The portal, the children in place when `disabled`, or nothing\n * before hydration.\n *\n * @example\n * <Portal>\n * <div className=\"box\">Rendered at the end of document.body</div>\n * </Portal>\n *\n * @example\n * // Into a dedicated overlay root\n * <Portal container=\"#overlays\">\n * <CommandPalette />\n * </Portal>\n */\nexport function Portal({ children, container, disabled = false }: PortalProps) {\n const hydrated = useIsHydrated();\n if (disabled) return <>{children}</>;\n if (!hydrated) return null;\n return createPortal(children, resolvePortalContainer(container));\n}\n"],"names":["_jsx","_Fragment"],"mappings":";;;;;AAIA;;;;;;;;;;;;;AAaG;AACG,SAAU,sBAAsB,CACpC,SAAgC,EAAA;IAEhC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,QAAQ,CAAC,IAAI;IACtB;AACA,IAAA,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;AACjC,QAAA,QACG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAwB,IAAI,QAAQ,CAAC,IAAI;IAE9E;AACA,IAAA,OAAO,SAAS;AAClB;AA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCG;AACG,SAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,EAAe,EAAA;AAC3E,IAAA,MAAM,QAAQ,GAAG,aAAa,EAAE;AAChC,IAAA,IAAI,QAAQ;QAAE,OAAOA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAI;AACpC,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,IAAI;IAC1B,OAAO,YAAY,CAAC,QAAQ,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;AAClE;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
/**
|
|
3
|
+
* Splits the items a container shows into one stack per position in use. An
|
|
4
|
+
* item goes to its own position when it has one and to the container's
|
|
5
|
+
* otherwise. A position with no items gets no stack.
|
|
6
|
+
*
|
|
7
|
+
* Stacks come back in `order`, so their order in the page follows the screen
|
|
8
|
+
* rather than which position happened to be used first, and a stack keeps its
|
|
9
|
+
* place while the others come and go. A position missing from `order` sorts
|
|
10
|
+
* after the known ones.
|
|
11
|
+
*
|
|
12
|
+
* @function groupIntoPositionStacks
|
|
13
|
+
* @param items - The items the container shows, in the order they were shown.
|
|
14
|
+
* @param positionOf - Reads an item's own position, if it has one.
|
|
15
|
+
* @param containerPosition - Where an item without a position of its own goes.
|
|
16
|
+
* @param order - Every known position, in the order stacks should render.
|
|
17
|
+
* @returns One stack per position in use.
|
|
18
|
+
*/
|
|
19
|
+
function groupIntoPositionStacks(items, positionOf, containerPosition, order) {
|
|
20
|
+
const byPosition = new Map();
|
|
21
|
+
for (const item of items) {
|
|
22
|
+
const position = positionOf(item) ?? containerPosition;
|
|
23
|
+
const stack = byPosition.get(position);
|
|
24
|
+
if (stack) {
|
|
25
|
+
stack.push(item);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
byPosition.set(position, [item]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const rank = (position) => {
|
|
32
|
+
const index = order.indexOf(position);
|
|
33
|
+
return index === -1 ? order.length : index;
|
|
34
|
+
};
|
|
35
|
+
// Array.prototype.sort is stable, so unknown positions keep the order they
|
|
36
|
+
// were first used in.
|
|
37
|
+
return Array.from(byPosition, ([position, stackItems]) => ({
|
|
38
|
+
key: position === containerPosition ? 'container' : `at-${position}`,
|
|
39
|
+
position,
|
|
40
|
+
items: stackItems,
|
|
41
|
+
})).sort((a, b) => rank(a.position) - rank(b.position));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { groupIntoPositionStacks };
|
|
45
|
+
//# sourceMappingURL=positionStacks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positionStacks.js","sources":["../../../src/helpers/positionStacks.ts"],"sourcesContent":["/**\n * The items a programmatic container shows at one place on the screen.\n */\nexport interface PositionStack<Item, Position extends string> {\n /**\n * A React key for the stack. The stack at the container's own position\n * keeps the same key whatever that position is, so changing the container's\n * `position` moves the items in it instead of remounting them.\n */\n key: string;\n /** Where on the screen the stack sits. */\n position: Position;\n /** The items at that position, in the order they were shown. */\n items: Item[];\n}\n\n/**\n * Splits the items a container shows into one stack per position in use. An\n * item goes to its own position when it has one and to the container's\n * otherwise. A position with no items gets no stack.\n *\n * Stacks come back in `order`, so their order in the page follows the screen\n * rather than which position happened to be used first, and a stack keeps its\n * place while the others come and go. A position missing from `order` sorts\n * after the known ones.\n *\n * @function groupIntoPositionStacks\n * @param items - The items the container shows, in the order they were shown.\n * @param positionOf - Reads an item's own position, if it has one.\n * @param containerPosition - Where an item without a position of its own goes.\n * @param order - Every known position, in the order stacks should render.\n * @returns One stack per position in use.\n */\nexport function groupIntoPositionStacks<Item, Position extends string>(\n items: readonly Item[],\n positionOf: (item: Item) => Position | undefined,\n containerPosition: Position,\n order: readonly Position[]\n): PositionStack<Item, Position>[] {\n const byPosition = new Map<Position, Item[]>();\n for (const item of items) {\n const position = positionOf(item) ?? containerPosition;\n const stack = byPosition.get(position);\n if (stack) {\n stack.push(item);\n } else {\n byPosition.set(position, [item]);\n }\n }\n\n const rank = (position: Position) => {\n const index = order.indexOf(position);\n return index === -1 ? order.length : index;\n };\n\n // Array.prototype.sort is stable, so unknown positions keep the order they\n // were first used in.\n return Array.from(byPosition, ([position, stackItems]) => ({\n key: position === containerPosition ? 'container' : `at-${position}`,\n position,\n items: stackItems,\n })).sort((a, b) => rank(a.position) - rank(b.position));\n}\n"],"names":[],"mappings":";AAgBA;;;;;;;;;;;;;;;;AAgBG;AACG,SAAU,uBAAuB,CACrC,KAAsB,EACtB,UAAgD,EAChD,iBAA2B,EAC3B,KAA0B,EAAA;AAE1B,IAAA,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB;AAC9C,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAiB;QACtD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;QACtC,IAAI,KAAK,EAAE;AACT,YAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAClB;aAAO;YACL,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;QAClC;IACF;AAEA,IAAA,MAAM,IAAI,GAAG,CAAC,QAAkB,KAAI;QAClC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;AACrC,QAAA,OAAO,KAAK,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK;AAC5C,IAAA,CAAC;;;AAID,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM;AACzD,QAAA,GAAG,EAAE,QAAQ,KAAK,iBAAiB,GAAG,WAAW,GAAG,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAE;QACpE,QAAQ;AACR,QAAA,KAAK,EAAE,UAAU;KAClB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACzD;;"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
// Ref-counted across every caller (e.g. a Dialog rendering its own Modal)
|
|
5
|
+
// so overlapping/nested locks don't fight over which one restores `overflow`.
|
|
6
|
+
// Every overlay that locks body scroll — Modal, Dialog, Sidebar, Loading —
|
|
7
|
+
// goes through here; a component setting `document.body.style.overflow`
|
|
8
|
+
// itself would clear a lock another overlay still needs.
|
|
9
|
+
let lockCount = 0;
|
|
10
|
+
let originalOverflow = '';
|
|
11
|
+
/**
|
|
12
|
+
* Locks (and ref-counted-ly unlocks) `document.body` scrolling while `active`
|
|
13
|
+
* is true. Safe to call from multiple components at once — the body scroll
|
|
14
|
+
* is only restored once every active caller has released its lock.
|
|
15
|
+
*
|
|
16
|
+
* @function useScrollLock
|
|
17
|
+
* @param active - Whether this caller wants the body scroll locked.
|
|
18
|
+
*/
|
|
19
|
+
function useScrollLock(active) {
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!active)
|
|
22
|
+
return undefined;
|
|
23
|
+
lockCount++;
|
|
24
|
+
if (lockCount === 1) {
|
|
25
|
+
originalOverflow = document.body.style.overflow;
|
|
26
|
+
document.body.style.overflow = 'hidden';
|
|
27
|
+
}
|
|
28
|
+
return () => {
|
|
29
|
+
lockCount--;
|
|
30
|
+
if (lockCount === 0) {
|
|
31
|
+
document.body.style.overflow = originalOverflow;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}, [active]);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { useScrollLock };
|
|
38
|
+
//# sourceMappingURL=scrollLock.js.map
|