@allxsmith/bestax-bulma 5.52.0 → 5.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Avatars.js +7 -2
  4. package/dist/esm/components/Avatars.js.map +1 -1
  5. package/dist/esm/components/Badge.js +7 -2
  6. package/dist/esm/components/Badge.js.map +1 -1
  7. package/dist/esm/components/Command.js +19 -9
  8. package/dist/esm/components/Command.js.map +1 -1
  9. package/dist/esm/components/Modal.js +2 -1
  10. package/dist/esm/components/Modal.js.map +1 -1
  11. package/dist/esm/components/Pagination.js +9 -1
  12. package/dist/esm/components/Pagination.js.map +1 -1
  13. package/dist/esm/components/Sidebar.js +3 -1
  14. package/dist/esm/components/Sidebar.js.map +1 -1
  15. package/dist/esm/components/Steps.js +5 -1
  16. package/dist/esm/components/Steps.js.map +1 -1
  17. package/dist/esm/components/Toast.js +8 -5
  18. package/dist/esm/components/Toast.js.map +1 -1
  19. package/dist/esm/elements/Notification.js +4 -2
  20. package/dist/esm/elements/Notification.js.map +1 -1
  21. package/dist/esm/elements/RingProgress.js +6 -1
  22. package/dist/esm/elements/RingProgress.js.map +1 -1
  23. package/dist/esm/form/Autocomplete.js +7 -2
  24. package/dist/esm/form/Autocomplete.js.map +1 -1
  25. package/dist/esm/form/Checkbox.js +3 -2
  26. package/dist/esm/form/Checkbox.js.map +1 -1
  27. package/dist/esm/form/CheckboxCard.js +3 -2
  28. package/dist/esm/form/CheckboxCard.js.map +1 -1
  29. package/dist/esm/form/Combobox.js +10 -4
  30. package/dist/esm/form/Combobox.js.map +1 -1
  31. package/dist/esm/form/DateInputBase.js +15 -6
  32. package/dist/esm/form/DateInputBase.js.map +1 -1
  33. package/dist/esm/form/DateRangeInputBase.js +15 -5
  34. package/dist/esm/form/DateRangeInputBase.js.map +1 -1
  35. package/dist/esm/form/DateTimeInputBase.js +15 -6
  36. package/dist/esm/form/DateTimeInputBase.js.map +1 -1
  37. package/dist/esm/form/Fieldset.js +64 -0
  38. package/dist/esm/form/Fieldset.js.map +1 -0
  39. package/dist/esm/form/File.js +4 -1
  40. package/dist/esm/form/File.js.map +1 -1
  41. package/dist/esm/form/FormContext.js +17 -1
  42. package/dist/esm/form/FormContext.js.map +1 -1
  43. package/dist/esm/form/InputBase.js +3 -2
  44. package/dist/esm/form/InputBase.js.map +1 -1
  45. package/dist/esm/form/Numberinput.js +3 -2
  46. package/dist/esm/form/Numberinput.js.map +1 -1
  47. package/dist/esm/form/PinInput.js +3 -2
  48. package/dist/esm/form/PinInput.js.map +1 -1
  49. package/dist/esm/form/Radio.js +3 -2
  50. package/dist/esm/form/Radio.js.map +1 -1
  51. package/dist/esm/form/RadioCard.js +3 -2
  52. package/dist/esm/form/RadioCard.js.map +1 -1
  53. package/dist/esm/form/Rate.js +12 -3
  54. package/dist/esm/form/Rate.js.map +1 -1
  55. package/dist/esm/form/SelectBase.js +3 -2
  56. package/dist/esm/form/SelectBase.js.map +1 -1
  57. package/dist/esm/form/Slider.js +10 -6
  58. package/dist/esm/form/Slider.js.map +1 -1
  59. package/dist/esm/form/Switch.js +3 -1
  60. package/dist/esm/form/Switch.js.map +1 -1
  61. package/dist/esm/form/Taginput.js +12 -5
  62. package/dist/esm/form/Taginput.js.map +1 -1
  63. package/dist/esm/form/TextAreaBase.js +3 -2
  64. package/dist/esm/form/TextAreaBase.js.map +1 -1
  65. package/dist/esm/form/TimeInputBase.js +13 -6
  66. package/dist/esm/form/TimeInputBase.js.map +1 -1
  67. package/dist/esm/form/_pickerInternals/PickerPopover.js +4 -2
  68. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
  69. package/dist/esm/form/_pickerInternals/useLocaleDefaults.js +80 -0
  70. package/dist/esm/form/_pickerInternals/useLocaleDefaults.js.map +1 -0
  71. package/dist/esm/helpers/LocaleProvider.js +156 -0
  72. package/dist/esm/helpers/LocaleProvider.js.map +1 -0
  73. package/dist/esm/helpers/localeFormat.js +108 -0
  74. package/dist/esm/helpers/localeFormat.js.map +1 -0
  75. package/dist/esm/helpers/localeInfo.js +109 -0
  76. package/dist/esm/helpers/localeInfo.js.map +1 -0
  77. package/dist/esm/helpers/portal.js +14 -1
  78. package/dist/esm/helpers/portal.js.map +1 -1
  79. package/dist/extras.css +1 -1
  80. package/dist/extras.css.map +1 -1
  81. package/dist/index.cjs +690 -73
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.esm.js +2 -0
  84. package/dist/index.esm.js.map +1 -1
  85. package/dist/types/components/Avatars.d.ts +1 -1
  86. package/dist/types/components/Badge.d.ts +1 -1
  87. package/dist/types/components/Command.d.ts +4 -2
  88. package/dist/types/components/Pagination.d.ts +3 -0
  89. package/dist/types/components/Steps.d.ts +4 -1
  90. package/dist/types/elements/RingProgress.d.ts +3 -2
  91. package/dist/types/form/Autocomplete.d.ts +6 -1
  92. package/dist/types/form/Combobox.d.ts +3 -2
  93. package/dist/types/form/DateInputBase.d.ts +25 -3
  94. package/dist/types/form/DateRangeInputBase.d.ts +25 -3
  95. package/dist/types/form/DateTimeInputBase.d.ts +25 -3
  96. package/dist/types/form/Fieldset.d.ts +86 -0
  97. package/dist/types/form/File.d.ts +2 -1
  98. package/dist/types/form/FormContext.d.ts +12 -0
  99. package/dist/types/form/Rate.d.ts +4 -1
  100. package/dist/types/form/Slider.d.ts +9 -2
  101. package/dist/types/form/Taginput.d.ts +8 -2
  102. package/dist/types/form/TimeInputBase.d.ts +5 -1
  103. package/dist/types/form/_pickerInternals/PickerPopover.d.ts +6 -0
  104. package/dist/types/form/_pickerInternals/useLocaleDefaults.d.ts +49 -0
  105. package/dist/types/helpers/LocaleProvider.d.ts +131 -0
  106. package/dist/types/helpers/localeFormat.d.ts +26 -0
  107. package/dist/types/helpers/localeInfo.d.ts +23 -0
  108. package/dist/types/helpers/portal.d.ts +11 -0
  109. package/dist/types/index.d.ts +3 -0
  110. package/dist/types-cjs/components/Avatars.d.ts +1 -1
  111. package/dist/types-cjs/components/Badge.d.ts +1 -1
  112. package/dist/types-cjs/components/Command.d.ts +4 -2
  113. package/dist/types-cjs/components/Pagination.d.ts +3 -0
  114. package/dist/types-cjs/components/Steps.d.ts +4 -1
  115. package/dist/types-cjs/elements/RingProgress.d.ts +3 -2
  116. package/dist/types-cjs/form/Autocomplete.d.ts +6 -1
  117. package/dist/types-cjs/form/Combobox.d.ts +3 -2
  118. package/dist/types-cjs/form/DateInputBase.d.ts +25 -3
  119. package/dist/types-cjs/form/DateRangeInputBase.d.ts +25 -3
  120. package/dist/types-cjs/form/DateTimeInputBase.d.ts +25 -3
  121. package/dist/types-cjs/form/Fieldset.d.ts +86 -0
  122. package/dist/types-cjs/form/File.d.ts +2 -1
  123. package/dist/types-cjs/form/FormContext.d.ts +12 -0
  124. package/dist/types-cjs/form/Rate.d.ts +4 -1
  125. package/dist/types-cjs/form/Slider.d.ts +9 -2
  126. package/dist/types-cjs/form/Taginput.d.ts +8 -2
  127. package/dist/types-cjs/form/TimeInputBase.d.ts +5 -1
  128. package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +6 -0
  129. package/dist/types-cjs/form/_pickerInternals/useLocaleDefaults.d.ts +49 -0
  130. package/dist/types-cjs/helpers/LocaleProvider.d.ts +131 -0
  131. package/dist/types-cjs/helpers/localeFormat.d.ts +26 -0
  132. package/dist/types-cjs/helpers/localeInfo.d.ts +23 -0
  133. package/dist/types-cjs/helpers/portal.d.ts +11 -0
  134. package/dist/types-cjs/index.d.ts +3 -0
  135. package/dist/versions/bestax-no-dark-mode.css +1 -1
  136. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  137. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  138. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  139. package/dist/versions/bestax-no-helpers.css +1 -1
  140. package/dist/versions/bestax-no-helpers.css.map +1 -1
  141. package/dist/versions/bestax-prefixed.css +1 -1
  142. package/dist/versions/bestax-prefixed.css.map +1 -1
  143. package/package.json +1 -1
  144. package/src/scss/form/_fieldset.scss +108 -0
  145. package/src/scss/form/_index.scss +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { buttonType } from '../helpers/buttonType';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useConfig } from '../helpers/Config';\nimport { useScrollLock } from '../helpers/scrollLock';\nimport {\n getActiveElementInTree,\n getDeepestActiveElement,\n} from '../helpers/shadowDom';\nimport { usePortalContainer } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport { useOverlayStack } from '../helpers/overlayStack';\nimport { focusTabStop, trapTab } from '../helpers/useFocusTrap';\n\n/**\n * Props for the Modal component.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root `.modal` element.\n */\nexport interface ModalProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'title'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Whether the modal is open/visible. */\n active?: boolean;\n /** Alias for `active`. Whether the modal is open/visible. */\n isActive?: boolean; // Alias for active\n /**\n * Called to ask for the modal to close. The props form calls it from the\n * background and the close button it renders. In the compound form,\n * `Modal.Close` calls it unless you give it an `onClick` of your own, and\n * `Modal.Background` doesn't call it on its own: pass it\n * `onClick={onClose}` for a click on the background to close the modal.\n * Escape calls it in both forms unless `closeOnEscape` is `false`.\n */\n onClose?: () => void;\n /** Additional CSS classes for the modal. */\n className?: string;\n /** Text color for modal content. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color for modal content. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Title/header for modal-card variant. (Legacy API only) */\n modalCardTitle?: React.ReactNode;\n /** Footer for modal-card variant. (Legacy API only) */\n modalCardFoot?: React.ReactNode;\n /**\n * Modal style: `'card'` for modal-card, `'content'` for modal-content. (Legacy API only)\n * @defaultValue auto\n */\n type?: 'card' | 'content';\n /** Modal body/content or compound components. */\n children?: React.ReactNode;\n /**\n * Close the modal when the Escape key is pressed (calls `onClose`). Only the\n * topmost open overlay responds, whichever Modal, Dialog, Sidebar or\n * full-page Loading opened last, so Escape closes one layer at a time. The\n * modal marks the Escape it closes on as used with `preventDefault()`, and\n * a Toast waits until no overlay is open. Turned off, a modal on top still\n * keeps Escape from the layers under it. A popup inside it, such as a\n * Dropdown's menu or a date picker's calendar, takes its own Escape first,\n * and so does content that calls `preventDefault()` on it.\n * @defaultValue true\n */\n closeOnEscape?: boolean;\n /**\n * Lock body scroll while the modal is active. Ref-counted and shared with\n * `Dialog`, `Sidebar` and `Loading`, so whichever overlay closes first does\n * not unlock the page underneath one that is still open.\n * @defaultValue true\n */\n lockScroll?: boolean;\n /**\n * Renders the modal into a portal target instead of inline, so it isn't\n * clipped by an ancestor with `overflow: hidden`, `filter` or `transform`.\n * `true` portals to the `portalContainer` a `ConfigProvider` sets,\n * `document.body` by default; a string is used as a\n * `document.querySelector` selector; an element is used directly. Renders\n * inline on the server and while hydrating, moving into the portal once the\n * client takes over, so hydration matches.\n * @defaultValue false\n */\n portal?: boolean | string | HTMLElement;\n}\n\n/**\n * Props for Modal.Background component.\n * @extraProp {React.MouseEventHandler<HTMLDivElement>} [onClick] - Called when the background is clicked. The background doesn't call the modal's `onClose` on its own, so pass `onClick={onClose}` for a click on it to close the modal.\n */\nexport interface ModalBackgroundProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Content component.\n */\nexport interface ModalContentProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card component.\n */\nexport interface ModalCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Head component.\n */\nexport interface ModalCardHeadProps extends React.HTMLAttributes<HTMLElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Title component.\n */\nexport interface ModalCardTitleProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Body component.\n */\nexport interface ModalCardBodyProps extends React.HTMLAttributes<HTMLElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Foot component.\n */\nexport interface ModalCardFootProps extends React.HTMLAttributes<HTMLElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Close component.\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 * @extraProp {React.MouseEventHandler<HTMLButtonElement>} [onClick] - Called when the button is clicked. Without one, the button calls the `onClose` of the `Modal` around it. Yours replaces that rather than running before it, so call `onClose` from it if the button should still close the modal.\n */\nexport interface ModalCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Size of the close button (only applies to 'floating' variant). */\n size?: 'small' | 'medium' | 'large';\n /** Button variant. 'delete' (default) for modal card headers, 'floating' for overlay close button. */\n variant?: 'delete' | 'floating';\n}\n\n// The enclosing modal's `onClose`, for a `Modal.Close` written as a part, so\n// it closes the modal the way the button the props form renders does.\nconst ModalCloseContext = createContext<(() => void) | undefined>(undefined);\n\n/**\n * Modal.Background - Renders the modal background overlay. Pass it\n * `onClick={onClose}` for a click on it to close the modal.\n *\n * @function\n * @param {ModalBackgroundProps} props - Component props.\n * @returns {JSX.Element} Modal background element.\n */\nconst ModalBackground: React.FC<ModalBackgroundProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-background'),\n className\n );\n return <div className={classes} {...props} />;\n};\n\n/**\n * Modal.Content - Renders modal content wrapper for custom content.\n *\n * @function\n * @param {ModalContentProps} props - Component props.\n * @returns {JSX.Element} Modal content element.\n */\nconst ModalContent: React.FC<ModalContentProps> = ({ className, ...props }) => {\n const classes = classNames(usePrefixedClassNames('modal-content'), className);\n return <div className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Head - Renders modal card header section.\n *\n * @function\n * @param {ModalCardHeadProps} props - Component props.\n * @returns {JSX.Element} Modal card header element.\n */\nconst ModalCardHead: React.FC<ModalCardHeadProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-head'),\n className\n );\n return <header className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Title - Renders modal card title.\n *\n * @function\n * @param {ModalCardTitleProps} props - Component props.\n * @returns {JSX.Element} Modal card title element.\n */\nconst ModalCardTitle: React.FC<ModalCardTitleProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-title'),\n className\n );\n return <p className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Body - Renders modal card body section.\n *\n * @function\n * @param {ModalCardBodyProps} props - Component props.\n * @returns {JSX.Element} Modal card body element.\n */\nconst ModalCardBody: React.FC<ModalCardBodyProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-body'),\n className\n );\n return <section className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Foot - Renders modal card footer section.\n *\n * @function\n * @param {ModalCardFootProps} props - Component props.\n * @returns {JSX.Element} Modal card footer element.\n */\nconst ModalCardFoot: React.FC<ModalCardFootProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-foot'),\n className\n );\n return <footer className={classes} {...props} />;\n};\n\n/**\n * Modal.Card - Renders modal card wrapper with compound components.\n * Use with Modal.Card.Head, Modal.Card.Title, Modal.Card.Body, and Modal.Card.Foot.\n *\n * @function\n * @param {ModalCardProps} props - Component props.\n * @returns {JSX.Element} Modal card element.\n */\nconst ModalCardComponent: React.FC<ModalCardProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(usePrefixedClassNames('modal-card'), className);\n return <div className={classes} {...props} />;\n};\n\nconst ModalCard = withSubComponents(ModalCardComponent, {\n Head: ModalCardHead,\n Title: ModalCardTitle,\n Body: ModalCardBody,\n Foot: ModalCardFoot,\n});\n\n/**\n * Modal.Close - Renders modal close button with two variant styles. It calls\n * the modal's `onClose` unless given an `onClick` of its own.\n *\n * @function\n * @param {ModalCloseProps} props - Component props.\n * @returns {JSX.Element} Close button element.\n *\n * @remarks\n * Supports two variants:\n * - 'delete' (default): For use in modal card headers, renders with 'delete' class\n * - 'floating': For floating overlay close button, renders with 'modal-close' class\n *\n * The size prop only applies to the 'floating' variant.\n */\nconst ModalClose: React.FC<ModalCloseProps> = ({\n className,\n size = 'large',\n variant = 'delete',\n onClick,\n ...props\n}) => {\n const onClose = useContext(ModalCloseContext);\n const classes = classNames(\n usePrefixedClassNames(\n variant === 'delete' ? 'delete' : 'modal-close',\n variant === 'floating' && size && { [`is-${size}`]: true }\n ),\n className\n );\n return (\n <button\n className={classes}\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 // A caller's own `onClick` replaces the close rather than running\n // before it, unlike `Popover.Close`: this button used to close only\n // through that handler, so a caller already closing there, as with\n // `onClick={onClose}`, would otherwise close twice.\n onClick={onClick ?? (onClose && (() => onClose()))}\n />\n );\n};\n\n/**\n * The `Modal` component provides an empty, accessible overlay for arbitrary content — for a ready-made confirm or alert, reach for `Dialog` instead.\n *\n * @function\n * @param {ModalProps} props - Props for the Modal component.\n * @returns {JSX.Element} The rendered modal.\n *\n * @example\n * // Legacy API\n * <Modal active={isOpen} onClose={handleClose} modalCardTitle=\"Title\">\n * Content\n * </Modal>\n *\n * @example\n * // Compound Component API\n * <Modal isActive={isOpen} onClose={handleClose}>\n * <Modal.Background onClick={handleClose} />\n * <Modal.Card>\n * <Modal.Card.Head>\n * <Modal.Card.Title>Title</Modal.Card.Title>\n * <Modal.Close />\n * </Modal.Card.Head>\n * <Modal.Card.Body>Content</Modal.Card.Body>\n * </Modal.Card>\n * </Modal>\n *\n * @see {@link https://bulma.io/documentation/components/modal/ | Bulma Modal documentation}\n */\nconst ModalRoot = forwardRef<HTMLDivElement, ModalProps>(function ModalRoot(\n {\n active,\n isActive,\n onClose,\n className,\n textColor,\n bgColor,\n modalCardTitle,\n modalCardFoot,\n type,\n children,\n closeOnEscape = true,\n lockScroll = true,\n portal = false,\n role,\n 'aria-modal': ariaModalProp,\n ...props\n },\n ref\n) {\n const { classPrefix, portalContainer } = useConfig();\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n // Support both active and isActive props\n const isModalActive = active ?? isActive ?? false;\n\n const modalRootRef = useRef<HTMLDivElement>(null);\n\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n\n // The forwarded ref and the internal one must both see the node: focus\n // management and the Tab trap read `modalRootRef`, while consumers expect\n // their own ref to resolve.\n const combinedRef = useCallback(\n (node: HTMLDivElement | null) => {\n (modalRootRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches\n // by running it instead of calling the ref with `null`; React 18\n // discards the return value entirely. Returning it from here would be\n // a React-19-only contract, so instead we hold the cleanup and run it\n // ourselves on detach — a consumer's cleanup ref then behaves the same\n // on both majors of the CI matrix. Same shape as `Dropdown`.\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<HTMLDivElement | null>).current = node;\n }\n },\n [ref]\n );\n const previouslyFocusedRef = useRef<HTMLElement | null>(null);\n const generatedTitleId = useId();\n // A portal has no server-rendered counterpart, so the server render and the\n // hydrating render have to stay inline and only move into the portal once\n // we're past hydration.\n const onClient = useIsHydrated();\n const resolveContainer = usePortalContainer();\n // Moving into the portal, or from one portal target to another, remounts\n // the modal's subtree, so any effect holding a DOM node from before the move\n // is holding a detached one. Effects that touch the modal's nodes key on\n // this, on `portal` and on `defaultTarget`, so they re-run against the new\n // tree.\n const isPortaled = Boolean(portal) && onClient;\n // The configured `portalContainer` only places a modal portaled with\n // `portal` set to `true`. In place, or with a target of its own, a change\n // to it moves nothing, so it mustn't re-run the effects either.\n const defaultTarget =\n isPortaled && portal === true ? portalContainer : undefined;\n\n useScrollLock(isModalActive && lockScroll);\n\n // Read when Escape arrives, so the key listener stays put while `onClose`\n // changes identity, as an inline one does on every render of the parent.\n const onCloseRef = useLatestRef(onClose);\n\n // Joins the stack of open overlays, so the keyboard handling below only\n // applies while this modal is on top.\n const isTopmost = useOverlayStack(isModalActive);\n\n // Escape closes, only for the topmost overlay. The listener is on\n // `window`, where a keydown arrives last, so everything inside the modal\n // has had the key first: React's handlers, and `document` listeners added\n // after this one, such as a date picker's.\n useEffect(() => {\n if (!isModalActive) return undefined;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || !isTopmost()) return;\n // Something inside already used this Escape, such as a popup that\n // closed on it, so the modal waits for the next one. One the modal\n // closes on is marked used, so nothing under it acts on it as well.\n if (closeOnEscape && onCloseRef.current && !e.defaultPrevented) {\n e.preventDefault();\n onCloseRef.current();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isModalActive, closeOnEscape, onCloseRef, isTopmost]);\n\n // Keep Tab within the modal: `aria-modal` hides the rest of the page from\n // assistive technology, so the keyboard order has to agree. Only while\n // it's the topmost modal overlay, so an overlay that isn't modal, such as\n // a Sidebar without an overlay, takes Escape from it but leaves it Tab.\n // It's the trap `useFocusTrap` sets, so it wraps at the stops Tab really\n // visits, skipping hidden, inert and closed content, and sends back a Tab\n // the browser still takes out. On `window` for the same reason as Escape:\n // a trap inside, such as a portaled popup's, has had the Tab first, and\n // one it used is left where it put focus. It reads the modal's node as\n // each key arrives, so a portal move that remounts the node, including one\n // to a selector that only starts matching while the modal is open, keeps\n // it trapped.\n useEffect(() => {\n if (!isModalActive) return undefined;\n return trapTab(\n () => modalRootRef.current,\n window,\n () => isTopmost('modal')\n );\n }, [isModalActive, isTopmost]);\n\n // Move focus into the modal on open, restore it on close\n useEffect(() => {\n if (!isModalActive) return undefined;\n\n // The element that had focus, wherever it sits: a portaled modal renders\n // under `document.body` while its opener can be inside a shadow root.\n previouslyFocusedRef.current =\n getDeepestActiveElement() as HTMLElement | null;\n const node = modalRootRef.current;\n if (node) focusTabStop(node);\n\n return () => {\n // Only hand focus back if this modal still owns it: closing a background\n // modal must not pull focus out of one that is still open on top. A\n // removed subtree leaves focus on <body>, which still counts as ours.\n const activeElement = getActiveElementInTree(node);\n if (\n activeElement &&\n activeElement !== document.body &&\n !node?.contains(activeElement)\n ) {\n return;\n }\n previouslyFocusedRef.current?.focus?.();\n };\n // `isPortaled` flips once when a hydrated portal modal moves out of the\n // inline tree, and `portal` or `defaultTarget` changing moves a portaled\n // one to another target; re-running rebinds focus onto the remounted\n // nodes. The cleanup above restores focus to the pre-open element first\n // (the detached subtree has left focus on <body>), so the re-run re-records\n // the same element and restore-on-close still lands in the right place.\n }, [isModalActive, isPortaled, portal, defaultTarget]);\n\n // Check if children contain compound components\n const hasCompoundComponents = React.Children.toArray(children).some(\n child =>\n React.isValidElement(child) &&\n (child.type === ModalBackground ||\n child.type === ModalContent ||\n child.type === ModalCard ||\n child.type === ModalClose)\n );\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('modal', {\n 'is-active': isModalActive,\n });\n const deleteClass = usePrefixedClassNames('delete');\n\n const modalClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n const resolvedRole = role ?? (isModalActive ? 'dialog' : undefined);\n const resolvedAriaModal =\n ariaModalProp ??\n (isModalActive && resolvedRole !== 'presentation' ? 'true' : undefined);\n // A dialog needs an accessible name: the legacy card title is wired up\n // automatically, compound users pass their own aria-label/aria-labelledby\n // (both arrive in `rest`, which is spread last and so wins).\n const titleId = modalCardTitle ? generatedTitleId : undefined;\n\n let modalElement: React.ReactElement;\n\n // If using compound components, render children as-is\n if (hasCompoundComponents) {\n modalElement = (\n <div\n className={modalClasses}\n ref={combinedRef}\n role={resolvedRole}\n aria-modal={resolvedAriaModal}\n tabIndex={-1}\n {...rest}\n data-testid=\"modal\"\n >\n {children}\n </div>\n );\n } else {\n // Legacy API: EXPLICIT type wins; fallback to auto detection if not provided\n let isModalCard: boolean;\n if (type === 'card') isModalCard = true;\n else if (type === 'content') isModalCard = false;\n else isModalCard = !!modalCardTitle || !!modalCardFoot;\n\n modalElement = (\n <div\n className={modalClasses}\n ref={combinedRef}\n role={resolvedRole}\n aria-modal={resolvedAriaModal}\n aria-labelledby={titleId}\n tabIndex={-1}\n {...rest}\n data-testid=\"modal\"\n >\n <div\n className={prefixedClassNames(classPrefix, 'modal-background')}\n onClick={onClose}\n data-testid=\"modal-background\"\n />\n {isModalCard ? (\n <div className={prefixedClassNames(classPrefix, 'modal-card')}>\n {modalCardTitle && (\n <header\n className={prefixedClassNames(classPrefix, 'modal-card-head')}\n >\n <p\n id={titleId}\n className={prefixedClassNames(\n classPrefix,\n 'modal-card-title'\n )}\n >\n {modalCardTitle}\n </p>\n {onClose && (\n <button\n className={deleteClass}\n aria-label=\"close\"\n onClick={onClose}\n type=\"button\"\n data-testid=\"modal-close\"\n />\n )}\n </header>\n )}\n <section\n className={prefixedClassNames(classPrefix, 'modal-card-body')}\n data-testid=\"modal-body\"\n >\n {children}\n </section>\n {modalCardFoot && (\n <footer\n className={prefixedClassNames(classPrefix, 'modal-card-foot')}\n >\n {modalCardFoot}\n </footer>\n )}\n </div>\n ) : (\n <div\n className={prefixedClassNames(classPrefix, 'modal-content')}\n data-testid=\"modal-content\"\n >\n {children}\n </div>\n )}\n {/* Show floating close button for modal-content, or for modal-card when no header */}\n {(!isModalCard || (!modalCardTitle && onClose)) && onClose && (\n <button\n className={prefixedClassNames(\n classPrefix,\n 'modal-close',\n 'is-large'\n )}\n aria-label=\"close\"\n onClick={onClose}\n type=\"button\"\n data-testid=\"modal-close-float\"\n />\n )}\n </div>\n );\n }\n\n // In both forms, so a `Modal.Close` anywhere inside closes this modal.\n modalElement = (\n <ModalCloseContext.Provider value={onClose}>\n {modalElement}\n </ModalCloseContext.Provider>\n );\n\n if (isPortaled) {\n const target = resolveContainer(\n typeof portal === 'boolean' ? undefined : portal\n );\n return createPortal(modalElement, target);\n }\n\n return modalElement;\n});\n\nexport const Modal = withSubComponents(\n ModalRoot,\n {\n Background: ModalBackground,\n Content: ModalContent,\n Card: ModalCard,\n Close: ModalClose,\n },\n 'Modal'\n);\nexport default Modal;\n"],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;;;;;;;;;;AAgLA;AACA;AACA,MAAM,iBAAiB,GAAG,aAAa,CAA2B,SAAS,CAAC;AAE5E;;;;;;;AAOG;AACH,MAAM,eAAe,GAAmC,CAAC,EACvD,SAAS,EACT,GAAG,KAAK,EACT,KAAI;IACH,MAAM,OAAO,GAAG,UAAU,CACxB,qBAAqB,CAAC,kBAAkB,CAAC,EACzC,SAAS,CACV;AACD,IAAA,OAAOA,aAAK,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AAC/C,CAAC;AAED;;;;;;AAMG;AACH,MAAM,YAAY,GAAgC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,KAAI;IAC5E,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC,eAAe,CAAC,EAAE,SAAS,CAAC;AAC7E,IAAA,OAAOA,aAAK,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AAC/C,CAAC;AAED;;;;;;AAMG;AACH,MAAM,aAAa,GAAiC,CAAC,EACnD,SAAS,EACT,GAAG,KAAK,EACT,KAAI;IACH,MAAM,OAAO,GAAG,UAAU,CACxB,qBAAqB,CAAC,iBAAiB,CAAC,EACxC,SAAS,CACV;AACD,IAAA,OAAOA,gBAAQ,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AAClD,CAAC;AAED;;;;;;AAMG;AACH,MAAM,cAAc,GAAkC,CAAC,EACrD,SAAS,EACT,GAAG,KAAK,EACT,KAAI;IACH,MAAM,OAAO,GAAG,UAAU,CACxB,qBAAqB,CAAC,kBAAkB,CAAC,EACzC,SAAS,CACV;AACD,IAAA,OAAOA,WAAG,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AAC7C,CAAC;AAED;;;;;;AAMG;AACH,MAAM,aAAa,GAAiC,CAAC,EACnD,SAAS,EACT,GAAG,KAAK,EACT,KAAI;IACH,MAAM,OAAO,GAAG,UAAU,CACxB,qBAAqB,CAAC,iBAAiB,CAAC,EACxC,SAAS,CACV;AACD,IAAA,OAAOA,iBAAS,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AACnD,CAAC;AAED;;;;;;AAMG;AACH,MAAM,aAAa,GAAiC,CAAC,EACnD,SAAS,EACT,GAAG,KAAK,EACT,KAAI;IACH,MAAM,OAAO,GAAG,UAAU,CACxB,qBAAqB,CAAC,iBAAiB,CAAC,EACxC,SAAS,CACV;AACD,IAAA,OAAOA,gBAAQ,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AAClD,CAAC;AAED;;;;;;;AAOG;AACH,MAAM,kBAAkB,GAA6B,CAAC,EACpD,SAAS,EACT,GAAG,KAAK,EACT,KAAI;IACH,MAAM,OAAO,GAAG,UAAU,CAAC,qBAAqB,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;AAC1E,IAAA,OAAOA,aAAK,SAAS,EAAE,OAAO,EAAA,GAAM,KAAK,GAAI;AAC/C,CAAC;AAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,kBAAkB,EAAE;AACtD,IAAA,IAAI,EAAE,aAAa;AACnB,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,IAAI,EAAE,aAAa;AACnB,IAAA,IAAI,EAAE,aAAa;AACpB,CAAA,CAAC;AAEF;;;;;;;;;;;;;;AAcG;AACH,MAAM,UAAU,GAA8B,CAAC,EAC7C,SAAS,EACT,IAAI,GAAG,OAAO,EACd,OAAO,GAAG,QAAQ,EAClB,OAAO,EACP,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC;AAC7C,IAAA,MAAM,OAAO,GAAG,UAAU,CACxB,qBAAqB,CACnB,OAAO,KAAK,QAAQ,GAAG,QAAQ,GAAG,aAAa,EAC/C,OAAO,KAAK,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,GAAG,IAAI,EAAE,CAC3D,EACD,SAAS,CACV;IACD,QACEA,gBACE,SAAS,EAAE,OAAO,EAAA,GACd,KAAK,EAAA,YAAA,EAMG,KAAK,CAAC,YAAY,CAAC,IAAI,OAAO,EAC1C,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;;;;;AAK5B,QAAA,OAAO,EAAE,OAAO,KAAK,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC,EAAA,CAClD;AAEN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;AACH,MAAM,SAAS,GAAG,UAAU,CAA6B,SAAS,SAAS,CACzE,EACE,MAAM,EACN,QAAQ,EACR,OAAO,EACP,SAAS,EACT,SAAS,EACT,OAAO,EACP,cAAc,EACd,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,aAAa,GAAG,IAAI,EACpB,UAAU,GAAG,IAAI,EACjB,MAAM,GAAG,KAAK,EACd,IAAI,EACJ,YAAY,EAAE,aAAa,EAC3B,GAAG,KAAK,EACT,EACD,GAAG,EAAA;IAEH,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE;AACpD,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;;AAGF,IAAA,MAAM,aAAa,GAAG,MAAM,IAAI,QAAQ,IAAI,KAAK;AAEjD,IAAA,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC;;AAGjD,IAAA,MAAM,kBAAkB,GAAG,MAAM,CAAsB,IAAI,CAAC;;;;AAK5D,IAAA,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,IAA2B,KAAI;AAC7B,QAAA,YAA8D,CAAC,OAAO;AACrE,YAAA,IAAI;AACN,QAAA,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;;;;;;;AAO7B,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,GAAqD,CAAC,OAAO,GAAG,IAAI;QACvE;AACF,IAAA,CAAC,EACD,CAAC,GAAG,CAAC,CACN;AACD,IAAA,MAAM,oBAAoB,GAAG,MAAM,CAAqB,IAAI,CAAC;AAC7D,IAAA,MAAM,gBAAgB,GAAG,KAAK,EAAE;;;;AAIhC,IAAA,MAAM,QAAQ,GAAG,aAAa,EAAE;AAChC,IAAA,MAAM,gBAAgB,GAAG,kBAAkB,EAAE;;;;;;IAM7C,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ;;;;AAI9C,IAAA,MAAM,aAAa,GACjB,UAAU,IAAI,MAAM,KAAK,IAAI,GAAG,eAAe,GAAG,SAAS;AAE7D,IAAA,aAAa,CAAC,aAAa,IAAI,UAAU,CAAC;;;AAI1C,IAAA,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC;;;AAIxC,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,aAAa,CAAC;;;;;IAMhD,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,aAAa;AAAE,YAAA,OAAO,SAAS;AAEpC,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI;YACzC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,SAAS,EAAE;gBAAE;;;;YAIxC,IAAI,aAAa,IAAI,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,gBAAgB,EAAE;gBAC9D,CAAC,CAAC,cAAc,EAAE;gBAClB,UAAU,CAAC,OAAO,EAAE;YACtB;AACF,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC;QACjD,OAAO,MAAM,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC;IACnE,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;;;;;;;;;;;;;IAczD,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,aAAa;AAAE,YAAA,OAAO,SAAS;AACpC,QAAA,OAAO,OAAO,CACZ,MAAM,YAAY,CAAC,OAAO,EAC1B,MAAM,EACN,MAAM,SAAS,CAAC,OAAO,CAAC,CACzB;AACH,IAAA,CAAC,EAAE,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;;IAG9B,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,aAAa;AAAE,YAAA,OAAO,SAAS;;;AAIpC,QAAA,oBAAoB,CAAC,OAAO;AAC1B,YAAA,uBAAuB,EAAwB;AACjD,QAAA,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO;AACjC,QAAA,IAAI,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC;AAE5B,QAAA,OAAO,MAAK;;;;AAIV,YAAA,MAAM,aAAa,GAAG,sBAAsB,CAAC,IAAI,CAAC;AAClD,YAAA,IACE,aAAa;gBACb,aAAa,KAAK,QAAQ,CAAC,IAAI;AAC/B,gBAAA,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC9B;gBACA;YACF;AACA,YAAA,oBAAoB,CAAC,OAAO,EAAE,KAAK,IAAI;AACzC,QAAA,CAAC;;;;;;;IAOH,CAAC,EAAE,CAAC,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;;IAGtD,MAAM,qBAAqB,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CACjE,KAAK,IACH,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;AAC3B,SAAC,KAAK,CAAC,IAAI,KAAK,eAAe;YAC7B,KAAK,CAAC,IAAI,KAAK,YAAY;YAC3B,KAAK,CAAC,IAAI,KAAK,SAAS;AACxB,YAAA,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAC/B;;AAGD,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,OAAO,EAAE;AAClD,QAAA,WAAW,EAAE,aAAa;AAC3B,KAAA,CAAC;AACF,IAAA,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,CAAC;IAEnD,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC;AAE5E,IAAA,MAAM,YAAY,GAAG,IAAI,KAAK,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;IACnE,MAAM,iBAAiB,GACrB,aAAa;AACb,SAAC,aAAa,IAAI,YAAY,KAAK,cAAc,GAAG,MAAM,GAAG,SAAS,CAAC;;;;IAIzE,MAAM,OAAO,GAAG,cAAc,GAAG,gBAAgB,GAAG,SAAS;AAE7D,IAAA,IAAI,YAAgC;;IAGpC,IAAI,qBAAqB,EAAE;AACzB,QAAA,YAAY,IACVA,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,YAAY,EACvB,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,YAAY,EAAA,YAAA,EACN,iBAAiB,EAC7B,QAAQ,EAAE,EAAE,EAAA,GACR,IAAI,EAAA,aAAA,EACI,OAAO,EAAA,QAAA,EAElB,QAAQ,EAAA,CACL,CACP;IACH;SAAO;;AAEL,QAAA,IAAI,WAAoB;QACxB,IAAI,IAAI,KAAK,MAAM;YAAE,WAAW,GAAG,IAAI;aAClC,IAAI,IAAI,KAAK,SAAS;YAAE,WAAW,GAAG,KAAK;;YAC3C,WAAW,GAAG,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,aAAa;QAEtD,YAAY,IACVC,IAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,YAAY,EACvB,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,YAAY,gBACN,iBAAiB,EAAA,iBAAA,EACZ,OAAO,EACxB,QAAQ,EAAE,EAAE,EAAA,GACR,IAAI,EAAA,aAAA,EACI,OAAO,aAEnBD,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAC9D,OAAO,EAAE,OAAO,EAAA,aAAA,EACJ,kBAAkB,EAAA,CAC9B,EACD,WAAW,IACVC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,YAAY,CAAC,EAAA,QAAA,EAAA,CAC1D,cAAc,KACbA,IAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAA,QAAA,EAAA,CAE7DD,GAAA,CAAA,GAAA,EAAA,EACE,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,kBAAkB,CAC3B,WAAW,EACX,kBAAkB,CACnB,EAAA,QAAA,EAEA,cAAc,EAAA,CACb,EACH,OAAO,KACNA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,WAAW,gBACX,OAAO,EAClB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAC,QAAQ,iBACD,aAAa,EAAA,CACzB,CACH,CAAA,EAAA,CACM,CACV,EACDA,GAAA,CAAA,SAAA,EAAA,EACE,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,CAAC,iBACjD,YAAY,EAAA,QAAA,EAEvB,QAAQ,EAAA,CACD,EACT,aAAa,KACZA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAA,QAAA,EAE5D,aAAa,GACP,CACV,CAAA,EAAA,CACG,KAENA,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,eAAe,CAAC,iBAC/C,eAAe,EAAA,QAAA,EAE1B,QAAQ,EAAA,CACL,CACP,EAEA,CAAC,CAAC,WAAW,KAAK,CAAC,cAAc,IAAI,OAAO,CAAC,KAAK,OAAO,KACxDA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,kBAAkB,CAC3B,WAAW,EACX,aAAa,EACb,UAAU,CACX,EAAA,YAAA,EACU,OAAO,EAClB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAC,QAAQ,EAAA,aAAA,EACD,mBAAmB,EAAA,CAC/B,CACH,CAAA,EAAA,CACG,CACP;IACH;;AAGA,IAAA,YAAY,IACVA,GAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,OAAO,EAAA,QAAA,EACvC,YAAY,EAAA,CACc,CAC9B;IAED,IAAI,UAAU,EAAE;AACd,QAAA,MAAM,MAAM,GAAG,gBAAgB,CAC7B,OAAO,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,MAAM,CACjD;AACD,QAAA,OAAO,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC;IAC3C;AAEA,IAAA,OAAO,YAAY;AACrB,CAAC,CAAC;AAEK,MAAM,KAAK,GAAG,iBAAiB,CACpC,SAAS,EACT;AACE,IAAA,UAAU,EAAE,eAAe;AAC3B,IAAA,OAAO,EAAE,YAAY;AACrB,IAAA,IAAI,EAAE,SAAS;AACf,IAAA,KAAK,EAAE,UAAU;CAClB,EACD,OAAO;;"}
