@allxsmith/bestax-bulma 5.27.0 → 5.27.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/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 +90 -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 +88 -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 +77 -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 +88 -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 +167 -0
- package/dist/esm/form/Field.js.map +1 -0
- package/dist/esm/form/File.js +112 -0
- package/dist/esm/form/File.js.map +1 -0
- package/dist/esm/form/FormContext.js +194 -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 +201 -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 +92 -0
- package/dist/esm/form/Radios.js.map +1 -0
- package/dist/esm/form/Rate.js +280 -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 +461 -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 +351 -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 +84 -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 +88 -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 +187 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +115 -17516
- package/dist/index.esm.js.map +1 -1
- package/dist/types/elements/Icon.d.ts +10 -7
- package/dist/types/form/Autocomplete.d.ts +1 -1
- package/dist/types/form/Checkboxes.d.ts +1 -1
- package/dist/types/form/DateInput.d.ts +1 -1
- package/dist/types/form/DateInputBase.d.ts +3 -4
- package/dist/types/form/DateRangeInput.d.ts +1 -1
- package/dist/types/form/DateTimeInput.d.ts +1 -1
- package/dist/types/form/DateTimeInputBase.d.ts +3 -4
- package/dist/types/form/Field.d.ts +2 -2
- package/dist/types/form/File.d.ts +4 -4
- package/dist/types/form/FormContext.d.ts +24 -2
- package/dist/types/form/Numberinput.d.ts +1 -1
- package/dist/types/form/Radios.d.ts +1 -1
- package/dist/types/form/Rate.d.ts +1 -1
- package/dist/types/form/Slider.d.ts +1 -1
- package/dist/types/form/Taginput.d.ts +1 -1
- package/dist/types/form/TimeInput.d.ts +1 -1
- package/dist/types/form/useAutoLabelId.d.ts +25 -4
- package/dist/types/helpers/Config.d.ts +3 -4
- package/dist/types/helpers/Theme.d.ts +44 -40
- package/dist/types-cjs/elements/Icon.d.ts +10 -7
- package/dist/types-cjs/form/Autocomplete.d.ts +1 -1
- package/dist/types-cjs/form/Checkboxes.d.ts +1 -1
- package/dist/types-cjs/form/DateInput.d.ts +1 -1
- package/dist/types-cjs/form/DateInputBase.d.ts +3 -4
- package/dist/types-cjs/form/DateRangeInput.d.ts +1 -1
- package/dist/types-cjs/form/DateTimeInput.d.ts +1 -1
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +3 -4
- package/dist/types-cjs/form/Field.d.ts +2 -2
- package/dist/types-cjs/form/File.d.ts +4 -4
- package/dist/types-cjs/form/FormContext.d.ts +24 -2
- package/dist/types-cjs/form/Numberinput.d.ts +1 -1
- package/dist/types-cjs/form/Radios.d.ts +1 -1
- package/dist/types-cjs/form/Rate.d.ts +1 -1
- package/dist/types-cjs/form/Slider.d.ts +1 -1
- package/dist/types-cjs/form/Taginput.d.ts +1 -1
- package/dist/types-cjs/form/TimeInput.d.ts +1 -1
- package/dist/types-cjs/form/useAutoLabelId.d.ts +25 -4
- package/dist/types-cjs/helpers/Config.d.ts +3 -4
- package/dist/types-cjs/helpers/Theme.d.ts +44 -40
- 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/form/_dateinput.scss +37 -6
- package/src/scss/form/_datetimeinput.scss +7 -2
- package/src/scss/form/_picker-popover.scss +1 -4
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { forwardRef, useRef, useCallback, useEffect } from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
6
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
7
|
+
import { withSubComponents } from '../helpers/withSubComponents.js';
|
|
8
|
+
import { useScrollLock } from '../helpers/scrollLock.js';
|
|
9
|
+
import { buttonType } from '../helpers/buttonType.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The `Sidebar` component provides a slide-out navigation panel that appears from the left or right side of the screen.
|
|
13
|
+
*
|
|
14
|
+
* @function
|
|
15
|
+
* @param {SidebarProps} props - Props for the Sidebar component.
|
|
16
|
+
* @param {React.Ref<HTMLElement>} ref - Forwarded ref to the sidebar element.
|
|
17
|
+
* @returns {JSX.Element | null} The rendered sidebar component.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Basic sidebar
|
|
21
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
22
|
+
* <Sidebar isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
23
|
+
* <Menu>...</Menu>
|
|
24
|
+
* </Sidebar>
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Right-side sidebar with custom width
|
|
28
|
+
* <Sidebar
|
|
29
|
+
* isOpen={isOpen}
|
|
30
|
+
* onClose={() => setIsOpen(false)}
|
|
31
|
+
* position="right"
|
|
32
|
+
* width="320px"
|
|
33
|
+
* >
|
|
34
|
+
* <div>Panel content</div>
|
|
35
|
+
* </Sidebar>
|
|
36
|
+
*/
|
|
37
|
+
const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width = '260px', isFullwidth, fullWidth, overlay = true, overlayClose = true, escapeClose = true, canCancel = true, children, inline = false, className, style, ...props }, ref) => {
|
|
38
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
39
|
+
const sidebarRef = useRef(null);
|
|
40
|
+
// Cleanup returned by a consumer's callback ref on attach, held until detach.
|
|
41
|
+
const consumerCleanupRef = useRef(null);
|
|
42
|
+
const resolvedFullwidth = isFullwidth ?? fullWidth ?? false;
|
|
43
|
+
// Close handler
|
|
44
|
+
const handleClose = useCallback(() => {
|
|
45
|
+
if (canCancel && onClose) {
|
|
46
|
+
onClose();
|
|
47
|
+
}
|
|
48
|
+
}, [canCancel, onClose]);
|
|
49
|
+
// Handle overlay click
|
|
50
|
+
const handleOverlayClick = useCallback(() => {
|
|
51
|
+
if (overlayClose) {
|
|
52
|
+
handleClose();
|
|
53
|
+
}
|
|
54
|
+
}, [overlayClose, handleClose]);
|
|
55
|
+
// Handle escape key
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!isOpen || !escapeClose)
|
|
58
|
+
return;
|
|
59
|
+
const handleKeyDown = (e) => {
|
|
60
|
+
if (e.key === 'Escape') {
|
|
61
|
+
handleClose();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
65
|
+
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
66
|
+
}, [isOpen, escapeClose, handleClose]);
|
|
67
|
+
// Prevent body scroll when sidebar is open. Ref-counted through the shared
|
|
68
|
+
// helper so an overlapping Modal/Dialog/Loading doesn't unlock underneath.
|
|
69
|
+
useScrollLock(isOpen && overlay);
|
|
70
|
+
// Focus trap (basic - focus sidebar when opened)
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (isOpen) {
|
|
73
|
+
const element = sidebarRef.current;
|
|
74
|
+
if (element) {
|
|
75
|
+
// Focus first focusable element or sidebar itself
|
|
76
|
+
const focusable = element.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
77
|
+
if (focusable) {
|
|
78
|
+
focusable.focus();
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
element.focus();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, [isOpen]);
|
|
86
|
+
// Use combined ref
|
|
87
|
+
const combinedRef = useCallback((node) => {
|
|
88
|
+
sidebarRef.current =
|
|
89
|
+
node;
|
|
90
|
+
if (typeof ref === 'function') {
|
|
91
|
+
// React 19 lets a callback ref return a cleanup function and detaches by
|
|
92
|
+
// running it instead of calling the ref with `null`; React 18 discards the
|
|
93
|
+
// return value entirely. Returning it from here would be a React-19-only
|
|
94
|
+
// contract, so we hold the cleanup and run it ourselves on detach — the
|
|
95
|
+
// same shape as `Dropdown`, `Modal`, `Dialog`, `Toast` and `Carousel`.
|
|
96
|
+
// The form controls that merge a forwarded ref still discard the cleanup
|
|
97
|
+
// and detach with `ref(null)`, so this is not yet library-wide — grep
|
|
98
|
+
// `typeof ref === 'function'` for the current split.
|
|
99
|
+
if (node === null) {
|
|
100
|
+
const consumerCleanup = consumerCleanupRef.current;
|
|
101
|
+
consumerCleanupRef.current = null;
|
|
102
|
+
if (consumerCleanup) {
|
|
103
|
+
consumerCleanup();
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
ref(null);
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const cleanup = ref(node);
|
|
111
|
+
consumerCleanupRef.current =
|
|
112
|
+
typeof cleanup === 'function' ? cleanup : null;
|
|
113
|
+
}
|
|
114
|
+
else if (ref) {
|
|
115
|
+
ref.current = node;
|
|
116
|
+
}
|
|
117
|
+
}, [ref]);
|
|
118
|
+
// Generate classes
|
|
119
|
+
const sidebarClasses = usePrefixedClassNames('sidebar', {
|
|
120
|
+
'is-active': isOpen,
|
|
121
|
+
[`is-${position}`]: position,
|
|
122
|
+
'is-fullwidth': resolvedFullwidth,
|
|
123
|
+
});
|
|
124
|
+
const backgroundClass = usePrefixedClassNames('sidebar-background', {
|
|
125
|
+
'is-active': isOpen,
|
|
126
|
+
});
|
|
127
|
+
const contentClass = usePrefixedClassNames('sidebar-content');
|
|
128
|
+
const combinedClasses = classNames(sidebarClasses, bulmaHelperClasses, className);
|
|
129
|
+
// Custom style for width
|
|
130
|
+
const sidebarStyle = {
|
|
131
|
+
...style,
|
|
132
|
+
'--bulma-sidebar-width': resolvedFullwidth ? '100%' : width,
|
|
133
|
+
};
|
|
134
|
+
const sidebarContent = (jsxs(Fragment, { children: [overlay && (jsx("div", { className: backgroundClass, onClick: handleOverlayClick, "aria-hidden": "true" })), jsx("aside", { ref: combinedRef, className: combinedClasses, style: sidebarStyle, role: "dialog", "aria-modal": overlay ? 'true' : undefined, "aria-hidden": !isOpen, tabIndex: -1, ...rest, children: jsx("div", { className: contentClass, children: children }) })] }));
|
|
135
|
+
if (inline) {
|
|
136
|
+
return sidebarContent;
|
|
137
|
+
}
|
|
138
|
+
// Render to portal for proper stacking
|
|
139
|
+
if (typeof document !== 'undefined') {
|
|
140
|
+
return createPortal(sidebarContent, document.body);
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
});
|
|
144
|
+
/**
|
|
145
|
+
* Container for the sidebar header.
|
|
146
|
+
*
|
|
147
|
+
* @function
|
|
148
|
+
* @param {SidebarHeaderProps} props - Props for the SidebarHeader component.
|
|
149
|
+
* @returns {JSX.Element} The rendered sidebar header.
|
|
150
|
+
*/
|
|
151
|
+
const SidebarHeader = ({ className, children, ...props }) => {
|
|
152
|
+
const headerClass = usePrefixedClassNames('sidebar-header');
|
|
153
|
+
return (jsx("div", { className: classNames(headerClass, className), ...props, children: children }));
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Title text inside the header.
|
|
157
|
+
*
|
|
158
|
+
* @function
|
|
159
|
+
* @param {SidebarTitleProps} props - Props for the SidebarTitle component.
|
|
160
|
+
* @returns {JSX.Element} The rendered sidebar title.
|
|
161
|
+
*/
|
|
162
|
+
const SidebarTitle = ({ className, children, ...props }) => {
|
|
163
|
+
const titleClass = usePrefixedClassNames('sidebar-title');
|
|
164
|
+
return (jsx("p", { className: classNames(titleClass, className), ...props, children: children }));
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Close button for the sidebar.
|
|
168
|
+
*
|
|
169
|
+
* @function
|
|
170
|
+
* @param {SidebarCloseProps} props - Props for the SidebarClose component.
|
|
171
|
+
* @returns {JSX.Element} The rendered close button.
|
|
172
|
+
*/
|
|
173
|
+
const SidebarClose = ({ className, children, ...props }) => {
|
|
174
|
+
const closeClass = usePrefixedClassNames('sidebar-close');
|
|
175
|
+
return (jsx("button", { className: classNames(closeClass, className), ...props, "aria-label": props['aria-label'] || 'Close', type: buttonType(props.type), children: children }));
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Main content area of the sidebar.
|
|
179
|
+
*
|
|
180
|
+
* @function
|
|
181
|
+
* @param {SidebarBodyProps} props - Props for the SidebarBody component.
|
|
182
|
+
* @returns {JSX.Element} The rendered sidebar body.
|
|
183
|
+
*/
|
|
184
|
+
const SidebarBody = ({ className, children, ...props }) => {
|
|
185
|
+
const bodyClass = usePrefixedClassNames('sidebar-body');
|
|
186
|
+
return (jsx("div", { className: classNames(bodyClass, className), ...props, children: children }));
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Footer area of the sidebar.
|
|
190
|
+
*
|
|
191
|
+
* @function
|
|
192
|
+
* @param {SidebarFooterProps} props - Props for the SidebarFooter component.
|
|
193
|
+
* @returns {JSX.Element} The rendered sidebar footer.
|
|
194
|
+
*/
|
|
195
|
+
const SidebarFooter = ({ className, children, ...props }) => {
|
|
196
|
+
const footerClass = usePrefixedClassNames('sidebar-footer');
|
|
197
|
+
return (jsx("div", { className: classNames(footerClass, className), ...props, children: children }));
|
|
198
|
+
};
|
|
199
|
+
// Attach static subcomponents
|
|
200
|
+
const Sidebar = withSubComponents(SidebarComponent, {
|
|
201
|
+
Header: SidebarHeader,
|
|
202
|
+
Title: SidebarTitle,
|
|
203
|
+
Close: SidebarClose,
|
|
204
|
+
Body: SidebarBody,
|
|
205
|
+
Footer: SidebarFooter,
|
|
206
|
+
}, 'Sidebar');
|
|
207
|
+
|
|
208
|
+
export { Sidebar };
|
|
209
|
+
//# sourceMappingURL=Sidebar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sidebar.js","sources":["../../../src/components/Sidebar.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useCallback, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useScrollLock } from '../helpers/scrollLock';\nimport { buttonType } from '../helpers/buttonType';\n\n/** Position of the sidebar relative to the viewport. */\nexport type SidebarPosition = 'left' | 'right';\n\n/**\n * Props for the Sidebar component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the sidebar element.\n */\nexport interface SidebarProps\n extends\n Omit<React.HTMLAttributes<HTMLElement>, 'children' | 'color'>,\n BulmaClassesProps {\n /** Whether the sidebar is open (required). */\n isOpen: boolean;\n /** Callback when sidebar should close. */\n onClose?: () => void;\n /** Which side the sidebar appears from. Default: 'left'. */\n position?: SidebarPosition;\n /** Custom width of the sidebar. */\n width?: string;\n /** Sidebar takes full width (mobile-style). */\n isFullwidth?: boolean;\n /** Sidebar takes full width (mobile-style). @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n fullWidth?: boolean;\n /** Show overlay behind sidebar. Default: true. */\n overlay?: boolean;\n /** Close sidebar when overlay is clicked. Default: true. */\n overlayClose?: boolean;\n /** Close sidebar on Escape key. Default: true. */\n escapeClose?: boolean;\n /** Allow closing the sidebar. Default: true. */\n canCancel?: boolean;\n /** Content to display in the sidebar. */\n children?: React.ReactNode;\n /** Renders inline instead of using a portal. */\n inline?: boolean;\n}\n\n/**\n * The `Sidebar` component provides a slide-out navigation panel that appears from the left or right side of the screen.\n *\n * @function\n * @param {SidebarProps} props - Props for the Sidebar component.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the sidebar element.\n * @returns {JSX.Element | null} The rendered sidebar component.\n *\n * @example\n * // Basic sidebar\n * const [isOpen, setIsOpen] = useState(false);\n * <Sidebar isOpen={isOpen} onClose={() => setIsOpen(false)}>\n * <Menu>...</Menu>\n * </Sidebar>\n *\n * @example\n * // Right-side sidebar with custom width\n * <Sidebar\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * position=\"right\"\n * width=\"320px\"\n * >\n * <div>Panel content</div>\n * </Sidebar>\n */\nconst SidebarComponent = forwardRef<HTMLElement, SidebarProps>(\n (\n {\n isOpen,\n onClose,\n position = 'left',\n width = '260px',\n isFullwidth,\n fullWidth,\n overlay = true,\n overlayClose = true,\n escapeClose = true,\n canCancel = true,\n children,\n inline = false,\n className,\n style,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const sidebarRef = useRef<HTMLElement>(null);\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const resolvedFullwidth = isFullwidth ?? fullWidth ?? false;\n\n // Close handler\n const handleClose = useCallback(() => {\n if (canCancel && onClose) {\n onClose();\n }\n }, [canCancel, onClose]);\n\n // Handle overlay click\n const handleOverlayClick = useCallback(() => {\n if (overlayClose) {\n handleClose();\n }\n }, [overlayClose, handleClose]);\n\n // Handle escape key\n useEffect(() => {\n if (!isOpen || !escapeClose) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, escapeClose, handleClose]);\n\n // Prevent body scroll when sidebar is open. Ref-counted through the shared\n // helper so an overlapping Modal/Dialog/Loading doesn't unlock underneath.\n useScrollLock(isOpen && overlay);\n\n // Focus trap (basic - focus sidebar when opened)\n useEffect(() => {\n if (isOpen) {\n const element = sidebarRef.current;\n if (element) {\n // Focus first focusable element or sidebar itself\n const focusable = element.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable) {\n focusable.focus();\n } else {\n element.focus();\n }\n }\n }\n }, [isOpen]);\n\n // Use combined ref\n const combinedRef = useCallback(\n (node: HTMLElement | null) => {\n (sidebarRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches by\n // running it instead of calling the ref with `null`; React 18 discards the\n // return value entirely. Returning it from here would be a React-19-only\n // contract, so we hold the cleanup and run it ourselves on detach — the\n // same shape as `Dropdown`, `Modal`, `Dialog`, `Toast` and `Carousel`.\n // The form controls that merge a forwarded ref still discard the cleanup\n // and detach with `ref(null)`, so this is not yet library-wide — grep\n // `typeof ref === 'function'` for the current split.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLElement | null>).current = node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const sidebarClasses = usePrefixedClassNames('sidebar', {\n 'is-active': isOpen,\n [`is-${position}`]: position,\n 'is-fullwidth': resolvedFullwidth,\n });\n const backgroundClass = usePrefixedClassNames('sidebar-background', {\n 'is-active': isOpen,\n });\n const contentClass = usePrefixedClassNames('sidebar-content');\n\n const combinedClasses = classNames(\n sidebarClasses,\n bulmaHelperClasses,\n className\n );\n\n // Custom style for width\n const sidebarStyle: React.CSSProperties = {\n ...style,\n '--bulma-sidebar-width': resolvedFullwidth ? '100%' : width,\n } as React.CSSProperties;\n\n const sidebarContent = (\n <>\n {overlay && (\n <div\n className={backgroundClass}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <aside\n ref={combinedRef}\n className={combinedClasses}\n style={sidebarStyle}\n role=\"dialog\"\n aria-modal={overlay ? 'true' : undefined}\n aria-hidden={!isOpen}\n tabIndex={-1}\n {...rest}\n >\n <div className={contentClass}>{children}</div>\n </aside>\n </>\n );\n\n if (inline) {\n return sidebarContent;\n }\n\n // Render to portal for proper stacking\n if (typeof document !== 'undefined') {\n return createPortal(sidebarContent, document.body);\n }\n\n return null;\n }\n);\n\n// Sub-components\n\n/**\n * Props for the SidebarHeader component.\n */\ninterface SidebarHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Header content. */\n children?: React.ReactNode;\n}\n\n/**\n * Container for the sidebar header.\n *\n * @function\n * @param {SidebarHeaderProps} props - Props for the SidebarHeader component.\n * @returns {JSX.Element} The rendered sidebar header.\n */\nconst SidebarHeader: React.FC<SidebarHeaderProps> = ({\n className,\n children,\n ...props\n}) => {\n const headerClass = usePrefixedClassNames('sidebar-header');\n return (\n <div className={classNames(headerClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n/**\n * Props for the SidebarTitle component.\n */\ninterface SidebarTitleProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Title content. */\n children?: React.ReactNode;\n}\n\n/**\n * Title text inside the header.\n *\n * @function\n * @param {SidebarTitleProps} props - Props for the SidebarTitle component.\n * @returns {JSX.Element} The rendered sidebar title.\n */\nconst SidebarTitle: React.FC<SidebarTitleProps> = ({\n className,\n children,\n ...props\n}) => {\n const titleClass = usePrefixedClassNames('sidebar-title');\n return (\n <p className={classNames(titleClass, className)} {...props}>\n {children}\n </p>\n );\n};\n\n/**\n * Props for the SidebarClose component.\n * Extends standard button attributes.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a close button inside a form does not submit it. Pass `'submit'` or `'reset'` and yours is used; any other value, or a spread carrying `type: undefined`, renders `'button'`.\n * @extraProp {string} [aria-label='Close'] - Accessible name. Pass your own to replace it. An empty one, or a spread carrying `'aria-label': undefined`, keeps the default rather than leaving the button unnamed.\n */\ntype SidebarCloseProps = React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Close button for the sidebar.\n *\n * @function\n * @param {SidebarCloseProps} props - Props for the SidebarClose component.\n * @returns {JSX.Element} The rendered close button.\n */\nconst SidebarClose: React.FC<SidebarCloseProps> = ({\n className,\n children,\n ...props\n}) => {\n const closeClass = usePrefixedClassNames('sidebar-close');\n return (\n <button\n className={classNames(closeClass, className)}\n {...props}\n // After the spread, reading through it: a key the spread carries with no\n // value would otherwise erase the default, leaving a nameless button\n // that submits the form around it. An empty label falls back too: the\n // button is drawn as an icon, so `''` would leave it unnamed. A caller's\n // own value still wins; `buttonType` says more.\n aria-label={props['aria-label'] || 'Close'}\n type={buttonType(props.type)}\n >\n {children}\n </button>\n );\n};\n\n/**\n * Props for the SidebarBody component.\n */\ninterface SidebarBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Body content. */\n children?: React.ReactNode;\n}\n\n/**\n * Main content area of the sidebar.\n *\n * @function\n * @param {SidebarBodyProps} props - Props for the SidebarBody component.\n * @returns {JSX.Element} The rendered sidebar body.\n */\nconst SidebarBody: React.FC<SidebarBodyProps> = ({\n className,\n children,\n ...props\n}) => {\n const bodyClass = usePrefixedClassNames('sidebar-body');\n return (\n <div className={classNames(bodyClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n/**\n * Props for the SidebarFooter component.\n */\ninterface SidebarFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content. */\n children?: React.ReactNode;\n}\n\n/**\n * Footer area of the sidebar.\n *\n * @function\n * @param {SidebarFooterProps} props - Props for the SidebarFooter component.\n * @returns {JSX.Element} The rendered sidebar footer.\n */\nconst SidebarFooter: React.FC<SidebarFooterProps> = ({\n className,\n children,\n ...props\n}) => {\n const footerClass = usePrefixedClassNames('sidebar-footer');\n return (\n <div className={classNames(footerClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n// Attach static subcomponents\nexport const Sidebar = withSubComponents(\n SidebarComponent,\n {\n Header: SidebarHeader,\n Title: SidebarTitle,\n Close: SidebarClose,\n Body: SidebarBody,\n Footer: SidebarFooter,\n },\n 'Sidebar'\n);\n\nexport default Sidebar;\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":";;;;;;;;;;AA8CA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;AACH,MAAM,gBAAgB,GAAG,UAAU,CACjC,CACE,EACE,MAAM,EACN,OAAO,EACP,QAAQ,GAAG,MAAM,EACjB,KAAK,GAAG,OAAO,EACf,WAAW,EACX,SAAS,EACT,OAAO,GAAG,IAAI,EACd,YAAY,GAAG,IAAI,EACnB,WAAW,GAAG,IAAI,EAClB,SAAS,GAAG,IAAI,EAChB,QAAQ,EACR,MAAM,GAAG,KAAK,EACd,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EACD,GAAG,KACD;IACF,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC;AAC3D,IAAA,MAAM,UAAU,GAAG,MAAM,CAAc,IAAI,CAAC;;AAE5C,IAAA,MAAM,kBAAkB,GAAG,MAAM,CAAsB,IAAI,CAAC;AAC5D,IAAA,MAAM,iBAAiB,GAAG,WAAW,IAAI,SAAS,IAAI,KAAK;;AAG3D,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,MAAK;AACnC,QAAA,IAAI,SAAS,IAAI,OAAO,EAAE;AACxB,YAAA,OAAO,EAAE;QACX;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;;AAGxB,IAAA,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAK;QAC1C,IAAI,YAAY,EAAE;AAChB,YAAA,WAAW,EAAE;QACf;AACF,IAAA,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;;IAG/B,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW;YAAE;AAE7B,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI;AACzC,YAAA,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE;AACtB,gBAAA,WAAW,EAAE;YACf;AACF,QAAA,CAAC;AAED,QAAA,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC;QACnD,OAAO,MAAM,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC;IACrE,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;;;AAItC,IAAA,aAAa,CAAC,MAAM,IAAI,OAAO,CAAC;;IAGhC,SAAS,CAAC,MAAK;QACb,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;YAClC,IAAI,OAAO,EAAE;;gBAEX,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CACrC,0EAA0E,CAC3E;gBACD,IAAI,SAAS,EAAE;oBACb,SAAS,CAAC,KAAK,EAAE;gBACnB;qBAAO;oBACL,OAAO,CAAC,KAAK,EAAE;gBACjB;YACF;QACF;AACF,IAAA,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;;AAGZ,IAAA,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,IAAwB,KAAI;AAC1B,QAAA,UAAyD,CAAC,OAAO;AAChE,YAAA,IAAI;AACN,QAAA,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;;;;;;;;;AAS7B,YAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACjB,gBAAA,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO;AAClD,gBAAA,kBAAkB,CAAC,OAAO,GAAG,IAAI;gBACjC,IAAI,eAAe,EAAE;AACnB,oBAAA,eAAe,EAAE;gBACnB;qBAAO;oBACL,GAAG,CAAC,IAAI,CAAC;gBACX;gBACA;YACF;AACA,YAAA,MAAM,OAAO,GAAY,GAAG,CAAC,IAAI,CAAC;AAClC,YAAA,kBAAkB,CAAC,OAAO;gBACxB,OAAO,OAAO,KAAK,UAAU,GAAI,OAAsB,GAAG,IAAI;QAClE;aAAO,IAAI,GAAG,EAAE;AACb,YAAA,GAAkD,CAAC,OAAO,GAAG,IAAI;QACpE;AACF,IAAA,CAAC,EACD,CAAC,GAAG,CAAC,CACN;;AAGD,IAAA,MAAM,cAAc,GAAG,qBAAqB,CAAC,SAAS,EAAE;AACtD,QAAA,WAAW,EAAE,MAAM;AACnB,QAAA,CAAC,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAE,GAAG,QAAQ;AAC5B,QAAA,cAAc,EAAE,iBAAiB;AAClC,KAAA,CAAC;AACF,IAAA,MAAM,eAAe,GAAG,qBAAqB,CAAC,oBAAoB,EAAE;AAClE,QAAA,WAAW,EAAE,MAAM;AACpB,KAAA,CAAC;AACF,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,iBAAiB,CAAC;IAE7D,MAAM,eAAe,GAAG,UAAU,CAChC,cAAc,EACd,kBAAkB,EAClB,SAAS,CACV;;AAGD,IAAA,MAAM,YAAY,GAAwB;AACxC,QAAA,GAAG,KAAK;QACR,uBAAuB,EAAE,iBAAiB,GAAG,MAAM,GAAG,KAAK;KACrC;AAExB,IAAA,MAAM,cAAc,IAClBA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,OAAO,KACNC,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,kBAAkB,EAAA,aAAA,EACf,MAAM,EAAA,CAClB,CACH,EACDA,GAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAC,QAAQ,EAAA,YAAA,EACD,OAAO,GAAG,MAAM,GAAG,SAAS,EAAA,aAAA,EAC3B,CAAC,MAAM,EACpB,QAAQ,EAAE,EAAE,EAAA,GACR,IAAI,EAAA,QAAA,EAERA,aAAK,SAAS,EAAE,YAAY,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAO,EAAA,CACxC,CAAA,EAAA,CACP,CACJ;IAED,IAAI,MAAM,EAAE;AACV,QAAA,OAAO,cAAc;IACvB;;AAGA,IAAA,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;QACnC,OAAO,YAAY,CAAC,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC;IACpD;AAEA,IAAA,OAAO,IAAI;AACb,CAAC,CACF;AAYD;;;;;;AAMG;AACH,MAAM,aAAa,GAAiC,CAAC,EACnD,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,WAAW,GAAG,qBAAqB,CAAC,gBAAgB,CAAC;AAC3D,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,KAAM,KAAK,EAAA,QAAA,EAC1D,QAAQ,EAAA,CACL;AAEV,CAAC;AAUD;;;;;;AAMG;AACH,MAAM,YAAY,GAAgC,CAAC,EACjD,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,eAAe,CAAC;AACzD,IAAA,QACEA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,KAAM,KAAK,EAAA,QAAA,EACvD,QAAQ,EAAA,CACP;AAER,CAAC;AAUD;;;;;;AAMG;AACH,MAAM,YAAY,GAAgC,CAAC,EACjD,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,eAAe,CAAC;AACzD,IAAA,QACEA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,EAAA,GACxC,KAAK,EAAA,YAAA,EAMG,KAAK,CAAC,YAAY,CAAC,IAAI,OAAO,EAC1C,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAA,QAAA,EAE3B,QAAQ,EAAA,CACF;AAEb,CAAC;AAUD;;;;;;AAMG;AACH,MAAM,WAAW,GAA+B,CAAC,EAC/C,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,cAAc,CAAC;AACvD,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,KAAM,KAAK,EAAA,QAAA,EACxD,QAAQ,EAAA,CACL;AAEV,CAAC;AAUD;;;;;;AAMG;AACH,MAAM,aAAa,GAAiC,CAAC,EACnD,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,WAAW,GAAG,qBAAqB,CAAC,gBAAgB,CAAC;AAC3D,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,KAAM,KAAK,EAAA,QAAA,EAC1D,QAAQ,EAAA,CACL;AAEV,CAAC;AAED;AACO,MAAM,OAAO,GAAG,iBAAiB,CACtC,gBAAgB,EAChB;AACE,IAAA,MAAM,EAAE,aAAa;AACrB,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,IAAI,EAAE,WAAW;AACjB,IAAA,MAAM,EAAE,aAAa;CACtB,EACD,SAAS;;"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { classNames, usePrefixedClassNames } from '../helpers/classNames.js';
|
|
5
|
+
import { withSubComponents } from '../helpers/withSubComponents.js';
|
|
6
|
+
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Individual Step component for use inside Steps.
|
|
10
|
+
*
|
|
11
|
+
* @function
|
|
12
|
+
* @param {StepProps} props - Props for the Step component.
|
|
13
|
+
* @returns {JSX.Element} The rendered step segment.
|
|
14
|
+
*/
|
|
15
|
+
const Step = ({ isActive = false, isCompleted = false, label, icon, clickable = false, onClick, stepNumber, completedIcon, className, children, ...props }) => {
|
|
16
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
17
|
+
const stepClasses = classNames(usePrefixedClassNames('steps-segment', {
|
|
18
|
+
'is-active': isActive,
|
|
19
|
+
'is-completed': isCompleted,
|
|
20
|
+
}), bulmaHelperClasses, className);
|
|
21
|
+
const stepsLinkClass = usePrefixedClassNames('steps-link');
|
|
22
|
+
const stepsMarkerClass = usePrefixedClassNames('steps-marker');
|
|
23
|
+
const stepsContentClass = usePrefixedClassNames('steps-content');
|
|
24
|
+
const stepsTitleClass = usePrefixedClassNames('steps-title');
|
|
25
|
+
const handleClick = () => {
|
|
26
|
+
if (clickable && onClick) {
|
|
27
|
+
onClick();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const handleKeyDown = (e) => {
|
|
31
|
+
if (clickable && onClick && (e.key === 'Enter' || e.key === ' ')) {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
onClick();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const resolvedCompletedIcon = completedIcon === undefined ? '\u2713' : completedIcon;
|
|
37
|
+
const markerContent = icon ||
|
|
38
|
+
(isCompleted && resolvedCompletedIcon
|
|
39
|
+
? resolvedCompletedIcon
|
|
40
|
+
: (stepNumber ?? null));
|
|
41
|
+
return (jsx("li", { className: stepClasses, onClick: handleClick, onKeyDown: handleKeyDown, tabIndex: clickable ? 0 : undefined, role: clickable ? 'button' : undefined, "aria-current": isActive ? 'step' : undefined, ...rest, children: jsxs("div", { className: stepsLinkClass, children: [jsx("span", { className: stepsMarkerClass, children: markerContent }), (label || children) && (jsx("div", { className: stepsContentClass, children: jsx("p", { className: stepsTitleClass, children: label || children }) }))] }) }));
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The `Steps` component provides a multi-step progress indicator for wizard flows, checkout processes, or any multi-step workflow.
|
|
45
|
+
*
|
|
46
|
+
* @function
|
|
47
|
+
* @param {StepsProps} props - Props for the Steps component.
|
|
48
|
+
* @returns {JSX.Element} The rendered steps component.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Basic steps with items
|
|
52
|
+
* <Steps
|
|
53
|
+
* value={1}
|
|
54
|
+
* items={[
|
|
55
|
+
* { label: 'Account' },
|
|
56
|
+
* { label: 'Profile' },
|
|
57
|
+
* { label: 'Complete' },
|
|
58
|
+
* ]}
|
|
59
|
+
* />
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Clickable steps with navigation
|
|
63
|
+
* <Steps
|
|
64
|
+
* value={currentStep}
|
|
65
|
+
* onStepClick={(step) => setCurrentStep(step)}
|
|
66
|
+
* hasNavigation
|
|
67
|
+
* items={[
|
|
68
|
+
* { label: 'Step 1', clickable: true },
|
|
69
|
+
* { label: 'Step 2', clickable: true },
|
|
70
|
+
* { label: 'Step 3', clickable: true },
|
|
71
|
+
* ]}
|
|
72
|
+
* />
|
|
73
|
+
*/
|
|
74
|
+
const StepsComponent = ({ value = 0, items, size, color, hasMarker = true, animated = true, rounded = true, vertical = false, labelPosition = 'bottom', mobileMode, showStepNumbers = true, hasNavigation = false, prevLabel, nextLabel, onPrev, onNext, onStepClick, className, children, ...props }) => {
|
|
75
|
+
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
76
|
+
// Generate classes for the wrapper div
|
|
77
|
+
const stepsClasses = usePrefixedClassNames('steps', {
|
|
78
|
+
[`is-${size}`]: size,
|
|
79
|
+
[`is-${color}`]: color,
|
|
80
|
+
'has-marker': hasMarker,
|
|
81
|
+
'is-animated': animated,
|
|
82
|
+
'is-rounded': rounded,
|
|
83
|
+
'is-vertical': vertical,
|
|
84
|
+
[`has-label-${labelPosition}`]: labelPosition && (labelPosition !== 'bottom' || vertical),
|
|
85
|
+
[`is-${mobileMode}`]: mobileMode,
|
|
86
|
+
});
|
|
87
|
+
const combinedClasses = classNames(stepsClasses, bulmaHelperClasses, className);
|
|
88
|
+
// Generate classes for the ul (list)
|
|
89
|
+
const listClasses = usePrefixedClassNames('steps-list', {
|
|
90
|
+
'is-vertical': vertical,
|
|
91
|
+
});
|
|
92
|
+
const stepsNavigationClass = usePrefixedClassNames('steps-navigation');
|
|
93
|
+
const prevButtonClass = usePrefixedClassNames('button');
|
|
94
|
+
const nextButtonClass = usePrefixedClassNames('button', {
|
|
95
|
+
'is-primary': true,
|
|
96
|
+
});
|
|
97
|
+
// Count total steps for navigation
|
|
98
|
+
const totalSteps = items ? items.length : React.Children.count(children);
|
|
99
|
+
// Render items if provided
|
|
100
|
+
const renderSteps = () => {
|
|
101
|
+
if (items && items.length > 0) {
|
|
102
|
+
return items.map((item, index) => (jsx(Step, { isActive: index === value, isCompleted: index < value, label: item.label, icon: item.icon, completedIcon: item.completedIcon, clickable: item.clickable, stepNumber: showStepNumbers ? index + 1 : undefined, onClick: item.clickable && onStepClick ? () => onStepClick(index) : undefined, className: item.className }, index)));
|
|
103
|
+
}
|
|
104
|
+
// If children are provided, clone them with active/completed states
|
|
105
|
+
if (children) {
|
|
106
|
+
return React.Children.map(children, (child, index) => {
|
|
107
|
+
if (React.isValidElement(child)) {
|
|
108
|
+
return React.cloneElement(child, {
|
|
109
|
+
isActive: index === value,
|
|
110
|
+
isCompleted: index < value,
|
|
111
|
+
stepNumber: showStepNumbers ? index + 1 : undefined,
|
|
112
|
+
onClick: child.props.clickable && onStepClick
|
|
113
|
+
? () => onStepClick(index)
|
|
114
|
+
: child.props.onClick,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return child;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
return (jsxs("div", { className: combinedClasses, ...rest, children: [jsx("ul", { className: listClasses, children: renderSteps() }), hasNavigation && (jsxs("div", { className: stepsNavigationClass, children: [jsx("button", { type: "button", className: prevButtonClass, disabled: value === 0, onClick: onPrev ?? (() => onStepClick?.(value - 1)), children: prevLabel ?? 'Previous' }), jsx("button", { type: "button", className: nextButtonClass, disabled: value === totalSteps - 1, onClick: onNext ?? (() => onStepClick?.(value + 1)), children: nextLabel ?? 'Next' })] }))] }));
|
|
123
|
+
};
|
|
124
|
+
// Attach Step as static property
|
|
125
|
+
const Steps = withSubComponents(StepsComponent, { Step }, 'Steps');
|
|
126
|
+
|
|
127
|
+
export { Step, Steps };
|
|
128
|
+
//# sourceMappingURL=Steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Steps.js","sources":["../../../src/components/Steps.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\n\n/** Available size modifiers for the Steps component. */\nexport type StepsSize = 'small' | 'medium' | 'large';\n/** Available color variants for the Steps component. */\nexport type StepsColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * Props for individual Step items.\n */\nexport interface StepItemProps {\n /** Step label/title */\n label?: React.ReactNode;\n /** Icon for the step marker */\n icon?: React.ReactNode;\n /**\n * Icon shown when the step is completed.\n * @defaultValue '✓'\n */\n completedIcon?: React.ReactNode;\n /** Whether this step is clickable */\n clickable?: boolean;\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for the Steps component.\n * @extraProp {React.ReactNode} [children] - Step children (alternative to items).\n * @extraProp {string} [className] - Additional CSS classes.\n */\nexport interface StepsProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Current active step (0-indexed). */\n value?: number;\n /** Array of step items. */\n items?: StepItemProps[];\n /** Size of the steps. */\n size?: StepsSize;\n /** Color variant. */\n color?: StepsColor;\n /** Show step markers. Default: true. */\n hasMarker?: boolean;\n /** Enable animations. Default: true. */\n animated?: boolean;\n /** Use rounded markers. Default: true. */\n rounded?: boolean;\n /** Vertical layout. */\n vertical?: boolean;\n /** Position of labels. */\n labelPosition?: 'bottom' | 'right' | 'left';\n /** Mobile display mode. */\n mobileMode?: 'minimal' | 'compact' | 'right';\n /** Displays step numbers in the markers. */\n showStepNumbers?: boolean;\n /**\n * Shows previous/next navigation buttons. They render `type=\"button\"`, so a\n * multi-step form wrapped around the steps is not submitted by moving\n * between them.\n */\n hasNavigation?: boolean;\n /** Label for the previous button. */\n prevLabel?: string;\n /** Label for the next button. */\n nextLabel?: string;\n /** Callback when previous button is clicked. */\n onPrev?: () => void;\n /** Callback when next button is clicked. */\n onNext?: () => void;\n /** Callback when a step is clicked. */\n onStepClick?: (step: number) => void;\n}\n\n/**\n * Props for the Step subcomponent.\n */\nexport interface StepProps\n extends\n Omit<React.LiHTMLAttributes<HTMLLIElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Whether this step is active */\n isActive?: boolean;\n /** Whether this step is completed */\n isCompleted?: boolean;\n /** Step label/title */\n label?: React.ReactNode;\n /** Icon for the step marker */\n icon?: React.ReactNode;\n /** Whether this step is clickable */\n clickable?: boolean;\n /** Click handler */\n onClick?: () => void;\n /** Step number to display in marker (1-indexed) */\n stepNumber?: number;\n /**\n * Icon shown when the step is completed.\n * @defaultValue '✓'\n */\n completedIcon?: React.ReactNode;\n}\n\n/**\n * Individual Step component for use inside Steps.\n *\n * @function\n * @param {StepProps} props - Props for the Step component.\n * @returns {JSX.Element} The rendered step segment.\n */\nexport const Step: React.FC<StepProps> = ({\n isActive = false,\n isCompleted = false,\n label,\n icon,\n clickable = false,\n onClick,\n stepNumber,\n completedIcon,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n const stepClasses = classNames(\n usePrefixedClassNames('steps-segment', {\n 'is-active': isActive,\n 'is-completed': isCompleted,\n }),\n bulmaHelperClasses,\n className\n );\n const stepsLinkClass = usePrefixedClassNames('steps-link');\n const stepsMarkerClass = usePrefixedClassNames('steps-marker');\n const stepsContentClass = usePrefixedClassNames('steps-content');\n const stepsTitleClass = usePrefixedClassNames('steps-title');\n\n const handleClick = () => {\n if (clickable && onClick) {\n onClick();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (clickable && onClick && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onClick();\n }\n };\n\n const resolvedCompletedIcon =\n completedIcon === undefined ? '\\u2713' : completedIcon;\n const markerContent =\n icon ||\n (isCompleted && resolvedCompletedIcon\n ? resolvedCompletedIcon\n : (stepNumber ?? null));\n\n return (\n <li\n className={stepClasses}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n tabIndex={clickable ? 0 : undefined}\n role={clickable ? 'button' : undefined}\n aria-current={isActive ? 'step' : undefined}\n {...rest}\n >\n <div className={stepsLinkClass}>\n <span className={stepsMarkerClass}>{markerContent}</span>\n {(label || children) && (\n <div className={stepsContentClass}>\n <p className={stepsTitleClass}>{label || children}</p>\n </div>\n )}\n </div>\n </li>\n );\n};\n\n/**\n * The `Steps` component provides a multi-step progress indicator for wizard flows, checkout processes, or any multi-step workflow.\n *\n * @function\n * @param {StepsProps} props - Props for the Steps component.\n * @returns {JSX.Element} The rendered steps component.\n *\n * @example\n * // Basic steps with items\n * <Steps\n * value={1}\n * items={[\n * { label: 'Account' },\n * { label: 'Profile' },\n * { label: 'Complete' },\n * ]}\n * />\n *\n * @example\n * // Clickable steps with navigation\n * <Steps\n * value={currentStep}\n * onStepClick={(step) => setCurrentStep(step)}\n * hasNavigation\n * items={[\n * { label: 'Step 1', clickable: true },\n * { label: 'Step 2', clickable: true },\n * { label: 'Step 3', clickable: true },\n * ]}\n * />\n */\nconst StepsComponent: React.FC<StepsProps> = ({\n value = 0,\n items,\n size,\n color,\n hasMarker = true,\n animated = true,\n rounded = true,\n vertical = false,\n labelPosition = 'bottom',\n mobileMode,\n showStepNumbers = true,\n hasNavigation = false,\n prevLabel,\n nextLabel,\n onPrev,\n onNext,\n onStepClick,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n // Generate classes for the wrapper div\n const stepsClasses = usePrefixedClassNames('steps', {\n [`is-${size}`]: size,\n [`is-${color}`]: color,\n 'has-marker': hasMarker,\n 'is-animated': animated,\n 'is-rounded': rounded,\n 'is-vertical': vertical,\n [`has-label-${labelPosition}`]:\n labelPosition && (labelPosition !== 'bottom' || vertical),\n [`is-${mobileMode}`]: mobileMode,\n });\n\n const combinedClasses = classNames(\n stepsClasses,\n bulmaHelperClasses,\n className\n );\n\n // Generate classes for the ul (list)\n const listClasses = usePrefixedClassNames('steps-list', {\n 'is-vertical': vertical,\n });\n const stepsNavigationClass = usePrefixedClassNames('steps-navigation');\n const prevButtonClass = usePrefixedClassNames('button');\n const nextButtonClass = usePrefixedClassNames('button', {\n 'is-primary': true,\n });\n\n // Count total steps for navigation\n const totalSteps = items ? items.length : React.Children.count(children);\n\n // Render items if provided\n const renderSteps = () => {\n if (items && items.length > 0) {\n return items.map((item, index) => (\n <Step\n key={index}\n isActive={index === value}\n isCompleted={index < value}\n label={item.label}\n icon={item.icon}\n completedIcon={item.completedIcon}\n clickable={item.clickable}\n stepNumber={showStepNumbers ? index + 1 : undefined}\n onClick={\n item.clickable && onStepClick ? () => onStepClick(index) : undefined\n }\n className={item.className}\n />\n ));\n }\n\n // If children are provided, clone them with active/completed states\n if (children) {\n return React.Children.map(children, (child, index) => {\n if (React.isValidElement<StepProps>(child)) {\n return React.cloneElement(child, {\n isActive: index === value,\n isCompleted: index < value,\n stepNumber: showStepNumbers ? index + 1 : undefined,\n onClick:\n child.props.clickable && onStepClick\n ? () => onStepClick(index)\n : child.props.onClick,\n });\n }\n return child;\n });\n }\n\n return null;\n };\n\n return (\n <div className={combinedClasses} {...rest}>\n <ul className={listClasses}>{renderSteps()}</ul>\n {hasNavigation && (\n <div className={stepsNavigationClass}>\n <button\n type=\"button\"\n className={prevButtonClass}\n disabled={value === 0}\n onClick={onPrev ?? (() => onStepClick?.(value - 1))}\n >\n {prevLabel ?? 'Previous'}\n </button>\n <button\n type=\"button\"\n className={nextButtonClass}\n disabled={value === totalSteps - 1}\n onClick={onNext ?? (() => onStepClick?.(value + 1))}\n >\n {nextLabel ?? 'Next'}\n </button>\n </div>\n )}\n </div>\n );\n};\n\n// Attach Step as static property\nexport const Steps = withSubComponents(StepsComponent, { Step }, 'Steps');\n\nexport default Steps;\n"],"names":["_jsx","_jsxs"],"mappings":";;;;;;;AA2GA;;;;;;AAMG;AACI,MAAM,IAAI,GAAwB,CAAC,EACxC,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,KAAK,EACnB,KAAK,EACL,IAAI,EACJ,SAAS,GAAG,KAAK,EACjB,OAAO,EACP,UAAU,EACV,aAAa,EACb,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;IACH,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC;AAE3D,IAAA,MAAM,WAAW,GAAG,UAAU,CAC5B,qBAAqB,CAAC,eAAe,EAAE;AACrC,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,cAAc,EAAE,WAAW;AAC5B,KAAA,CAAC,EACF,kBAAkB,EAClB,SAAS,CACV;AACD,IAAA,MAAM,cAAc,GAAG,qBAAqB,CAAC,YAAY,CAAC;AAC1D,IAAA,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,cAAc,CAAC;AAC9D,IAAA,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,eAAe,CAAC;AAChE,IAAA,MAAM,eAAe,GAAG,qBAAqB,CAAC,aAAa,CAAC;IAE5D,MAAM,WAAW,GAAG,MAAK;AACvB,QAAA,IAAI,SAAS,IAAI,OAAO,EAAE;AACxB,YAAA,OAAO,EAAE;QACX;AACF,IAAA,CAAC;AAED,IAAA,MAAM,aAAa,GAAG,CAAC,CAAsB,KAAI;AAC/C,QAAA,IAAI,SAAS,IAAI,OAAO,KAAK,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE;YAChE,CAAC,CAAC,cAAc,EAAE;AAClB,YAAA,OAAO,EAAE;QACX;AACF,IAAA,CAAC;AAED,IAAA,MAAM,qBAAqB,GACzB,aAAa,KAAK,SAAS,GAAG,QAAQ,GAAG,aAAa;IACxD,MAAM,aAAa,GACjB,IAAI;SACH,WAAW,IAAI;AACd,cAAE;AACF,eAAG,UAAU,IAAI,IAAI,CAAC,CAAC;AAE3B,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EACE,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,SAAS,GAAG,CAAC,GAAG,SAAS,EACnC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,EAAA,cAAA,EACxB,QAAQ,GAAG,MAAM,GAAG,SAAS,EAAA,GACvC,IAAI,YAERC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAC5BD,cAAM,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAAG,aAAa,GAAQ,EACxD,CAAC,KAAK,IAAI,QAAQ,MACjBA,aAAK,SAAS,EAAE,iBAAiB,EAAA,QAAA,EAC/BA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,eAAe,YAAG,KAAK,IAAI,QAAQ,EAAA,CAAK,EAAA,CAClD,CACP,CAAA,EAAA,CACG,EAAA,CACH;AAET;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BG;AACH,MAAM,cAAc,GAAyB,CAAC,EAC5C,KAAK,GAAG,CAAC,EACT,KAAK,EACL,IAAI,EACJ,KAAK,EACL,SAAS,GAAG,IAAI,EAChB,QAAQ,GAAG,IAAI,EACf,OAAO,GAAG,IAAI,EACd,QAAQ,GAAG,KAAK,EAChB,aAAa,GAAG,QAAQ,EACxB,UAAU,EACV,eAAe,GAAG,IAAI,EACtB,aAAa,GAAG,KAAK,EACrB,SAAS,EACT,SAAS,EACT,MAAM,EACN,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;IACH,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC;;AAG3D,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,OAAO,EAAE;AAClD,QAAA,CAAC,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,GAAG,IAAI;AACpB,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK;AACtB,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,aAAa,EAAE,QAAQ;AACvB,QAAA,YAAY,EAAE,OAAO;AACrB,QAAA,aAAa,EAAE,QAAQ;AACvB,QAAA,CAAC,CAAA,UAAA,EAAa,aAAa,CAAA,CAAE,GAC3B,aAAa,KAAK,aAAa,KAAK,QAAQ,IAAI,QAAQ,CAAC;AAC3D,QAAA,CAAC,CAAA,GAAA,EAAM,UAAU,CAAA,CAAE,GAAG,UAAU;AACjC,KAAA,CAAC;IAEF,MAAM,eAAe,GAAG,UAAU,CAChC,YAAY,EACZ,kBAAkB,EAClB,SAAS,CACV;;AAGD,IAAA,MAAM,WAAW,GAAG,qBAAqB,CAAC,YAAY,EAAE;AACtD,QAAA,aAAa,EAAE,QAAQ;AACxB,KAAA,CAAC;AACF,IAAA,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,kBAAkB,CAAC;AACtE,IAAA,MAAM,eAAe,GAAG,qBAAqB,CAAC,QAAQ,CAAC;AACvD,IAAA,MAAM,eAAe,GAAG,qBAAqB,CAAC,QAAQ,EAAE;AACtD,QAAA,YAAY,EAAE,IAAI;AACnB,KAAA,CAAC;;IAGF,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;;IAGxE,MAAM,WAAW,GAAG,MAAK;QACvB,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAC3BA,GAAA,CAAC,IAAI,EAAA,EAEH,QAAQ,EAAE,KAAK,KAAK,KAAK,EACzB,WAAW,EAAE,KAAK,GAAG,KAAK,EAC1B,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,aAAa,EAAE,IAAI,CAAC,aAAa,EACjC,SAAS,EAAE,IAAI,CAAC,SAAS,EACzB,UAAU,EAAE,eAAe,GAAG,KAAK,GAAG,CAAC,GAAG,SAAS,EACnD,OAAO,EACL,IAAI,CAAC,SAAS,IAAI,WAAW,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,SAAS,EAEtE,SAAS,EAAE,IAAI,CAAC,SAAS,IAXpB,KAAK,CAYV,CACH,CAAC;QACJ;;QAGA,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAI;AACnD,gBAAA,IAAI,KAAK,CAAC,cAAc,CAAY,KAAK,CAAC,EAAE;AAC1C,oBAAA,OAAO,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE;wBAC/B,QAAQ,EAAE,KAAK,KAAK,KAAK;wBACzB,WAAW,EAAE,KAAK,GAAG,KAAK;wBAC1B,UAAU,EAAE,eAAe,GAAG,KAAK,GAAG,CAAC,GAAG,SAAS;AACnD,wBAAA,OAAO,EACL,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI;AACvB,8BAAE,MAAM,WAAW,CAAC,KAAK;AACzB,8BAAE,KAAK,CAAC,KAAK,CAAC,OAAO;AAC1B,qBAAA,CAAC;gBACJ;AACA,gBAAA,OAAO,KAAK;AACd,YAAA,CAAC,CAAC;QACJ;AAEA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;IAED,QACEC,cAAK,SAAS,EAAE,eAAe,EAAA,GAAM,IAAI,EAAA,QAAA,EAAA,CACvCD,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,WAAW,EAAA,QAAA,EAAG,WAAW,EAAE,EAAA,CAAM,EAC/C,aAAa,KACZC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,oBAAoB,EAAA,QAAA,EAAA,CAClCD,gBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,KAAK,KAAK,CAAC,EACrB,OAAO,EAAE,MAAM,KAAK,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,EAAA,QAAA,EAElD,SAAS,IAAI,UAAU,EAAA,CACjB,EACTA,GAAA,CAAA,QAAA,EAAA,EACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,KAAK,KAAK,UAAU,GAAG,CAAC,EAClC,OAAO,EAAE,MAAM,KAAK,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,EAAA,QAAA,EAElD,SAAS,IAAI,MAAM,GACb,CAAA,EAAA,CACL,CACP,CAAA,EAAA,CACG;AAEV,CAAC;AAED;AACO,MAAM,KAAK,GAAG,iBAAiB,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO;;"}
|