1
+ {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { buttonType } from '../helpers/buttonType';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useConfig } from '../helpers/Config';\nimport { useScrollLock } from '../helpers/scrollLock';\nimport {\n getActiveElementInTree,\n getDeepestActiveElement,\n} from '../helpers/shadowDom';\nimport { usePortalContainer } from '../helpers/portal';\nimport { LocalePortalScope } from '../helpers/LocaleProvider';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport { useOverlayStack } from '../helpers/overlayStack';\nimport { focusTabStop, trapTab } from '../helpers/useFocusTrap';\n\n/**\n * Props for the Modal component.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the root `.modal` element.\n */\nexport interface ModalProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'title'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Whether the modal is open/visible. */\n active?: boolean;\n /** Alias for `active`. Whether the modal is open/visible. */\n isActive?: boolean; // Alias for active\n /**\n * Called to ask for the modal to close. The props form calls it from the\n * background and the close button it renders. In the compound form,\n * `Modal.Close` calls it unless you give it an `onClick` of your own, and\n * `Modal.Background` doesn't call it on its own: pass it\n * `onClick={onClose}` for a click on the background to close the modal.\n * Escape calls it in both forms unless `closeOnEscape` is `false`.\n */\n onClose?: () => void;\n /** Additional CSS classes for the modal. */\n className?: string;\n /** Text color for modal content. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color for modal content. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Title/header for modal-card variant. (Legacy API only) */\n modalCardTitle?: React.ReactNode;\n /** Footer for modal-card variant. (Legacy API only) */\n modalCardFoot?: React.ReactNode;\n /**\n * Modal style: `'card'` for modal-card, `'content'` for modal-content. (Legacy API only)\n * @defaultValue auto\n */\n type?: 'card' | 'content';\n /** Modal body/content or compound components. */\n children?: React.ReactNode;\n /**\n * Close the modal when the Escape key is pressed (calls `onClose`). Only the\n * topmost open overlay responds, whichever Modal, Dialog, Sidebar or\n * full-page Loading opened last, so Escape closes one layer at a time. The\n * modal marks the Escape it closes on as used with `preventDefault()`, and\n * a Toast waits until no overlay is open. Turned off, a modal on top still\n * keeps Escape from the layers under it. A popup inside it, such as a\n * Dropdown's menu or a date picker's calendar, takes its own Escape first,\n * and so does content that calls `preventDefault()` on it.\n * @defaultValue true\n */\n closeOnEscape?: boolean;\n /**\n * Lock body scroll while the modal is active. Ref-counted and shared with\n * `Dialog`, `Sidebar` and `Loading`, so whichever overlay closes first does\n * not unlock the page underneath one that is still open.\n * @defaultValue true\n */\n lockScroll?: boolean;\n /**\n * Renders the modal into a portal target instead of inline, so it isn't\n * clipped by an ancestor with `overflow: hidden`, `filter` or `transform`.\n * `true` portals to the `portalContainer` a `ConfigProvider` sets,\n * `document.body` by default; a string is used as a\n * `document.querySelector` selector; an element is used directly. Renders\n * inline on the server and while hydrating, moving into the portal once the\n * client takes over, so hydration matches.\n * @defaultValue false\n */\n portal?: boolean | string | HTMLElement;\n}\n\n/**\n * Props for Modal.Background component.\n * @extraProp {React.MouseEventHandler<HTMLDivElement>} [onClick] - Called when the background is clicked. The background doesn't call the modal's `onClose` on its own, so pass `onClick={onClose}` for a click on it to close the modal.\n */\nexport interface ModalBackgroundProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Content component.\n */\nexport interface ModalContentProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card component.\n */\nexport interface ModalCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Head component.\n */\nexport interface ModalCardHeadProps extends React.HTMLAttributes<HTMLElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Title component.\n */\nexport interface ModalCardTitleProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Body component.\n */\nexport interface ModalCardBodyProps extends React.HTMLAttributes<HTMLElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Card.Foot component.\n */\nexport interface ModalCardFootProps extends React.HTMLAttributes<HTMLElement> {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Modal.Close component.\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 * @extraProp {React.MouseEventHandler<HTMLButtonElement>} [onClick] - Called when the button is clicked. Without one, the button calls the `onClose` of the `Modal` around it. Yours replaces that rather than running before it, so call `onClose` from it if the button should still close the modal.\n */\nexport interface ModalCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Size of the close button (only applies to 'floating' variant). */\n size?: 'small' | 'medium' | 'large';\n /** Button variant. 'delete' (default) for modal card headers, 'floating' for overlay close button. */\n variant?: 'delete' | 'floating';\n}\n\n// The enclosing modal's `onClose`, for a `Modal.Close` written as a part, so\n// it closes the modal the way the button the props form renders does.\nconst ModalCloseContext = createContext<(() => void) | undefined>(undefined);\n\n/**\n * Modal.Background - Renders the modal background overlay. Pass it\n * `onClick={onClose}` for a click on it to close the modal.\n *\n * @function\n * @param {ModalBackgroundProps} props - Component props.\n * @returns {JSX.Element} Modal background element.\n */\nconst ModalBackground: React.FC<ModalBackgroundProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-background'),\n className\n );\n return <div className={classes} {...props} />;\n};\n\n/**\n * Modal.Content - Renders modal content wrapper for custom content.\n *\n * @function\n * @param {ModalContentProps} props - Component props.\n * @returns {JSX.Element} Modal content element.\n */\nconst ModalContent: React.FC<ModalContentProps> = ({ className, ...props }) => {\n const classes = classNames(usePrefixedClassNames('modal-content'), className);\n return <div className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Head - Renders modal card header section.\n *\n * @function\n * @param {ModalCardHeadProps} props - Component props.\n * @returns {JSX.Element} Modal card header element.\n */\nconst ModalCardHead: React.FC<ModalCardHeadProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-head'),\n className\n );\n return <header className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Title - Renders modal card title.\n *\n * @function\n * @param {ModalCardTitleProps} props - Component props.\n * @returns {JSX.Element} Modal card title element.\n */\nconst ModalCardTitle: React.FC<ModalCardTitleProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-title'),\n className\n );\n return <p className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Body - Renders modal card body section.\n *\n * @function\n * @param {ModalCardBodyProps} props - Component props.\n * @returns {JSX.Element} Modal card body element.\n */\nconst ModalCardBody: React.FC<ModalCardBodyProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-body'),\n className\n );\n return <section className={classes} {...props} />;\n};\n\n/**\n * Modal.Card.Foot - Renders modal card footer section.\n *\n * @function\n * @param {ModalCardFootProps} props - Component props.\n * @returns {JSX.Element} Modal card footer element.\n */\nconst ModalCardFoot: React.FC<ModalCardFootProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(\n usePrefixedClassNames('modal-card-foot'),\n className\n );\n return <footer className={classes} {...props} />;\n};\n\n/**\n * Modal.Card - Renders modal card wrapper with compound components.\n * Use with Modal.Card.Head, Modal.Card.Title, Modal.Card.Body, and Modal.Card.Foot.\n *\n * @function\n * @param {ModalCardProps} props - Component props.\n * @returns {JSX.Element} Modal card element.\n */\nconst ModalCardComponent: React.FC<ModalCardProps> = ({\n className,\n ...props\n}) => {\n const classes = classNames(usePrefixedClassNames('modal-card'), className);\n return <div className={classes} {...props} />;\n};\n\nconst ModalCard = withSubComponents(ModalCardComponent, {\n Head: ModalCardHead,\n Title: ModalCardTitle,\n Body: ModalCardBody,\n Foot: ModalCardFoot,\n});\n\n/**\n * Modal.Close - Renders modal close button with two variant styles. It calls\n * the modal's `onClose` unless given an `onClick` of its own.\n *\n * @function\n * @param {ModalCloseProps} props - Component props.\n * @returns {JSX.Element} Close button element.\n *\n * @remarks\n * Supports two variants:\n * - 'delete' (default): For use in modal card headers, renders with 'delete' class\n * - 'floating': For floating overlay close button, renders with 'modal-close' class\n *\n * The size prop only applies to the 'floating' variant.\n */\nconst ModalClose: React.FC<ModalCloseProps> = ({\n className,\n size = 'large',\n variant = 'delete',\n onClick,\n ...props\n}) => {\n const onClose = useContext(ModalCloseContext);\n const classes = classNames(\n usePrefixedClassNames(\n variant === 'delete' ? 'delete' : 'modal-close',\n variant === 'floating' && size && { [`is-${size}`]: true }\n ),\n className\n );\n return (\n <button\n className={classes}\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 // A caller's own `onClick` replaces the close rather than running\n // before it, unlike `Popover.Close`: this button used to close only\n // through that handler, so a caller already closing there, as with\n // `onClick={onClose}`, would otherwise close twice.\n onClick={onClick ?? (onClose && (() => onClose()))}\n />\n );\n};\n\n/**\n * The `Modal` component provides an empty, accessible overlay for arbitrary content — for a ready-made confirm or alert, reach for `Dialog` instead.\n *\n * @function\n * @param {ModalProps} props - Props for the Modal component.\n * @returns {JSX.Element} The rendered modal.\n *\n * @example\n * // Legacy API\n * <Modal active={isOpen} onClose={handleClose} modalCardTitle=\"Title\">\n * Content\n * </Modal>\n *\n * @example\n * // Compound Component API\n * <Modal isActive={isOpen} onClose={handleClose}>\n * <Modal.Background onClick={handleClose} />\n * <Modal.Card>\n * <Modal.Card.Head>\n * <Modal.Card.Title>Title</Modal.Card.Title>\n * <Modal.Close />\n * </Modal.Card.Head>\n * <Modal.Card.Body>Content</Modal.Card.Body>\n * </Modal.Card>\n * </Modal>\n *\n * @see {@link https://bulma.io/documentation/components/modal/ | Bulma Modal documentation}\n */\nconst ModalRoot = forwardRef<HTMLDivElement, ModalProps>(function ModalRoot(\n {\n active,\n isActive,\n onClose,\n className,\n textColor,\n bgColor,\n modalCardTitle,\n modalCardFoot,\n type,\n children,\n closeOnEscape = true,\n lockScroll = true,\n portal = false,\n role,\n 'aria-modal': ariaModalProp,\n ...props\n },\n ref\n) {\n const { classPrefix, portalContainer } = useConfig();\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n // Support both active and isActive props\n const isModalActive = active ?? isActive ?? false;\n\n const modalRootRef = useRef<HTMLDivElement>(null);\n\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n\n // The forwarded ref and the internal one must both see the node: focus\n // management and the Tab trap read `modalRootRef`, while consumers expect\n // their own ref to resolve.\n const combinedRef = useCallback(\n (node: HTMLDivElement | null) => {\n (modalRootRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches\n // by running it instead of calling the ref with `null`; React 18\n // discards the return value entirely. Returning it from here would be\n // a React-19-only contract, so instead we hold the cleanup and run it\n // ourselves on detach — a consumer's cleanup ref then behaves the same\n // on both majors of the CI matrix. Same shape as `Dropdown`.\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<HTMLDivElement | null>).current = node;\n }\n },\n [ref]\n );\n const previouslyFocusedRef = useRef<HTMLElement | null>(null);\n const generatedTitleId = useId();\n // A portal has no server-rendered counterpart, so the server render and the\n // hydrating render have to stay inline and only move into the portal once\n // we're past hydration.\n const onClient = useIsHydrated();\n const resolveContainer = usePortalContainer();\n // Moving into the portal, or from one portal target to another, remounts\n // the modal's subtree, so any effect holding a DOM node from before the move\n // is holding a detached one. Effects that touch the modal's nodes key on\n // this, on `portal` and on `defaultTarget`, so they re-run against the new\n // tree.\n const isPortaled = Boolean(portal) && onClient;\n // The configured `portalContainer` only places a modal portaled with\n // `portal` set to `true`. In place, or with a target of its own, a change\n // to it moves nothing, so it mustn't re-run the effects either.\n const defaultTarget =\n isPortaled && portal === true ? portalContainer : undefined;\n\n useScrollLock(isModalActive && lockScroll);\n\n // Read when Escape arrives, so the key listener stays put while `onClose`\n // changes identity, as an inline one does on every render of the parent.\n const onCloseRef = useLatestRef(onClose);\n\n // Joins the stack of open overlays, so the keyboard handling below only\n // applies while this modal is on top.\n const isTopmost = useOverlayStack(isModalActive);\n\n // Escape closes, only for the topmost overlay. The listener is on\n // `window`, where a keydown arrives last, so everything inside the modal\n // has had the key first: React's handlers, and `document` listeners added\n // after this one, such as a date picker's.\n useEffect(() => {\n if (!isModalActive) return undefined;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || !isTopmost()) return;\n // Something inside already used this Escape, such as a popup that\n // closed on it, so the modal waits for the next one. One the modal\n // closes on is marked used, so nothing under it acts on it as well.\n if (closeOnEscape && onCloseRef.current && !e.defaultPrevented) {\n e.preventDefault();\n onCloseRef.current();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isModalActive, closeOnEscape, onCloseRef, isTopmost]);\n\n // Keep Tab within the modal: `aria-modal` hides the rest of the page from\n // assistive technology, so the keyboard order has to agree. Only while\n // it's the topmost modal overlay, so an overlay that isn't modal, such as\n // a Sidebar without an overlay, takes Escape from it but leaves it Tab.\n // It's the trap `useFocusTrap` sets, so it wraps at the stops Tab really\n // visits, skipping hidden, inert and closed content, and sends back a Tab\n // the browser still takes out. On `window` for the same reason as Escape:\n // a trap inside, such as a portaled popup's, has had the Tab first, and\n // one it used is left where it put focus. It reads the modal's node as\n // each key arrives, so a portal move that remounts the node, including one\n // to a selector that only starts matching while the modal is open, keeps\n // it trapped.\n useEffect(() => {\n if (!isModalActive) return undefined;\n return trapTab(\n () => modalRootRef.current,\n window,\n () => isTopmost('modal')\n );\n }, [isModalActive, isTopmost]);\n\n // Move focus into the modal on open, restore it on close\n useEffect(() => {\n if (!isModalActive) return undefined;\n\n // The element that had focus, wherever it sits: a portaled modal renders\n // under `document.body` while its opener can be inside a shadow root.\n previouslyFocusedRef.current =\n getDeepestActiveElement() as HTMLElement | null;\n const node = modalRootRef.current;\n if (node) focusTabStop(node);\n\n return () => {\n // Only hand focus back if this modal still owns it: closing a background\n // modal must not pull focus out of one that is still open on top. A\n // removed subtree leaves focus on <body>, which still counts as ours.\n const activeElement = getActiveElementInTree(node);\n if (\n activeElement &&\n activeElement !== document.body &&\n !node?.contains(activeElement)\n ) {\n return;\n }\n previouslyFocusedRef.current?.focus?.();\n };\n // `isPortaled` flips once when a hydrated portal modal moves out of the\n // inline tree, and `portal` or `defaultTarget` changing moves a portaled\n // one to another target; re-running rebinds focus onto the remounted\n // nodes. The cleanup above restores focus to the pre-open element first\n // (the detached subtree has left focus on <body>), so the re-run re-records\n // the same element and restore-on-close still lands in the right place.\n }, [isModalActive, isPortaled, portal, defaultTarget]);\n\n // Check if children contain compound components\n const hasCompoundComponents = React.Children.toArray(children).some(\n child =>\n React.isValidElement(child) &&\n (child.type === ModalBackground ||\n child.type === ModalContent ||\n child.type === ModalCard ||\n child.type === ModalClose)\n );\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('modal', {\n 'is-active': isModalActive,\n });\n const deleteClass = usePrefixedClassNames('delete');\n\n const modalClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n const resolvedRole = role ?? (isModalActive ? 'dialog' : undefined);\n const resolvedAriaModal =\n ariaModalProp ??\n (isModalActive && resolvedRole !== 'presentation' ? 'true' : undefined);\n // A dialog needs an accessible name: the legacy card title is wired up\n // automatically, compound users pass their own aria-label/aria-labelledby\n // (both arrive in `rest`, which is spread last and so wins).\n const titleId = modalCardTitle ? generatedTitleId : undefined;\n\n let modalElement: React.ReactElement;\n\n // If using compound components, render children as-is\n if (hasCompoundComponents) {\n modalElement = (\n <div\n className={modalClasses}\n ref={combinedRef}\n role={resolvedRole}\n aria-modal={resolvedAriaModal}\n tabIndex={-1}\n {...rest}\n data-testid=\"modal\"\n >\n {children}\n </div>\n );\n } else {\n // Legacy API: EXPLICIT type wins; fallback to auto detection if not provided\n let isModalCard: boolean;\n if (type === 'card') isModalCard = true;\n else if (type === 'content') isModalCard = false;\n else isModalCard = !!modalCardTitle || !!modalCardFoot;\n\n modalElement = (\n <div\n className={modalClasses}\n ref={combinedRef}\n role={resolvedRole}\n aria-modal={resolvedAriaModal}\n aria-labelledby={titleId}\n tabIndex={-1}\n {...rest}\n data-testid=\"modal\"\n >\n <div\n className={prefixedClassNames(classPrefix, 'modal-background')}\n onClick={onClose}\n data-testid=\"modal-background\"\n />\n {isModalCard ? (\n <div className={prefixedClassNames(classPrefix, 'modal-card')}>\n {modalCardTitle && (\n <header\n className={prefixedClassNames(classPrefix, 'modal-card-head')}\n >\n <p\n id={titleId}\n className={prefixedClassNames(\n classPrefix,\n 'modal-card-title'\n )}\n >\n {modalCardTitle}\n </p>\n {onClose && (\n <button\n className={deleteClass}\n aria-label=\"close\"\n onClick={onClose}\n type=\"button\"\n data-testid=\"modal-close\"\n />\n )}\n </header>\n )}\n <section\n className={prefixedClassNames(classPrefix, 'modal-card-body')}\n data-testid=\"modal-body\"\n >\n {children}\n </section>\n {modalCardFoot && (\n <footer\n className={prefixedClassNames(classPrefix, 'modal-card-foot')}\n >\n {modalCardFoot}\n </footer>\n )}\n </div>\n ) : (\n <div\n className={prefixedClassNames(classPrefix, 'modal-content')}\n data-testid=\"modal-content\"\n >\n {children}\n </div>\n )}\n {/* Show floating close button for modal-content, or for modal-card when no header */}\n {(!isModalCard || (!modalCardTitle && onClose)) && onClose && (\n <button\n className={prefixedClassNames(\n classPrefix,\n 'modal-close',\n 'is-large'\n )}\n aria-label=\"close\"\n onClick={onClose}\n type=\"button\"\n data-testid=\"modal-close-float\"\n />\n )}\n </div>\n );\n }\n\n // In both forms, so a `Modal.Close` anywhere inside closes this modal.\n modalElement = (\n <ModalCloseContext.Provider value={onClose}>\n {modalElement}\n </ModalCloseContext.Provider>\n );\n\n if (isPortaled) {\n const target = resolveContainer(\n typeof portal === 'boolean' ? undefined : portal\n );\n return createPortal(\n <LocalePortalScope target={target}>{modalElement}</LocalePortalScope>,\n target\n );\n }\n\n return modalElement;\n});\n\nexport const Modal = withSubComponents(\n ModalRoot,\n {\n Background: ModalBackground,\n Content: ModalContent,\n Card: ModalCard,\n Close: ModalClose,\n },\n 'Modal'\n);\nexport default Modal;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -5,6 +5,7 @@ import { classNames, usePrefixedClassNames } from '../helpers/classNames.js';
5
5
  import { withSubComponents } from '../helpers/withSubComponents.js';
6
6
  import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
7
7
  import { warnDeprecatedColorProp } from '../helpers/colorDeprecations.js';
8
+ import { useNumberFormat } from '../helpers/localeFormat.js';
8
9
 
9
10
  /** A count read as a whole number from zero, or `fallback` when it's no number. */
10
11
  function whole(count, fallback) {
@@ -82,6 +83,7 @@ const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded,
82
83
  backgroundColor: bgColor,
83
84
  ...props,
84
85
  });
86
+ const formatNumber = useNumberFormat();
85
87
  // Generate Bulma classes with prefix
86
88
  const bulmaClasses = usePrefixedClassNames('pagination', {
87
89
  [`is-${color}`]: color,
@@ -124,7 +126,13 @@ const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded,
124
126
  });
125
127
  const atStart = disabled || page <= 1;
126
128
  const atEnd = disabled || page >= pages;
127
- content = (jsxs(Fragment, { children: [jsx(PaginationPrevious, { disabled: atStart, ...linkTo(page - 1, atStart), children: previousLabel }), jsx(PaginationNext, { disabled: atEnd, ...linkTo(page + 1, atEnd), children: nextLabel }), jsx(PaginationList, { children: pageItems(pages, page, whole(siblingCount, 1), whole(boundaryCount, 1)).map(item => typeof item === 'number' ? (jsx(PaginationLink, { "aria-label": getPageLabel ? getPageLabel(item) : `Page ${item}`, active: item === page, disabled: disabled, ...linkTo(item, Boolean(disabled)), children: item }, item)) : (jsx(PaginationEllipsis, {}, item))) })] }));
129
+ content = (jsxs(Fragment, { children: [jsx(PaginationPrevious, { disabled: atStart, ...linkTo(page - 1, atStart), children: previousLabel }), jsx(PaginationNext, { disabled: atEnd, ...linkTo(page + 1, atEnd), children: nextLabel }), jsx(PaginationList, { children: pageItems(pages, page, whole(siblingCount, 1), whole(boundaryCount, 1)).map(item => {
130
+ if (typeof item !== 'number') {
131
+ return jsx(PaginationEllipsis, {}, item);
132
+ }
133
+ const shown = formatNumber ? formatNumber(item) : item;
134
+ return (jsx(PaginationLink, { "aria-label": getPageLabel ? getPageLabel(item) : `Page ${shown}`, active: item === page, disabled: disabled, ...linkTo(item, Boolean(disabled)), children: shown }, item));
135
+ }) })] }));
128
136
  }
129
137
  return (jsx("nav", { className: paginationClasses, role: "navigation", "aria-label": "pagination", ...rest, children: content }));
130
138
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.js","sources":["../../../src/components/Pagination.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnDeprecatedColorProp } from '../helpers/colorDeprecations';\n\n/**\n * Props for the Pagination component.\n */\nexport interface PaginationProps\n extends\n React.HTMLAttributes<HTMLElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * Color modifier for the pagination (renders `is-<color>`).\n *\n * Bulma ships no pagination color CSS, so this prop has never had a visual\n * effect for any value. Passing it logs a console warning in development.\n * Use `textColor` / `bgColor` instead.\n * @deprecated No `.pagination.is-<color>` CSS exists; the prop renders\n * unstyled and will be removed in the next major version.\n */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Size modifier for the pagination. */\n size?: 'small' | 'medium' | 'large';\n /** Alignment for the pagination. */\n align?: 'centered' | 'right';\n /** Renders pagination with rounded corners. */\n rounded?: boolean;\n /**\n * The number of pages. Given `total` and no children, `Pagination` renders\n * the whole control itself: Previous, Next and a link for each page it\n * shows, with an ellipsis where it skips some. Given children, it renders\n * those as they are, and `total` and the other page props do nothing.\n */\n total?: number;\n /**\n * The page shown as current, counting from 1, when rendering from `total`.\n * Leave it out and `Pagination` keeps the page itself, starting at 1.\n */\n current?: number;\n /**\n * Called with the page chosen, when rendering from `total`. Choosing the\n * page already current doesn't call it.\n */\n onPageChange?: (page: number) => void;\n /** How many pages to show on each side of the current one, when rendering from `total`. */\n siblingCount?: number;\n /** How many pages to always show at the start and at the end, when rendering from `total`. */\n boundaryCount?: number;\n /** The Previous link's content, when rendering from `total`. */\n previousLabel?: React.ReactNode;\n /** The Next link's content, when rendering from `total`. */\n nextLabel?: React.ReactNode;\n /** Disables every link, when rendering from `total`. */\n disabled?: boolean;\n /**\n * The `href` for a page's link, when rendering from `total`, making each\n * one a real link (`page => '?page=' + page`). A click then calls\n * `onPageChange` and the browser follows the link too. Without it the\n * links have no `href`, act as buttons, and Enter or Space chooses a page.\n */\n getPageHref?: (page: number) => string;\n /**\n * The accessible name of a page's link, when rendering from `total`, since\n * its content is only the number (`page => 'Page ' + page` by default).\n */\n getPageLabel?: (page: number) => string;\n /** Additional CSS classes. */\n className?: string;\n /** Custom pagination content (usually subcomponents). */\n children?: React.ReactNode;\n}\n\n/** A page's number, or a run of pages left out. */\ntype PageItem = number | 'start-gap' | 'end-gap';\n\n/** A count read as a whole number from zero, or `fallback` when it's no number. */\nfunction whole(count: number, fallback: number): number {\n return Number.isFinite(count) ? Math.max(Math.floor(count), 0) : fallback;\n}\n\nfunction range(from: number, to: number): number[] {\n return Array.from({ length: Math.max(to - from + 1, 0) }, (_, i) => from + i);\n}\n\n/**\n * The pages to show for `current` of `total`: the first and last\n * `boundaries`, `siblings` on each side of the current one, and a gap for\n * each run left out. A gap of a single page shows that page instead, and the\n * window around the current page slides inward near either end, so the row\n * keeps its length as the page moves.\n */\nfunction pageItems(\n total: number,\n current: number,\n siblings: number,\n boundaries: number\n): PageItem[] {\n const windowSize = siblings * 2 + 1;\n // Every page fits in the room the boundary pages, the window and two gaps take.\n if (total <= boundaries * 2 + windowSize + 2) return range(1, total);\n const lowest = boundaries + 2;\n const highest = total - boundaries - 1;\n const start = Math.min(\n Math.max(current - siblings, lowest),\n highest - windowSize + 1\n );\n const end = start + windowSize - 1;\n const gap = (from: number, to: number, name: PageItem): PageItem[] =>\n to === from ? [from] : [name];\n return [\n ...range(1, boundaries),\n ...gap(boundaries + 1, start - 1, 'start-gap'),\n ...range(start, end),\n ...gap(end + 1, total - boundaries, 'end-gap'),\n ...range(total - boundaries + 1, total),\n ];\n}\n\n/**\n * Props for PaginationPrevious and PaginationNext components.\n */\nexport interface PaginationPreviousNextProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Whether previous/next is disabled. */\n disabled?: boolean;\n /** Button content. */\n children?: React.ReactNode;\n}\n\n/**\n * \"Previous\" navigation button.\n *\n * @function\n * @param {PaginationPreviousNextProps} props - Props for the PaginationPrevious component.\n * @returns {JSX.Element} The rendered previous button.\n */\nexport const PaginationPrevious: React.FC<PaginationPreviousNextProps> = ({\n className,\n disabled,\n children,\n ...props\n}) => (\n <a\n className={classNames(\n usePrefixedClassNames('pagination-previous', {\n 'is-disabled': disabled,\n }),\n className\n )}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n {...props}\n onClick={\n disabled\n ? e => {\n e.preventDefault();\n e.stopPropagation();\n }\n : props.onClick\n }\n >\n {children}\n </a>\n);\n\n/**\n * \"Next\" navigation button.\n *\n * @function\n * @param {PaginationPreviousNextProps} props - Props for the PaginationNext component.\n * @returns {JSX.Element} The rendered next button.\n */\nexport const PaginationNext: React.FC<PaginationPreviousNextProps> = ({\n className,\n disabled,\n children,\n ...props\n}) => (\n <a\n className={classNames(\n usePrefixedClassNames('pagination-next', { 'is-disabled': disabled }),\n className\n )}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n {...props}\n onClick={\n disabled\n ? e => {\n e.preventDefault();\n e.stopPropagation();\n }\n : props.onClick\n }\n >\n {children}\n </a>\n);\n\n/**\n * The `Pagination` component provides a flexible, composable Bulma pagination navigation for your Bulma React UI.\n *\n * @function\n * @param {PaginationProps} props - Props for the Pagination component.\n * @returns {JSX.Element} The rendered pagination.\n * @see {@link https://bulma.io/documentation/components/pagination/ | Bulma Pagination documentation}\n */\nconst PaginationComponent: React.FC<PaginationProps> = ({\n color,\n textColor,\n bgColor,\n size,\n align,\n rounded,\n total,\n current,\n onPageChange,\n siblingCount = 1,\n boundaryCount = 1,\n previousLabel = 'Previous',\n nextLabel = 'Next',\n disabled,\n getPageHref,\n getPageLabel,\n className,\n children,\n ...props\n}) => {\n const [kept, setKept] = React.useState(1);\n warnDeprecatedColorProp(\n 'Pagination',\n color,\n 'Use the textColor / bgColor helper props instead.'\n );\n\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('pagination', {\n [`is-${color}`]: color,\n [`is-${size}`]: size,\n [`is-${align}`]: align,\n 'is-rounded': rounded,\n });\n\n const paginationClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n // A child that renders nothing (`{show && …}` when false) is no children.\n const fromTotal =\n total !== undefined && React.Children.toArray(children).length === 0;\n let content: React.ReactNode = children;\n if (fromTotal) {\n const pages = Number.isFinite(total) ? Math.max(Math.floor(total), 0) : 0;\n // A current page that's no number reads as the first.\n const page = Math.min(\n Math.max(whole(current ?? kept, 1), 1),\n Math.max(pages, 1)\n );\n const choose = (next: number) => {\n if (next === page) return;\n if (current === undefined) setKept(next);\n onPageChange?.(next);\n };\n /**\n * What a link to `target` is given, beside what it renders. With no\n * `getPageHref` it's a button; a link that's `off` goes nowhere.\n */\n const linkTo = (target: number, off: boolean) => ({\n href: off || !getPageHref ? undefined : getPageHref(target),\n role: getPageHref ? undefined : 'button',\n // A link that's off is disabled too, and the parts drop its clicks.\n onClick: () => choose(target),\n onKeyDown: getPageHref\n ? undefined\n : (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n if (off || (e.key !== 'Enter' && e.key !== ' ')) return;\n e.preventDefault();\n choose(target);\n },\n });\n const atStart = disabled || page <= 1;\n const atEnd = disabled || page >= pages;\n content = (\n <>\n <PaginationPrevious disabled={atStart} {...linkTo(page - 1, atStart)}>\n {previousLabel}\n </PaginationPrevious>\n <PaginationNext disabled={atEnd} {...linkTo(page + 1, atEnd)}>\n {nextLabel}\n </PaginationNext>\n <PaginationList>\n {pageItems(\n pages,\n page,\n whole(siblingCount, 1),\n whole(boundaryCount, 1)\n ).map(item =>\n typeof item === 'number' ? (\n <PaginationLink\n key={item}\n aria-label={getPageLabel ? getPageLabel(item) : `Page ${item}`}\n active={item === page}\n disabled={disabled}\n {...linkTo(item, Boolean(disabled))}\n >\n {item}\n </PaginationLink>\n ) : (\n <PaginationEllipsis key={item} />\n )\n )}\n </PaginationList>\n </>\n );\n }\n\n return (\n <nav\n className={paginationClasses}\n role=\"navigation\"\n aria-label=\"pagination\"\n {...rest}\n >\n {content}\n </nav>\n );\n};\n\n/**\n * Props for the PaginationList component.\n */\nexport interface PaginationListProps\n extends\n React.HTMLAttributes<HTMLUListElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the list. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color modifier for the list. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the list. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** List items. */\n children?: React.ReactNode;\n}\n\n/**\n * Container for page links and ellipsis.\n *\n * @function\n * @param {PaginationListProps} props - Props for the PaginationList component.\n * @returns {JSX.Element} The rendered pagination list.\n */\nexport const PaginationList: React.FC<PaginationListProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n return (\n <ul\n className={classNames(\n usePrefixedClassNames('pagination-list'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </ul>\n );\n};\n\n/**\n * Props for the PaginationLink component.\n */\nexport interface PaginationLinkProps\n extends\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Bulma color modifier. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the link is for the current page. */\n active?: boolean;\n /** Whether the link is disabled. */\n disabled?: boolean;\n /** Link content. */\n children?: React.ReactNode;\n}\n\n/**\n * Page number or navigation link.\n *\n * @function\n * @param {PaginationLinkProps} props - Props for the PaginationLink component.\n * @returns {JSX.Element} The rendered pagination link.\n */\nexport const PaginationLink: React.FC<PaginationLinkProps> = ({\n className,\n textColor,\n bgColor,\n active,\n disabled,\n onClick,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (onClick) {\n onClick(e);\n }\n };\n\n return (\n <li>\n <a\n className={classNames(\n usePrefixedClassNames('pagination-link', {\n 'is-current': active,\n 'is-disabled': disabled,\n }),\n bulmaHelperClasses,\n className\n )}\n aria-current={active ? 'page' : undefined}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n onClick={handleClick}\n {...rest}\n >\n {children}\n </a>\n </li>\n );\n};\n\n/**\n * Ellipsis separator.\n *\n * @function\n * @param {React.LiHTMLAttributes<HTMLLIElement>} props - Standard li props.\n * @returns {JSX.Element} The rendered ellipsis.\n */\nexport const PaginationEllipsis: React.FC<\n React.LiHTMLAttributes<HTMLLIElement>\n> = props => (\n <li>\n <span className={usePrefixedClassNames('pagination-ellipsis')} {...props}>\n &hellip;\n </span>\n </li>\n);\n\nexport const Pagination = withSubComponents(\n PaginationComponent,\n {\n Link: PaginationLink,\n List: PaginationList,\n Ellipsis: PaginationEllipsis,\n Previous: PaginationPrevious,\n Next: PaginationNext,\n },\n 'Pagination'\n);\n\nexport default Pagination;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination.js","sources":["../../../src/components/Pagination.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnDeprecatedColorProp } from '../helpers/colorDeprecations';\nimport { useNumberFormat } from '../helpers/localeFormat';\n\n/**\n * Props for the Pagination component.\n */\nexport interface PaginationProps\n extends\n React.HTMLAttributes<HTMLElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * Color modifier for the pagination (renders `is-<color>`).\n *\n * Bulma ships no pagination color CSS, so this prop has never had a visual\n * effect for any value. Passing it logs a console warning in development.\n * Use `textColor` / `bgColor` instead.\n * @deprecated No `.pagination.is-<color>` CSS exists; the prop renders\n * unstyled and will be removed in the next major version.\n */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Size modifier for the pagination. */\n size?: 'small' | 'medium' | 'large';\n /** Alignment for the pagination. */\n align?: 'centered' | 'right';\n /** Renders pagination with rounded corners. */\n rounded?: boolean;\n /**\n * The number of pages. Given `total` and no children, `Pagination` renders\n * the whole control itself: Previous, Next and a link for each page it\n * shows, with an ellipsis where it skips some. Given children, it renders\n * those as they are, and `total` and the other page props do nothing.\n */\n total?: number;\n /**\n * The page shown as current, counting from 1, when rendering from `total`.\n * Leave it out and `Pagination` keeps the page itself, starting at 1.\n */\n current?: number;\n /**\n * Called with the page chosen, when rendering from `total`. Choosing the\n * page already current doesn't call it.\n */\n onPageChange?: (page: number) => void;\n /** How many pages to show on each side of the current one, when rendering from `total`. */\n siblingCount?: number;\n /** How many pages to always show at the start and at the end, when rendering from `total`. */\n boundaryCount?: number;\n /** The Previous link's content, when rendering from `total`. */\n previousLabel?: React.ReactNode;\n /** The Next link's content, when rendering from `total`. */\n nextLabel?: React.ReactNode;\n /** Disables every link, when rendering from `total`. */\n disabled?: boolean;\n /**\n * The `href` for a page's link, when rendering from `total`, making each\n * one a real link (`page => '?page=' + page`). A click then calls\n * `onPageChange` and the browser follows the link too. Without it the\n * links have no `href`, act as buttons, and Enter or Space chooses a page.\n */\n getPageHref?: (page: number) => string;\n /**\n * The accessible name of a page's link, when rendering from `total`, since\n * its content is only the number (`page => 'Page ' + page` by default).\n * Inside a `LocaleProvider` with a `locale`, the number on the link, and\n * in the default name, is written the way that locale writes numbers, so\n * the name still holds the text on screen.\n */\n getPageLabel?: (page: number) => string;\n /** Additional CSS classes. */\n className?: string;\n /** Custom pagination content (usually subcomponents). */\n children?: React.ReactNode;\n}\n\n/** A page's number, or a run of pages left out. */\ntype PageItem = number | 'start-gap' | 'end-gap';\n\n/** A count read as a whole number from zero, or `fallback` when it's no number. */\nfunction whole(count: number, fallback: number): number {\n return Number.isFinite(count) ? Math.max(Math.floor(count), 0) : fallback;\n}\n\nfunction range(from: number, to: number): number[] {\n return Array.from({ length: Math.max(to - from + 1, 0) }, (_, i) => from + i);\n}\n\n/**\n * The pages to show for `current` of `total`: the first and last\n * `boundaries`, `siblings` on each side of the current one, and a gap for\n * each run left out. A gap of a single page shows that page instead, and the\n * window around the current page slides inward near either end, so the row\n * keeps its length as the page moves.\n */\nfunction pageItems(\n total: number,\n current: number,\n siblings: number,\n boundaries: number\n): PageItem[] {\n const windowSize = siblings * 2 + 1;\n // Every page fits in the room the boundary pages, the window and two gaps take.\n if (total <= boundaries * 2 + windowSize + 2) return range(1, total);\n const lowest = boundaries + 2;\n const highest = total - boundaries - 1;\n const start = Math.min(\n Math.max(current - siblings, lowest),\n highest - windowSize + 1\n );\n const end = start + windowSize - 1;\n const gap = (from: number, to: number, name: PageItem): PageItem[] =>\n to === from ? [from] : [name];\n return [\n ...range(1, boundaries),\n ...gap(boundaries + 1, start - 1, 'start-gap'),\n ...range(start, end),\n ...gap(end + 1, total - boundaries, 'end-gap'),\n ...range(total - boundaries + 1, total),\n ];\n}\n\n/**\n * Props for PaginationPrevious and PaginationNext components.\n */\nexport interface PaginationPreviousNextProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Whether previous/next is disabled. */\n disabled?: boolean;\n /** Button content. */\n children?: React.ReactNode;\n}\n\n/**\n * \"Previous\" navigation button.\n *\n * @function\n * @param {PaginationPreviousNextProps} props - Props for the PaginationPrevious component.\n * @returns {JSX.Element} The rendered previous button.\n */\nexport const PaginationPrevious: React.FC<PaginationPreviousNextProps> = ({\n className,\n disabled,\n children,\n ...props\n}) => (\n <a\n className={classNames(\n usePrefixedClassNames('pagination-previous', {\n 'is-disabled': disabled,\n }),\n className\n )}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n {...props}\n onClick={\n disabled\n ? e => {\n e.preventDefault();\n e.stopPropagation();\n }\n : props.onClick\n }\n >\n {children}\n </a>\n);\n\n/**\n * \"Next\" navigation button.\n *\n * @function\n * @param {PaginationPreviousNextProps} props - Props for the PaginationNext component.\n * @returns {JSX.Element} The rendered next button.\n */\nexport const PaginationNext: React.FC<PaginationPreviousNextProps> = ({\n className,\n disabled,\n children,\n ...props\n}) => (\n <a\n className={classNames(\n usePrefixedClassNames('pagination-next', { 'is-disabled': disabled }),\n className\n )}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n {...props}\n onClick={\n disabled\n ? e => {\n e.preventDefault();\n e.stopPropagation();\n }\n : props.onClick\n }\n >\n {children}\n </a>\n);\n\n/**\n * The `Pagination` component provides a flexible, composable Bulma pagination navigation for your Bulma React UI.\n *\n * @function\n * @param {PaginationProps} props - Props for the Pagination component.\n * @returns {JSX.Element} The rendered pagination.\n * @see {@link https://bulma.io/documentation/components/pagination/ | Bulma Pagination documentation}\n */\nconst PaginationComponent: React.FC<PaginationProps> = ({\n color,\n textColor,\n bgColor,\n size,\n align,\n rounded,\n total,\n current,\n onPageChange,\n siblingCount = 1,\n boundaryCount = 1,\n previousLabel = 'Previous',\n nextLabel = 'Next',\n disabled,\n getPageHref,\n getPageLabel,\n className,\n children,\n ...props\n}) => {\n const [kept, setKept] = React.useState(1);\n warnDeprecatedColorProp(\n 'Pagination',\n color,\n 'Use the textColor / bgColor helper props instead.'\n );\n\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n const formatNumber = useNumberFormat();\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('pagination', {\n [`is-${color}`]: color,\n [`is-${size}`]: size,\n [`is-${align}`]: align,\n 'is-rounded': rounded,\n });\n\n const paginationClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n // A child that renders nothing (`{show && …}` when false) is no children.\n const fromTotal =\n total !== undefined && React.Children.toArray(children).length === 0;\n let content: React.ReactNode = children;\n if (fromTotal) {\n const pages = Number.isFinite(total) ? Math.max(Math.floor(total), 0) : 0;\n // A current page that's no number reads as the first.\n const page = Math.min(\n Math.max(whole(current ?? kept, 1), 1),\n Math.max(pages, 1)\n );\n const choose = (next: number) => {\n if (next === page) return;\n if (current === undefined) setKept(next);\n onPageChange?.(next);\n };\n /**\n * What a link to `target` is given, beside what it renders. With no\n * `getPageHref` it's a button; a link that's `off` goes nowhere.\n */\n const linkTo = (target: number, off: boolean) => ({\n href: off || !getPageHref ? undefined : getPageHref(target),\n role: getPageHref ? undefined : 'button',\n // A link that's off is disabled too, and the parts drop its clicks.\n onClick: () => choose(target),\n onKeyDown: getPageHref\n ? undefined\n : (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n if (off || (e.key !== 'Enter' && e.key !== ' ')) return;\n e.preventDefault();\n choose(target);\n },\n });\n const atStart = disabled || page <= 1;\n const atEnd = disabled || page >= pages;\n content = (\n <>\n <PaginationPrevious disabled={atStart} {...linkTo(page - 1, atStart)}>\n {previousLabel}\n </PaginationPrevious>\n <PaginationNext disabled={atEnd} {...linkTo(page + 1, atEnd)}>\n {nextLabel}\n </PaginationNext>\n <PaginationList>\n {pageItems(\n pages,\n page,\n whole(siblingCount, 1),\n whole(boundaryCount, 1)\n ).map(item => {\n if (typeof item !== 'number') {\n return <PaginationEllipsis key={item} />;\n }\n const shown = formatNumber ? formatNumber(item) : item;\n return (\n <PaginationLink\n key={item}\n aria-label={getPageLabel ? getPageLabel(item) : `Page ${shown}`}\n active={item === page}\n disabled={disabled}\n {...linkTo(item, Boolean(disabled))}\n >\n {shown}\n </PaginationLink>\n );\n })}\n </PaginationList>\n </>\n );\n }\n\n return (\n <nav\n className={paginationClasses}\n role=\"navigation\"\n aria-label=\"pagination\"\n {...rest}\n >\n {content}\n </nav>\n );\n};\n\n/**\n * Props for the PaginationList component.\n */\nexport interface PaginationListProps\n extends\n React.HTMLAttributes<HTMLUListElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the list. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color modifier for the list. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the list. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** List items. */\n children?: React.ReactNode;\n}\n\n/**\n * Container for page links and ellipsis.\n *\n * @function\n * @param {PaginationListProps} props - Props for the PaginationList component.\n * @returns {JSX.Element} The rendered pagination list.\n */\nexport const PaginationList: React.FC<PaginationListProps> = ({\n className,\n textColor,\n bgColor,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n return (\n <ul\n className={classNames(\n usePrefixedClassNames('pagination-list'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </ul>\n );\n};\n\n/**\n * Props for the PaginationLink component.\n */\nexport interface PaginationLinkProps\n extends\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Bulma color modifier. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the link is for the current page. */\n active?: boolean;\n /** Whether the link is disabled. */\n disabled?: boolean;\n /** Link content. */\n children?: React.ReactNode;\n}\n\n/**\n * Page number or navigation link.\n *\n * @function\n * @param {PaginationLinkProps} props - Props for the PaginationLink component.\n * @returns {JSX.Element} The rendered pagination link.\n */\nexport const PaginationLink: React.FC<PaginationLinkProps> = ({\n className,\n textColor,\n bgColor,\n active,\n disabled,\n onClick,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (onClick) {\n onClick(e);\n }\n };\n\n return (\n <li>\n <a\n className={classNames(\n usePrefixedClassNames('pagination-link', {\n 'is-current': active,\n 'is-disabled': disabled,\n }),\n bulmaHelperClasses,\n className\n )}\n aria-current={active ? 'page' : undefined}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n onClick={handleClick}\n {...rest}\n >\n {children}\n </a>\n </li>\n );\n};\n\n/**\n * Ellipsis separator.\n *\n * @function\n * @param {React.LiHTMLAttributes<HTMLLIElement>} props - Standard li props.\n * @returns {JSX.Element} The rendered ellipsis.\n */\nexport const PaginationEllipsis: React.FC<\n React.LiHTMLAttributes<HTMLLIElement>\n> = props => (\n <li>\n <span className={usePrefixedClassNames('pagination-ellipsis')} {...props}>\n &hellip;\n </span>\n </li>\n);\n\nexport const Pagination = withSubComponents(\n PaginationComponent,\n {\n Link: PaginationLink,\n List: PaginationList,\n Ellipsis: PaginationEllipsis,\n Previous: PaginationPrevious,\n Next: PaginationNext,\n },\n 'Pagination'\n);\n\nexport default Pagination;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
7
7
  import { withSubComponents } from '../helpers/withSubComponents.js';
8
8
  import { useScrollLock } from '../helpers/scrollLock.js';
9
9
  import { usePortalContainer } from '../helpers/portal.js';
10
+ import { LocalePortalScope } from '../helpers/LocaleProvider.js';
10
11
  import { useConfig } from '../helpers/Config.js';
11
12
  import { buttonType } from '../helpers/buttonType.js';
12
13
  import { useLatestRef } from '../helpers/useLatestRef.js';
@@ -200,7 +201,8 @@ const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width
200
201
  }
201
202
  // Render to portal for proper stacking
202
203
  if (typeof document !== 'undefined') {
203
- return createPortal(sidebarContent, resolveContainer());
204
+ const target = resolveContainer();
205
+ return createPortal(jsx(LocalePortalScope, { target: target, children: sidebarContent }), target);
204
206
  }
205
207
  return null;
206
208
  });
@@ -1 +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 { usePortalContainer } from '../helpers/portal';\nimport { useConfig } from '../helpers/Config';\nimport { buttonType } from '../helpers/buttonType';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport { isModalOverlayOpen, useOverlayStack } from '../helpers/overlayStack';\nimport { focusTabStop, trapTab } from '../helpers/useFocusTrap';\nimport { inertProps } from '../helpers/inertProps';\nimport {\n getActiveElementInTree,\n getDeepestActiveElement,\n} from '../helpers/shadowDom';\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 /**\n * Whether the sidebar is open (required). Opening moves focus into the\n * sidebar, to its first tab stop or the sidebar itself, except for a sidebar\n * without an overlay opened while a modal overlay, such as a Modal, is open:\n * that one leaves focus where it is. That's decided as it opens, and\n * changing `overlay` while it's open doesn't move focus. Closing hands\n * focus back to whatever had it when the sidebar opened, unless focus has\n * already left the sidebar, as it does for an overlay opened over it. A\n * closed sidebar stays in the page, so it can slide out, and is `inert` and\n * `aria-hidden` there: Tab passes over its content and assistive\n * technology doesn't read it.\n */\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 /**\n * Show an overlay behind the sidebar, which makes it modal: it gets\n * `aria-modal=\"true\"`, locks body scroll, and keeps Tab and Shift+Tab\n * inside it while it is the topmost modal overlay. A Modal or Dialog opened\n * over it, even one rendered inside it, holds Tab until it closes. Without\n * an overlay the sidebar isn't modal and holds no Tab: on the page, Tab\n * moves in and out of it freely, and opened over a Modal, it leaves the\n * Modal holding Tab, and focus, while still taking Escape first. Whether\n * the sidebar takes focus is decided as it opens: changing this while it's\n * open moves the Tab trap, not focus. Default: true.\n */\n overlay?: boolean;\n /** Close sidebar when overlay is clicked. Default: true. */\n overlayClose?: boolean;\n /**\n * Close sidebar on Escape key. Only the topmost open overlay responds,\n * whichever Modal, Dialog, Sidebar or full-page Loading opened last, so\n * Escape closes one layer at a time. The sidebar marks the Escape it closes\n * on as used with `preventDefault()`, and a Toast waits until no overlay is\n * open. Turned off, a sidebar on top still keeps Escape from the layers\n * under it. A popup inside it, such as a Dropdown's menu or a date picker's\n * calendar, takes its own Escape first, and so does content that calls\n * `preventDefault()` on it. Default: true.\n */\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 resolveContainer = usePortalContainer();\n const { portalContainer } = useConfig();\n // Where the configured default puts the sidebar. An `inline` one doesn't\n // portal, so a change to the default moves nothing.\n const defaultTarget = inline ? undefined : portalContainer;\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 // Read when Escape arrives, so the key listener stays put while\n // `onClose` changes identity, as an inline one does on every render of\n // the parent.\n const handleCloseRef = useLatestRef(handleClose);\n\n // Joins the stack of open overlays, so the sidebar answers Escape only\n // while it's the topmost overlay, and keeps it from those under it. It's\n // modal with an overlay: without one it leaves Tab to a modal overlay\n // under it.\n const isTopmost = useOverlayStack(isOpen, overlay);\n const closesOnEscape = escapeClose && canCancel && Boolean(onClose);\n\n // Handle escape key. On `window`, as in `Modal`, so everything inside the\n // sidebar has had the key first, and an Escape it used is left to it. One\n // the sidebar closes on is marked used, so nothing under it acts on it.\n useEffect(() => {\n if (!isOpen || !closesOnEscape) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || e.defaultPrevented || !isTopmost()) return;\n e.preventDefault();\n handleCloseRef.current();\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, closesOnEscape, handleCloseRef, isTopmost]);\n\n // Keep Tab inside while there's an overlay, as `Modal` does:\n // `aria-modal` hides the rest of the page from assistive technology, so\n // the keyboard order has to agree. Only while it's the topmost modal\n // overlay, so a Modal or Dialog opened over the sidebar, even one\n // rendered inside it, holds Tab instead until it closes, and a sidebar\n // without an overlay opened over it doesn't. On `window` for the same\n // reason as Escape: a trap inside, such as a portaled popup's, has had\n // the Tab first, and one it used is left where it put focus. It's the trap\n // `useFocusTrap` sets, so a Tab the browser still takes out, as Safari\n // does past links, is sent back in. It reads the aside as each key\n // arrives, so one remounted while the sidebar is open, by a new portal\n // target or by switching `inline`, stays trapped.\n useEffect(() => {\n if (!isOpen || !overlay) return undefined;\n return trapTab(\n () => sidebarRef.current,\n window,\n () => isTopmost('modal')\n );\n }, [isOpen, overlay, isTopmost]);\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 // Move focus into the sidebar on open, to the first stop Tab wraps to or\n // the sidebar itself, and hand it back on close, as `Modal` does. A\n // different `defaultTarget` remounts the portaled sidebar: the cleanup\n // hands focus back from the old nodes, which left it on <body>, and the\n // re-run records the same opener and focuses the new nodes. Whether it\n // takes focus is decided as it opens, so `overlay` changing while it's\n // open leaves focus where the user has it.\n useEffect(() => {\n if (!isOpen) return undefined;\n const element = sidebarRef.current;\n /* istanbul ignore if: the aside renders whenever the sidebar is open, so its ref is set before this runs */\n if (!element) return undefined;\n\n // The element that had focus, wherever it sits: a portaled sidebar\n // renders under `document.body` while its opener can be inside a\n // shadow root.\n const opener = getDeepestActiveElement() as HTMLElement | null;\n // Without an overlay the sidebar holds no Tab, so with a modal overlay\n // open under it, the first Tab would take focus back there and leave\n // the sidebar's other controls out of reach. It leaves focus alone\n // then, and the cleanup below finds focus outside and leaves it too.\n if (overlay || !isModalOverlayOpen()) {\n focusTabStop(element);\n }\n\n return () => {\n // Only while the sidebar still holds focus: closing one under another\n // overlay mustn't pull focus out of the one on top, and focus moved\n // out to the page stays there. A removed subtree leaves focus on\n // <body>, which still counts as held.\n const active = getActiveElementInTree(element);\n if (active === document.body || element.contains(active)) {\n opener?.focus();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `overlay` is read as the sidebar opens, on purpose\n }, [isOpen, defaultTarget]);\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 // React commits this before the effect that moves focus in runs, so\n // an opening sidebar is no longer inert by then.\n {...inertProps(!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, resolveContainer());\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":"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"}
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 { usePortalContainer } from '../helpers/portal';\nimport { LocalePortalScope } from '../helpers/LocaleProvider';\nimport { useConfig } from '../helpers/Config';\nimport { buttonType } from '../helpers/buttonType';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport { isModalOverlayOpen, useOverlayStack } from '../helpers/overlayStack';\nimport { focusTabStop, trapTab } from '../helpers/useFocusTrap';\nimport { inertProps } from '../helpers/inertProps';\nimport {\n getActiveElementInTree,\n getDeepestActiveElement,\n} from '../helpers/shadowDom';\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 /**\n * Whether the sidebar is open (required). Opening moves focus into the\n * sidebar, to its first tab stop or the sidebar itself, except for a sidebar\n * without an overlay opened while a modal overlay, such as a Modal, is open:\n * that one leaves focus where it is. That's decided as it opens, and\n * changing `overlay` while it's open doesn't move focus. Closing hands\n * focus back to whatever had it when the sidebar opened, unless focus has\n * already left the sidebar, as it does for an overlay opened over it. A\n * closed sidebar stays in the page, so it can slide out, and is `inert` and\n * `aria-hidden` there: Tab passes over its content and assistive\n * technology doesn't read it.\n */\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 /**\n * Show an overlay behind the sidebar, which makes it modal: it gets\n * `aria-modal=\"true\"`, locks body scroll, and keeps Tab and Shift+Tab\n * inside it while it is the topmost modal overlay. A Modal or Dialog opened\n * over it, even one rendered inside it, holds Tab until it closes. Without\n * an overlay the sidebar isn't modal and holds no Tab: on the page, Tab\n * moves in and out of it freely, and opened over a Modal, it leaves the\n * Modal holding Tab, and focus, while still taking Escape first. Whether\n * the sidebar takes focus is decided as it opens: changing this while it's\n * open moves the Tab trap, not focus. Default: true.\n */\n overlay?: boolean;\n /** Close sidebar when overlay is clicked. Default: true. */\n overlayClose?: boolean;\n /**\n * Close sidebar on Escape key. Only the topmost open overlay responds,\n * whichever Modal, Dialog, Sidebar or full-page Loading opened last, so\n * Escape closes one layer at a time. The sidebar marks the Escape it closes\n * on as used with `preventDefault()`, and a Toast waits until no overlay is\n * open. Turned off, a sidebar on top still keeps Escape from the layers\n * under it. A popup inside it, such as a Dropdown's menu or a date picker's\n * calendar, takes its own Escape first, and so does content that calls\n * `preventDefault()` on it. Default: true.\n */\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 resolveContainer = usePortalContainer();\n const { portalContainer } = useConfig();\n // Where the configured default puts the sidebar. An `inline` one doesn't\n // portal, so a change to the default moves nothing.\n const defaultTarget = inline ? undefined : portalContainer;\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 // Read when Escape arrives, so the key listener stays put while\n // `onClose` changes identity, as an inline one does on every render of\n // the parent.\n const handleCloseRef = useLatestRef(handleClose);\n\n // Joins the stack of open overlays, so the sidebar answers Escape only\n // while it's the topmost overlay, and keeps it from those under it. It's\n // modal with an overlay: without one it leaves Tab to a modal overlay\n // under it.\n const isTopmost = useOverlayStack(isOpen, overlay);\n const closesOnEscape = escapeClose && canCancel && Boolean(onClose);\n\n // Handle escape key. On `window`, as in `Modal`, so everything inside the\n // sidebar has had the key first, and an Escape it used is left to it. One\n // the sidebar closes on is marked used, so nothing under it acts on it.\n useEffect(() => {\n if (!isOpen || !closesOnEscape) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || e.defaultPrevented || !isTopmost()) return;\n e.preventDefault();\n handleCloseRef.current();\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, closesOnEscape, handleCloseRef, isTopmost]);\n\n // Keep Tab inside while there's an overlay, as `Modal` does:\n // `aria-modal` hides the rest of the page from assistive technology, so\n // the keyboard order has to agree. Only while it's the topmost modal\n // overlay, so a Modal or Dialog opened over the sidebar, even one\n // rendered inside it, holds Tab instead until it closes, and a sidebar\n // without an overlay opened over it doesn't. On `window` for the same\n // reason as Escape: a trap inside, such as a portaled popup's, has had\n // the Tab first, and one it used is left where it put focus. It's the trap\n // `useFocusTrap` sets, so a Tab the browser still takes out, as Safari\n // does past links, is sent back in. It reads the aside as each key\n // arrives, so one remounted while the sidebar is open, by a new portal\n // target or by switching `inline`, stays trapped.\n useEffect(() => {\n if (!isOpen || !overlay) return undefined;\n return trapTab(\n () => sidebarRef.current,\n window,\n () => isTopmost('modal')\n );\n }, [isOpen, overlay, isTopmost]);\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 // Move focus into the sidebar on open, to the first stop Tab wraps to or\n // the sidebar itself, and hand it back on close, as `Modal` does. A\n // different `defaultTarget` remounts the portaled sidebar: the cleanup\n // hands focus back from the old nodes, which left it on <body>, and the\n // re-run records the same opener and focuses the new nodes. Whether it\n // takes focus is decided as it opens, so `overlay` changing while it's\n // open leaves focus where the user has it.\n useEffect(() => {\n if (!isOpen) return undefined;\n const element = sidebarRef.current;\n /* istanbul ignore if: the aside renders whenever the sidebar is open, so its ref is set before this runs */\n if (!element) return undefined;\n\n // The element that had focus, wherever it sits: a portaled sidebar\n // renders under `document.body` while its opener can be inside a\n // shadow root.\n const opener = getDeepestActiveElement() as HTMLElement | null;\n // Without an overlay the sidebar holds no Tab, so with a modal overlay\n // open under it, the first Tab would take focus back there and leave\n // the sidebar's other controls out of reach. It leaves focus alone\n // then, and the cleanup below finds focus outside and leaves it too.\n if (overlay || !isModalOverlayOpen()) {\n focusTabStop(element);\n }\n\n return () => {\n // Only while the sidebar still holds focus: closing one under another\n // overlay mustn't pull focus out of the one on top, and focus moved\n // out to the page stays there. A removed subtree leaves focus on\n // <body>, which still counts as held.\n const active = getActiveElementInTree(element);\n if (active === document.body || element.contains(active)) {\n opener?.focus();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `overlay` is read as the sidebar opens, on purpose\n }, [isOpen, defaultTarget]);\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 // React commits this before the effect that moves focus in runs, so\n // an opening sidebar is no longer inert by then.\n {...inertProps(!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 const target = resolveContainer();\n return createPortal(\n <LocalePortalScope target={target}>{sidebarContent}</LocalePortalScope>,\n target\n );\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":"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"}
@@ -4,6 +4,7 @@ import React from 'react';
4
4
  import { classNames, usePrefixedClassNames } from '../helpers/classNames.js';
5
5
  import { withSubComponents } from '../helpers/withSubComponents.js';
6
6
  import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
7
+ import { useNumberFormat } from '../helpers/localeFormat.js';
7
8
 
8
9
  /**
9
10
  * Individual Step component for use inside Steps.
@@ -14,6 +15,7 @@ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
14
15
  */
15
16
  const Step = ({ isActive = false, isCompleted = false, label, icon, clickable = false, onClick, stepNumber, completedIcon, className, children, ...props }) => {
16
17
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
18
+ const formatNumber = useNumberFormat();
17
19
  const stepClasses = classNames(usePrefixedClassNames('steps-segment', {
18
20
  'is-active': isActive,
19
21
  'is-completed': isCompleted,
@@ -26,7 +28,9 @@ const Step = ({ isActive = false, isCompleted = false, label, icon, clickable =
26
28
  const markerContent = icon ||
27
29
  (isCompleted && resolvedCompletedIcon
28
30
  ? resolvedCompletedIcon
29
- : (stepNumber ?? null));
31
+ : stepNumber == null || !formatNumber
32
+ ? (stepNumber ?? null)
33
+ : formatNumber(stepNumber));
30
34
  const title = label || children;
31
35
  const current = isActive ? 'step' : undefined;
32
36
  // The step stays a list item, and a real button inside it does the
@@ -1 +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 /**\n * Step label/title. On a `clickable` step it's rendered inside the step's\n * `<button>`, so it has to be phrasing content, like text, a `<span>` or an\n * icon, with no link, button or other control in it.\n */\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 /**\n * Whether this step is clickable. A clickable step puts its marker and\n * label in a `<button type=\"button\">` inside its list item, which calls\n * `onStepClick`, and the current step's `aria-current` goes on that button.\n */\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 /**\n * Position of labels. `right` and `left` mean the end and the start of the\n * line, so in a right-to-left page `right` puts each label to the left of\n * its marker, and `left` to the right.\n */\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 /**\n * Step label/title, or pass it as `children`. On a `clickable` step it's\n * rendered inside the step's `<button>`, so it has to be phrasing content,\n * like text, a `<span>` or an icon, with no link, button or other control\n * in it.\n */\n label?: React.ReactNode;\n /** Icon for the step marker */\n icon?: React.ReactNode;\n /**\n * Whether this step is clickable. A clickable step puts its marker and\n * label in a `<button type=\"button\">` inside the `<li>`, which calls\n * `onClick`, and `aria-current` goes on that button. The `<li>` keeps the\n * rest of the props.\n */\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 resolvedCompletedIcon =\n completedIcon === undefined ? '\\u2713' : completedIcon;\n const markerContent =\n icon ||\n (isCompleted && resolvedCompletedIcon\n ? resolvedCompletedIcon\n : (stepNumber ?? null));\n const title = label || children;\n const current = isActive ? 'step' : undefined;\n\n // The step stays a list item, and a real button inside it does the\n // clicking, so the list keeps its items and the button brings Enter, Space\n // and focus with it. A button holds only phrasing content, so its parts\n // are spans.\n if (clickable) {\n return (\n <li className={stepClasses} {...rest}>\n <button\n type=\"button\"\n className={stepsLinkClass}\n onClick={() => onClick?.()}\n aria-current={current}\n >\n <span className={stepsMarkerClass}>{markerContent}</span>\n {title && (\n <span className={stepsContentClass}>\n <span className={stepsTitleClass}>{title}</span>\n </span>\n )}\n </button>\n </li>\n );\n }\n\n return (\n <li className={stepClasses} aria-current={current} {...rest}>\n <div className={stepsLinkClass}>\n <span className={stepsMarkerClass}>{markerContent}</span>\n {title && (\n <div className={stepsContentClass}>\n <p className={stepsTitleClass}>{title}</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 // role=\"list\" restates the <ul>'s own role, for Safari: WebKit stops\n // exposing a list as one once its markers are hidden, as they are here,\n // unless the role is set explicitly.\n return (\n <div className={combinedClasses} {...rest}>\n <ul className={listClasses} role=\"list\">\n {renderSteps()}\n </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":";;;;;;;AAiIA;;;;;;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;AAE5D,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;AAC3B,IAAA,MAAM,KAAK,GAAG,KAAK,IAAI,QAAQ;IAC/B,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS;;;;;IAM7C,IAAI,SAAS,EAAE;QACb,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,WAAW,EAAA,GAAM,IAAI,EAAA,QAAA,EAClCC,IAAA,CAAA,QAAA,EAAA,EACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,MAAM,OAAO,IAAI,EAAA,cAAA,EACZ,OAAO,EAAA,QAAA,EAAA,CAErBD,cAAM,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAAG,aAAa,EAAA,CAAQ,EACxD,KAAK,KACJA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,iBAAiB,YAChCA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,eAAe,EAAA,QAAA,EAAG,KAAK,EAAA,CAAQ,EAAA,CAC3C,CACR,CAAA,EAAA,CACM,EAAA,CACN;IAET;AAEA,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,WAAW,EAAA,cAAA,EAAgB,OAAO,EAAA,GAAM,IAAI,YACzDC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAC5BD,cAAM,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAAG,aAAa,GAAQ,EACxD,KAAK,KACJA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,iBAAiB,YAC/BA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,eAAe,EAAA,QAAA,EAAG,KAAK,EAAA,CAAK,EAAA,CACtC,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;;;;IAKD,QACEC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,eAAe,KAAM,IAAI,EAAA,QAAA,EAAA,CACvCD,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,WAAW,EAAE,IAAI,EAAC,MAAM,EAAA,QAAA,EACpC,WAAW,EAAE,GACX,EACJ,aAAa,KACZC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,oBAAoB,EAAA,QAAA,EAAA,CAClCD,GAAA,CAAA,QAAA,EAAA,EACE,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;;"}
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';\nimport { useNumberFormat } from '../helpers/localeFormat';\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 /**\n * Step label/title. On a `clickable` step it's rendered inside the step's\n * `<button>`, so it has to be phrasing content, like text, a `<span>` or an\n * icon, with no link, button or other control in it.\n */\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 /**\n * Whether this step is clickable. A clickable step puts its marker and\n * label in a `<button type=\"button\">` inside its list item, which calls\n * `onStepClick`, and the current step's `aria-current` goes on that button.\n */\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 /**\n * Position of labels. `right` and `left` mean the end and the start of the\n * line, so in a right-to-left page `right` puts each label to the left of\n * its marker, and `left` to the right.\n */\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 /**\n * Step label/title, or pass it as `children`. On a `clickable` step it's\n * rendered inside the step's `<button>`, so it has to be phrasing content,\n * like text, a `<span>` or an icon, with no link, button or other control\n * in it.\n */\n label?: React.ReactNode;\n /** Icon for the step marker */\n icon?: React.ReactNode;\n /**\n * Whether this step is clickable. A clickable step puts its marker and\n * label in a `<button type=\"button\">` inside the `<li>`, which calls\n * `onClick`, and `aria-current` goes on that button. The `<li>` keeps the\n * rest of the props.\n */\n clickable?: boolean;\n /** Click handler */\n onClick?: () => void;\n /**\n * Step number to display in marker (1-indexed), written the way the\n * `locale` of a `LocaleProvider` around it writes numbers.\n */\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 const formatNumber = useNumberFormat();\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 resolvedCompletedIcon =\n completedIcon === undefined ? '\\u2713' : completedIcon;\n const markerContent =\n icon ||\n (isCompleted && resolvedCompletedIcon\n ? resolvedCompletedIcon\n : stepNumber == null || !formatNumber\n ? (stepNumber ?? null)\n : formatNumber(stepNumber));\n const title = label || children;\n const current = isActive ? 'step' : undefined;\n\n // The step stays a list item, and a real button inside it does the\n // clicking, so the list keeps its items and the button brings Enter, Space\n // and focus with it. A button holds only phrasing content, so its parts\n // are spans.\n if (clickable) {\n return (\n <li className={stepClasses} {...rest}>\n <button\n type=\"button\"\n className={stepsLinkClass}\n onClick={() => onClick?.()}\n aria-current={current}\n >\n <span className={stepsMarkerClass}>{markerContent}</span>\n {title && (\n <span className={stepsContentClass}>\n <span className={stepsTitleClass}>{title}</span>\n </span>\n )}\n </button>\n </li>\n );\n }\n\n return (\n <li className={stepClasses} aria-current={current} {...rest}>\n <div className={stepsLinkClass}>\n <span className={stepsMarkerClass}>{markerContent}</span>\n {title && (\n <div className={stepsContentClass}>\n <p className={stepsTitleClass}>{title}</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 // role=\"list\" restates the <ul>'s own role, for Safari: WebKit stops\n // exposing a list as one once its markers are hidden, as they are here,\n // unless the role is set explicitly.\n return (\n <div className={combinedClasses} {...rest}>\n <ul className={listClasses} role=\"list\">\n {renderSteps()}\n </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":"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"}