@allxsmith/bestax-bulma 5.38.1 → 5.39.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.
@@ -225,10 +225,12 @@ const ModalRoot = forwardRef(function ModalRoot({ active, isActive, onClose, cla
225
225
  // changes identity, as an inline one does on every render of the parent.
226
226
  const onCloseRef = useLatestRef(onClose);
227
227
  // Joins the stack of open overlays, so the keyboard handling below only
228
- // applies while this modal is the topmost overlay.
228
+ // applies while this modal is on top.
229
229
  const isTopmost = useOverlayStack(isModalActive);
230
- // Escape closes; Tab cycles inside the modal. Both only for the topmost
231
- // overlay. The listener is on `window`, where a keydown arrives last, so
230
+ // Escape closes, only for the topmost overlay. Tab cycles inside the modal
231
+ // while it's the topmost modal overlay, so an overlay that isn't modal,
232
+ // such as a Sidebar without an overlay, takes Escape from it but leaves it
233
+ // Tab. The listener is on `window`, where a keydown arrives last, so
232
234
  // everything inside the modal has had the key first: React's handlers, and
233
235
  // `document` listeners added after this one, such as a date picker's.
234
236
  useEffect(() => {
@@ -236,9 +238,9 @@ const ModalRoot = forwardRef(function ModalRoot({ active, isActive, onClose, cla
236
238
  return undefined;
237
239
  const handleKeyDown = (e) => {
238
240
  const node = modalRootRef.current;
239
- if (!isTopmost())
240
- return;
241
241
  if (e.key === 'Escape') {
242
+ if (!isTopmost())
243
+ return;
242
244
  // Something inside already used this Escape, such as a popup that
243
245
  // closed on it, so the modal waits for the next one. One the modal
244
246
  // closes on is marked used, so nothing under it acts on it as well.
@@ -250,8 +252,12 @@ const ModalRoot = forwardRef(function ModalRoot({ active, isActive, onClose, cla
250
252
  }
251
253
  // A trap inside the modal, such as a portaled popup's, already moved
252
254
  // focus on this Tab, so the modal leaves it where it went.
253
- if (e.key !== 'Tab' || !node || e.defaultPrevented)
255
+ if (e.key !== 'Tab' ||
256
+ !node ||
257
+ e.defaultPrevented ||
258
+ !isTopmost('modal')) {
254
259
  return;
260
+ }
255
261
  // Keep Tab within the modal — `aria-modal` hides the rest of the page
256
262
  // from assistive technology, so the keyboard order has to agree.
257
263
  const focusable = getTabbable(node);
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\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';\n\n/**\n * Controls the modal can hand focus to. Disabled and hidden controls are\n * excluded because `focus()` on them is a no-op, which would leave focus\n * outside the modal.\n */\nconst FOCUSABLE_SELECTOR =\n 'button:not(:disabled), [href], input:not(:disabled):not([type=\"hidden\"]), select:not(:disabled), textarea:not(:disabled), [tabindex]';\n\n/**\n * The modal's tab stops, in document order. The selector alone is not the\n * tabbable set — `[href]` and `button` match regardless of `tabindex`, so an\n * `<a href tabIndex={-1}>` would otherwise be treated as a tab stop and let\n * Tab escape the modal when it sorts last. `el.tabIndex` is the browser's own\n * resolved value, so filtering on it drops every negative index (not just\n * `-1`) without a second selector to keep in sync.\n */\nconst getTabbable = (node: HTMLElement): HTMLElement[] =>\n Array.from(node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n el => el.tabIndex >= 0\n );\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 /** Callback invoked to request modal close (background or close button). */\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 */\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 */\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/**\n * Modal.Background - Renders the modal background overlay.\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.\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 ...props\n}) => {\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 />\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}>\n * <Modal.Background onClick={handleClose} />\n * <Modal.Card>\n * <Modal.Card.Head>\n * <Modal.Card.Title>Title</Modal.Card.Title>\n * <Modal.Close onClick={handleClose} />\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 the topmost overlay.\n const isTopmost = useOverlayStack(isModalActive);\n\n // Escape closes; Tab cycles inside the modal. Both only for the topmost\n // overlay. The listener is on `window`, where a keydown arrives last, so\n // everything inside the modal has had the key first: React's handlers, and\n // `document` listeners added after this one, such as a date picker's.\n useEffect(() => {\n if (!isModalActive) return undefined;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const node = modalRootRef.current;\n if (!isTopmost()) return;\n\n if (e.key === 'Escape') {\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 return;\n }\n // A trap inside the modal, such as a portaled popup's, already moved\n // focus on this Tab, so the modal leaves it where it went.\n if (e.key !== 'Tab' || !node || e.defaultPrevented) return;\n\n // Keep Tab within the modal — `aria-modal` hides the rest of the page\n // from assistive technology, so the keyboard order has to agree.\n const focusable = getTabbable(node);\n const activeElement = getActiveElementInTree(node);\n if (focusable.length === 0) {\n e.preventDefault();\n node.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const outside = !node.contains(activeElement);\n if (e.shiftKey) {\n if (outside || activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else if (outside || activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isModalActive, closeOnEscape, onCloseRef, 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 const focusable = node ? getTabbable(node)[0] : undefined;\n (focusable ?? node)?.focus();\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 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":"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"}
1
+ {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\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';\n\n/**\n * Controls the modal can hand focus to. Disabled and hidden controls are\n * excluded because `focus()` on them is a no-op, which would leave focus\n * outside the modal.\n */\nconst FOCUSABLE_SELECTOR =\n 'button:not(:disabled), [href], input:not(:disabled):not([type=\"hidden\"]), select:not(:disabled), textarea:not(:disabled), [tabindex]';\n\n/**\n * The modal's tab stops, in document order. The selector alone is not the\n * tabbable set — `[href]` and `button` match regardless of `tabindex`, so an\n * `<a href tabIndex={-1}>` would otherwise be treated as a tab stop and let\n * Tab escape the modal when it sorts last. `el.tabIndex` is the browser's own\n * resolved value, so filtering on it drops every negative index (not just\n * `-1`) without a second selector to keep in sync.\n */\nconst getTabbable = (node: HTMLElement): HTMLElement[] =>\n Array.from(node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n el => el.tabIndex >= 0\n );\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 /** Callback invoked to request modal close (background or close button). */\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 */\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 */\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/**\n * Modal.Background - Renders the modal background overlay.\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.\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 ...props\n}) => {\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 />\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}>\n * <Modal.Background onClick={handleClose} />\n * <Modal.Card>\n * <Modal.Card.Head>\n * <Modal.Card.Title>Title</Modal.Card.Title>\n * <Modal.Close onClick={handleClose} />\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. Tab cycles inside the modal\n // while it's the topmost modal overlay, so an overlay that isn't modal,\n // such as a Sidebar without an overlay, takes Escape from it but leaves it\n // Tab. The listener is on `window`, where a keydown arrives last, so\n // everything inside the modal has had the key first: React's handlers, and\n // `document` listeners added after this one, such as a date picker's.\n useEffect(() => {\n if (!isModalActive) return undefined;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const node = modalRootRef.current;\n\n if (e.key === 'Escape') {\n if (!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 return;\n }\n // A trap inside the modal, such as a portaled popup's, already moved\n // focus on this Tab, so the modal leaves it where it went.\n if (\n e.key !== 'Tab' ||\n !node ||\n e.defaultPrevented ||\n !isTopmost('modal')\n ) {\n return;\n }\n\n // Keep Tab within the modal — `aria-modal` hides the rest of the page\n // from assistive technology, so the keyboard order has to agree.\n const focusable = getTabbable(node);\n const activeElement = getActiveElementInTree(node);\n if (focusable.length === 0) {\n e.preventDefault();\n node.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const outside = !node.contains(activeElement);\n if (e.shiftKey) {\n if (outside || activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else if (outside || activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isModalActive, closeOnEscape, onCloseRef, 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 const focusable = node ? getTabbable(node)[0] : undefined;\n (focusable ?? node)?.focus();\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 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":"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"}
@@ -16,7 +16,7 @@ const NavbarDropdownContext = React.createContext(null);
16
16
  * @returns {JSX.Element} The rendered navbar.
17
17
  * @see {@link https://bulma.io/documentation/components/navbar/ | Bulma Navbar documentation}
18
18
  */
19
- const NavbarComponent = forwardRef(function NavbarComponent({ className, textColor, bgColor, color, transparent, fixed, children, ...props }, ref) {
19
+ const NavbarComponent = forwardRef(function NavbarComponent({ className, textColor, bgColor, color, transparent, isSpaced, hasShadow, fixed, children, ...props }, ref) {
20
20
  const { bulmaHelperClasses, rest } = useBulmaClasses({
21
21
  color: textColor,
22
22
  backgroundColor: bgColor,
@@ -26,6 +26,8 @@ const NavbarComponent = forwardRef(function NavbarComponent({ className, textCol
26
26
  const bulmaClasses = usePrefixedClassNames('navbar', {
27
27
  [`is-${color}`]: color,
28
28
  'is-transparent': transparent,
29
+ 'is-spaced': isSpaced,
30
+ 'has-shadow': hasShadow,
29
31
  [`is-fixed-${fixed}`]: fixed,
30
32
  });
31
33
  const navbarClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
@@ -1 +1 @@
1
- {"version":3,"file":"Navbar.js","sources":["../../../src/components/Navbar.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useEffect, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport type { PolymorphicComponent } from '../helpers/polymorphic';\nimport { buttonType } from '../helpers/buttonType';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * Shared state a `Navbar.Dropdown` exposes to its `Navbar.Link` trigger so the\n * trigger needs no hand-wired ARIA or keyboard handling.\n */\ninterface NavbarDropdownContextValue {\n /** Whether the dropdown is currently open. */\n active: boolean;\n /** Flips the open state. */\n toggle: () => void;\n /** Closes the dropdown (no-op if already closed). */\n close: () => void;\n}\n\nconst NavbarDropdownContext =\n React.createContext<NavbarDropdownContextValue | null>(null);\n\n/**\n * Props for the Navbar component.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the root `<nav>` element.\n */\nexport interface NavbarProps\n extends\n React.HTMLAttributes<HTMLElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes for the navbar. */\n className?: string;\n /** Text color for the navbar. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color modifier for the navbar. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Background color for the navbar. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Renders the navbar with a transparent background. */\n transparent?: boolean;\n /** Fixes the navbar to the top or bottom of the viewport. */\n fixed?: 'top' | 'bottom';\n /** Navbar content (compose with subcomponents). */\n children?: React.ReactNode;\n}\n\n/**\n * The `Navbar` component implements Bulma's powerful, responsive navigation bar for your Bulma React UI.\n *\n * @function\n * @param {NavbarProps} props - Props for the Navbar component.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the root `<nav>` element.\n * @returns {JSX.Element} The rendered navbar.\n * @see {@link https://bulma.io/documentation/components/navbar/ | Bulma Navbar documentation}\n */\nconst NavbarComponent = forwardRef<HTMLElement, NavbarProps>(\n function NavbarComponent(\n {\n className,\n textColor,\n bgColor,\n color,\n transparent,\n fixed,\n children,\n ...props\n },\n ref\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('navbar', {\n [`is-${color}`]: color,\n 'is-transparent': transparent,\n [`is-fixed-${fixed}`]: fixed,\n });\n\n const navbarClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <nav\n ref={ref}\n className={navbarClasses}\n role=\"navigation\"\n aria-label=\"main navigation\"\n {...rest}\n >\n {children}\n </nav>\n );\n }\n);\n\n/**\n * Props for the NavbarBrand component.\n */\nexport interface NavbarBrandProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the brand. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `.navbar-brand.is-<color>` rule, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Brand content. */\n children?: React.ReactNode;\n}\n\n/**\n * For logo and branding (left side)\n *\n * @function\n * @param {NavbarBrandProps} props - Props for the NavbarBrand component.\n * @returns {JSX.Element} The rendered brand area.\n */\nexport const NavbarBrand: React.FC<NavbarBrandProps> = ({\n className,\n children,\n textColor,\n color,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-brand'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * The NavbarItem component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface NavbarItemOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor'\n> {\n /**\n * Not accepted. `color` here would be the deprecated presentational HTML\n * attribute, and `useBulmaClasses` consumes any `color` key as a Bulma helper\n * before the target could see it — so it is declared unavailable rather than\n * silently eaten. Use `textColor` / `bgColor`.\n * @internal\n */\n color?: never;\n /**\n * Not accepted under this name. `useBulmaClasses` consumes any\n * `backgroundColor` key before `rest` is spread, so a custom `as` target\n * declaring one would never receive it. Use `bgColor`.\n * @internal\n */\n backgroundColor?: never;\n /** Additional CSS classes. */\n className?: string;\n /** Whether the item is active. */\n active?: boolean;\n /** Text color for the item. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color for the item. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Navbar item content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the NavbarItem component. The DOM attributes and the `ref` both\n * follow `as`: rendering as a router link accepts that component's props (`to`\n * and friends) by inference, and `as=\"span\"` rejects `href`.\n *\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders, typed from `as`: the DOM node for an intrinsic tag, or whatever handle a custom component exposes.\n */\nexport type NavbarItemProps<T extends React.ElementType = 'a'> =\n NavbarItemOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof NavbarItemOwnProps | 'as'> & {\n /**\n * Render as another intrinsic element (`'span'`, `'div'`, `'button'`) or a custom component (e.g. a router link). Defaults to `'a'`.\n *\n * `'button'` renders `type=\"button\"`, so an item inside a form does not submit it. Pass\n * `type=\"submit\"` or `type=\"reset\"` and yours is used; any other value, or a spread\n * carrying `type: undefined`, renders `type=\"button\"`.\n */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `NavbarItemProps<T>` above — the body cannot see through `T`.\n */\ntype NavbarItemImplProps = NavbarItemOwnProps & {\n as?: React.ElementType;\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n};\n\n/**\n * Navigation links, buttons, or custom content\n *\n * @function\n * @param {NavbarItemProps} props - Props for the NavbarItem component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered item.\n */\nexport const NavbarItem = forwardRef(function NavbarItem(\n itemProps: NavbarItemProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n className,\n as: Component = 'a',\n active,\n textColor,\n bgColor,\n children,\n ...props\n } = itemProps as NavbarItemImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n return (\n <Component\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-item', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n // A `<button>` defaults to type=\"submit\", and a navbar inside a form must\n // not submit it. After the spread, reading through it, so a spread\n // carrying `type: undefined` cannot erase the default. A caller's\n // `submit` or `reset` still wins; `buttonType` says more.\n {...(Component === 'button' ? { type: buttonType(rest.type) } : {})}\n >\n {children}\n </Component>\n );\n}) as PolymorphicComponent<NavbarItemOwnProps, 'a'>;\n\nNavbarItem.displayName = 'NavbarItem';\n\n/**\n * Props for the NavbarBurger component.\n * @extraProp {React.Ref<HTMLButtonElement>} [ref] - Ref forwarded to the burger button element.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a burger 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 */\nexport interface NavbarBurgerProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the burger. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `.navbar-burger.is-<color>` rule, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Whether the burger is active. */\n active?: boolean;\n /**\n * Custom content inside the burger, rendered after its four bar spans.\n * Bulma styles every `<span>` in the burger as a bar, so an extra span here\n * draws an extra bar.\n */\n children?: React.ReactNode;\n /**\n * Accessible name. Pass your own to replace it. An empty one, or a spread\n * carrying `'aria-label': undefined`, keeps the default rather than leaving\n * the button unnamed.\n * @defaultValue 'menu'\n */\n 'aria-label'?: string;\n /**\n * Expanded state for assistive technology. It follows `active` unless you\n * pass `true` or `false`; a spread carrying `'aria-expanded': undefined`\n * still follows `active`.\n * @defaultValue active\n */\n 'aria-expanded'?: boolean;\n /** Click handler. */\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n}\n\n/**\n * Responsive menu toggle (mobile)\n *\n * @function\n * @param {NavbarBurgerProps} props - Props for the NavbarBurger component.\n * @param {React.Ref<HTMLButtonElement>} ref - Forwarded ref to the burger button element.\n * @returns {JSX.Element} The rendered burger.\n */\nexport const NavbarBurger = forwardRef<HTMLButtonElement, NavbarBurgerProps>(\n function NavbarBurger(\n { className, active, textColor, color, children, ...props },\n ref\n ) {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n\n return (\n <button\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-burger', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n // After the spread, reading through it: a key the spread carries with\n // no value would otherwise erase the default, leaving a nameless\n // button that submits the form around it. An empty label falls back\n // too: the button is drawn as an icon, so `''` would leave it unnamed.\n // A caller's own value still wins; `buttonType` says more.\n aria-label={rest['aria-label'] || 'menu'}\n aria-expanded={rest['aria-expanded'] ?? !!active}\n type={buttonType(rest.type)}\n >\n {/* Bulma v1's burger mixin positions four spans: the first two meet\n in the middle (they rotate into the X), the third and fourth draw\n the top and bottom bars. */}\n <span aria-hidden=\"true\"></span>\n <span aria-hidden=\"true\"></span>\n <span aria-hidden=\"true\"></span>\n <span aria-hidden=\"true\"></span>\n {children}\n </button>\n );\n }\n);\n\nNavbarBurger.displayName = 'NavbarBurger';\n\n/**\n * Props for the NavbarMenu component.\n */\nexport interface NavbarMenuProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the menu. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `.navbar-menu.is-<color>` rule, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Whether the menu is active. */\n active?: boolean;\n /** Menu content. */\n children?: React.ReactNode;\n}\n\n/**\n * Collapsible content (contains `Navbar.Start` and `Navbar.End`)\n *\n * @function\n * @param {NavbarMenuProps} props - Props for the NavbarMenu component.\n * @returns {JSX.Element} The rendered menu.\n */\nexport const NavbarMenu: React.FC<NavbarMenuProps> = ({\n className,\n active,\n textColor,\n color,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-menu', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Props for the NavbarStartEnd component.\n */\nexport interface NavbarStartEndProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `is-<color>` rule for this area, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Content. */\n children?: React.ReactNode;\n}\n\n/**\n * Left-aligned menu area\n *\n * @function\n * @param {NavbarStartEndProps} props - Props for the NavbarStart component.\n * @returns {JSX.Element} The rendered start area.\n */\nexport const NavbarStart: React.FC<NavbarStartEndProps> = ({\n className,\n textColor,\n color,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-start'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Right-aligned menu area\n *\n * @function\n * @param {NavbarStartEndProps} props - Props for the NavbarEnd component.\n * @returns {JSX.Element} The rendered end area.\n */\nexport const NavbarEnd: React.FC<NavbarStartEndProps> = ({\n className,\n textColor,\n color,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-end'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * The NavbarLink component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface NavbarLinkOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor'\n> {\n /**\n * Not accepted. `color` here would be the deprecated presentational HTML\n * attribute, and `useBulmaClasses` consumes any `color` key as a Bulma helper\n * before the target could see it — so it is declared unavailable rather than\n * silently eaten. Use `textColor` / `bgColor`.\n * @internal\n */\n color?: never;\n /**\n * Not accepted under this name. `useBulmaClasses` consumes any\n * `backgroundColor` key before `rest` is spread, so a custom `as` target\n * declaring one would never receive it. Use `bgColor`.\n * @internal\n */\n backgroundColor?: never;\n /** Additional CSS classes. */\n className?: string;\n /** Remove the dropdown arrow indicator. */\n arrowless?: boolean;\n /** Text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Link content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the NavbarLink component. The DOM attributes and the `ref` both\n * follow `as`: `as=\"button\"` accepts the button attributes and a button ref,\n * and `as=\"span\"` rejects `href` and `target`. Not `rel` — React declares it on\n * `HTMLAttributes<T>`, so it is valid on every element, and rejecting it would\n * mean diverging from React's own typing.\n *\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders, typed from `as`: the DOM node for an intrinsic tag, or whatever handle a custom component exposes.\n */\nexport type NavbarLinkProps<T extends React.ElementType = 'a'> =\n NavbarLinkOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof NavbarLinkOwnProps | 'as'> & {\n /**\n * Render as another intrinsic element (`'button'`, `'span'`) or a custom component. Defaults to `'a'`.\n *\n * Inside a `Navbar.Dropdown` this also decides the trigger's semantics. A custom\n * component is taken to be interactive already — a router link, typically — so it\n * keeps its own role and click behaviour. An intrinsic tag is judged on what it is:\n * `'button'`, or anything carrying an `href`, is left alone, and everything else\n * (`'span'`, a bare `'a'`, a custom element) gets `role=\"button\"`, `tabIndex` and a\n * click that opens the dropdown.\n *\n * If your custom component renders something non-interactive, pass `role=\"button\"` and\n * it takes that fallback too — `tabIndex` and click included. The keyboard path is\n * attached either way.\n *\n * `'button'` renders `type=\"button\"`, so a link inside a form does not submit it. Pass\n * `type=\"submit\"` or `type=\"reset\"` and yours is used; any other value, or a spread\n * carrying `type: undefined`, renders `type=\"button\"`.\n */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `NavbarLinkProps<T>` above — the body cannot see through `T`, so it names the\n * handful of DOM props it actually reads back off `rest`.\n */\ntype NavbarLinkImplProps = NavbarLinkOwnProps & {\n as?: React.ElementType;\n href?: string;\n role?: React.AriaRole;\n onKeyDown?: React.KeyboardEventHandler<HTMLAnchorElement>;\n onClick?: React.MouseEventHandler<HTMLAnchorElement>;\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n};\n\n/**\n * Dropdown trigger with arrow indicator (use as first child of `Navbar.Dropdown`)\n *\n * @function\n * @param {NavbarLinkProps} props - Props for the NavbarLink component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered navbar link.\n */\nexport const NavbarLink = forwardRef(function NavbarLink(\n linkProps: NavbarLinkProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n className,\n as: Component = 'a',\n arrowless,\n textColor,\n bgColor,\n children,\n ...props\n } = linkProps as NavbarLinkImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const dropdownContext = useContext(NavbarDropdownContext);\n const hasHref = rest.href !== undefined;\n // What a custom component renders cannot be read off its input props, and the\n // prop that ends in an anchor belongs to the router, not to us — `to`, `state`,\n // `params` and a dozen further spellings all get there. Sniffing for more names\n // trades one wrong guess for another, so a non-string `as` counts as\n // interactive: announcing a real anchor as a button, and layering a synthetic\n // click over its navigation, is the worse of the two failures (#668).\n //\n // A custom ELEMENT stays out of it. A hyphenated tag is a real DOM element and\n // none of those is natively interactive, so `<x-trigger>` keeps the fallback\n // exactly like `as=\"span\"` — the same line `Avatar` draws for `role=\"img\"`.\n //\n // Where we are guessing, the caller settles it: a custom target that declares\n // `role=\"button\"` is saying it is a button and not a link, so it takes the\n // whole fallback — including the click, which is the half it could not supply\n // itself. `Avatar` gives the same escape hatch to the same guess. An `href`\n // still wins: a target with somewhere to navigate is a link whatever role it\n // claims.\n const customTargetIsButton =\n typeof Component !== 'string' && rest.role === 'button';\n\n const isNativeInteractive =\n Component === 'button' ||\n (typeof Component !== 'string' && !customTargetIsButton) ||\n hasHref;\n\n // Guarded like Button's disabled blocker: these run on whatever `as` renders,\n // and a custom target's callback need not take a DOM event. One declaring\n // `onKeyDown: (k: {key: string}) => void` reaches `e.preventDefault()` and\n // throws. Composing the caller's handler is unconditional; acting on the\n // event is not ours to do when the payload is foreign.\n const isDomEvent = (e: unknown): e is { preventDefault: () => void } =>\n typeof (e as { preventDefault?: unknown })?.preventDefault === 'function';\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n rest.onKeyDown?.(e);\n if (!isDomEvent(e)) return;\n if (!dropdownContext || e.defaultPrevented) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n dropdownContext.toggle();\n } else if (e.key === 'Escape' && dropdownContext.active) {\n e.preventDefault();\n dropdownContext.close();\n }\n };\n\n // When the link is not natively interactive (no `href`, not a `<button>`) it\n // renders as `role=\"button\"`, so a mouse/touch click has no default action to\n // open the dropdown. Compose the caller's handler and toggle the dropdown\n // unless the caller prevented the default. Native links/buttons keep their own\n // click semantics (navigation / the caller's handler).\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n rest.onClick?.(e);\n if (!isDomEvent(e)) return;\n if (!dropdownContext || isNativeInteractive || e.defaultPrevented) return;\n dropdownContext.toggle();\n };\n\n return (\n <Component\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-link', {\n 'is-arrowless': arrowless,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n {...(dropdownContext && {\n 'aria-haspopup': 'true',\n 'aria-expanded': dropdownContext.active,\n onKeyDown: handleKeyDown,\n ...(!isNativeInteractive && {\n role: 'button',\n tabIndex: 0,\n onClick: handleClick,\n }),\n })}\n // The same button type default as `Navbar.Item`, for the same reason.\n {...(Component === 'button' ? { type: buttonType(rest.type) } : {})}\n >\n {children}\n </Component>\n );\n}) as PolymorphicComponent<NavbarLinkOwnProps, 'a'>;\n\nNavbarLink.displayName = 'NavbarLink';\n\n/**\n * Props for the NavbarDropdown component.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the dropdown container element.\n */\nexport interface NavbarDropdownProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Dropdown aligned right. */\n right?: boolean;\n /** Dropdown opens upwards. */\n up?: boolean;\n /** Dropdown opens on hover. */\n hoverable?: boolean;\n /** Dropdown is open. */\n active?: boolean;\n /** Callback when dropdown active state changes. */\n onActiveChange?: (active: boolean) => void;\n /** Dropdown content. */\n children?: React.ReactNode;\n}\n\n/**\n * Dropdown parent (with options for hover, up, right, active)\n *\n * @function\n * @param {NavbarDropdownProps} props - Props for the NavbarDropdown component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the dropdown container element.\n * @returns {JSX.Element} The rendered dropdown.\n */\nexport const NavbarDropdown = forwardRef<HTMLDivElement, NavbarDropdownProps>(\n function NavbarDropdown(\n {\n className,\n right,\n up,\n hoverable,\n active: activeProp,\n onActiveChange,\n children,\n ...props\n },\n ref\n ) {\n const [active, setActive] = useState<boolean>(!!activeProp);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- syncing to controlled prop\n if (typeof activeProp === 'boolean') setActive(activeProp);\n }, [activeProp]);\n\n // Keep `onActiveChange` out of the state updater (a pure function) so Strict\n // Mode's double-invoked updaters don't double-fire it — mirrors `Dropdown`.\n const toggle = () => {\n const next = !active;\n setActive(next);\n onActiveChange?.(next);\n };\n\n const close = () => {\n /* istanbul ignore next: close() is only invoked once already active */\n if (!active) return;\n setActive(false);\n onActiveChange?.(false);\n };\n\n return (\n <NavbarDropdownContext.Provider value={{ active, toggle, close }}>\n <div\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-item', 'has-dropdown', {\n 'has-dropdown-up': up,\n 'is-right': right,\n 'is-hoverable': hoverable,\n 'is-active': active,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n </NavbarDropdownContext.Provider>\n );\n }\n);\n\nNavbarDropdown.displayName = 'NavbarDropdown';\n\n/**\n * Props for the NavbarDropdownMenu component.\n */\nexport interface NavbarDropdownMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Dropdown aligned right. */\n right?: boolean;\n /** Dropdown opens upwards. */\n up?: boolean;\n /** Dropdown menu content. */\n children?: React.ReactNode;\n}\n\n/**\n * Dropdown menu container\n *\n * @function\n * @param {NavbarDropdownMenuProps} props - Props for the NavbarDropdownMenu component.\n * @returns {JSX.Element} The rendered dropdown menu.\n */\nexport const NavbarDropdownMenu: React.FC<NavbarDropdownMenuProps> = ({\n className,\n right,\n up,\n children,\n ...props\n}) => (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-dropdown', {\n 'is-right': right,\n 'is-up': up,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n\n/**\n * Divider in dropdown menus.\n *\n * @function\n * @param {React.HTMLAttributes<HTMLHRElement>} props - Standard hr props.\n * @returns {JSX.Element} The rendered divider.\n */\nexport const NavbarDivider: React.FC<React.HTMLAttributes<HTMLHRElement>> = ({\n className,\n ...props\n}) => (\n <hr\n className={classNames(usePrefixedClassNames('navbar-divider'), className)}\n {...props}\n />\n);\n\n// Attach subcomponents\nexport const Navbar = withSubComponents(\n NavbarComponent,\n {\n Brand: NavbarBrand,\n Item: NavbarItem,\n Link: NavbarLink,\n Burger: NavbarBurger,\n Menu: NavbarMenu,\n Start: NavbarStart,\n End: NavbarEnd,\n Dropdown: NavbarDropdown,\n DropdownMenu: NavbarDropdownMenu,\n Divider: NavbarDivider,\n },\n 'Navbar'\n);\n\nexport default Navbar;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"Navbar.js","sources":["../../../src/components/Navbar.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useEffect, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport type { PolymorphicComponent } from '../helpers/polymorphic';\nimport { buttonType } from '../helpers/buttonType';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * Shared state a `Navbar.Dropdown` exposes to its `Navbar.Link` trigger so the\n * trigger needs no hand-wired ARIA or keyboard handling.\n */\ninterface NavbarDropdownContextValue {\n /** Whether the dropdown is currently open. */\n active: boolean;\n /** Flips the open state. */\n toggle: () => void;\n /** Closes the dropdown (no-op if already closed). */\n close: () => void;\n}\n\nconst NavbarDropdownContext =\n React.createContext<NavbarDropdownContextValue | null>(null);\n\n/**\n * Props for the Navbar component.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the root `<nav>` element.\n */\nexport interface NavbarProps\n extends\n React.HTMLAttributes<HTMLElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes for the navbar. */\n className?: string;\n /** Text color for the navbar. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color modifier for the navbar. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Background color for the navbar. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Renders the navbar with a transparent background. */\n transparent?: boolean;\n /**\n * Renders Bulma's `is-spaced`: padding around the navbar, rounded items\n * and boxed dropdowns. Bulma applies it from the desktop breakpoint up, so\n * below that the navbar looks the same either way. With `fixed=\"top\"`, put\n * `has-spaced-navbar-fixed-top` on `<html>` beside `has-navbar-fixed-top`\n * (the `-bottom` pair for `fixed=\"bottom\"`). From desktop up the spaced\n * navbar is taller than `has-navbar-fixed-top` pads the page for, and\n * there the spaced class pads it for the taller navbar.\n */\n isSpaced?: boolean;\n /**\n * Renders Bulma's `has-shadow`: a shadow below the navbar, or above it with\n * `fixed=\"bottom\"`. Off unless set, since Bulma's navbar has no shadow of\n * its own. `Box` and `Card` take a `hasShadow` that defaults to `true`\n * instead, because Bulma gives those a shadow already.\n */\n hasShadow?: boolean;\n /** Fixes the navbar to the top or bottom of the viewport. */\n fixed?: 'top' | 'bottom';\n /** Navbar content (compose with subcomponents). */\n children?: React.ReactNode;\n}\n\n/**\n * The `Navbar` component implements Bulma's powerful, responsive navigation bar for your Bulma React UI.\n *\n * @function\n * @param {NavbarProps} props - Props for the Navbar component.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the root `<nav>` element.\n * @returns {JSX.Element} The rendered navbar.\n * @see {@link https://bulma.io/documentation/components/navbar/ | Bulma Navbar documentation}\n */\nconst NavbarComponent = forwardRef<HTMLElement, NavbarProps>(\n function NavbarComponent(\n {\n className,\n textColor,\n bgColor,\n color,\n transparent,\n isSpaced,\n hasShadow,\n fixed,\n children,\n ...props\n },\n ref\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('navbar', {\n [`is-${color}`]: color,\n 'is-transparent': transparent,\n 'is-spaced': isSpaced,\n 'has-shadow': hasShadow,\n [`is-fixed-${fixed}`]: fixed,\n });\n\n const navbarClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <nav\n ref={ref}\n className={navbarClasses}\n role=\"navigation\"\n aria-label=\"main navigation\"\n {...rest}\n >\n {children}\n </nav>\n );\n }\n);\n\n/**\n * Props for the NavbarBrand component.\n */\nexport interface NavbarBrandProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the brand. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `.navbar-brand.is-<color>` rule, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Brand content. */\n children?: React.ReactNode;\n}\n\n/**\n * For logo and branding (left side)\n *\n * @function\n * @param {NavbarBrandProps} props - Props for the NavbarBrand component.\n * @returns {JSX.Element} The rendered brand area.\n */\nexport const NavbarBrand: React.FC<NavbarBrandProps> = ({\n className,\n children,\n textColor,\n color,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-brand'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * The NavbarItem component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface NavbarItemOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor'\n> {\n /**\n * Not accepted. `color` here would be the deprecated presentational HTML\n * attribute, and `useBulmaClasses` consumes any `color` key as a Bulma helper\n * before the target could see it — so it is declared unavailable rather than\n * silently eaten. Use `textColor` / `bgColor`.\n * @internal\n */\n color?: never;\n /**\n * Not accepted under this name. `useBulmaClasses` consumes any\n * `backgroundColor` key before `rest` is spread, so a custom `as` target\n * declaring one would never receive it. Use `bgColor`.\n * @internal\n */\n backgroundColor?: never;\n /** Additional CSS classes. */\n className?: string;\n /** Whether the item is active. */\n active?: boolean;\n /** Text color for the item. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color for the item. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Navbar item content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the NavbarItem component. The DOM attributes and the `ref` both\n * follow `as`: rendering as a router link accepts that component's props (`to`\n * and friends) by inference, and `as=\"span\"` rejects `href`.\n *\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders, typed from `as`: the DOM node for an intrinsic tag, or whatever handle a custom component exposes.\n */\nexport type NavbarItemProps<T extends React.ElementType = 'a'> =\n NavbarItemOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof NavbarItemOwnProps | 'as'> & {\n /**\n * Render as another intrinsic element (`'span'`, `'div'`, `'button'`) or a custom component (e.g. a router link). Defaults to `'a'`.\n *\n * `'button'` renders `type=\"button\"`, so an item inside a form does not submit it. Pass\n * `type=\"submit\"` or `type=\"reset\"` and yours is used; any other value, or a spread\n * carrying `type: undefined`, renders `type=\"button\"`.\n */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `NavbarItemProps<T>` above — the body cannot see through `T`.\n */\ntype NavbarItemImplProps = NavbarItemOwnProps & {\n as?: React.ElementType;\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n};\n\n/**\n * Navigation links, buttons, or custom content\n *\n * @function\n * @param {NavbarItemProps} props - Props for the NavbarItem component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered item.\n */\nexport const NavbarItem = forwardRef(function NavbarItem(\n itemProps: NavbarItemProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n className,\n as: Component = 'a',\n active,\n textColor,\n bgColor,\n children,\n ...props\n } = itemProps as NavbarItemImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n return (\n <Component\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-item', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n // A `<button>` defaults to type=\"submit\", and a navbar inside a form must\n // not submit it. After the spread, reading through it, so a spread\n // carrying `type: undefined` cannot erase the default. A caller's\n // `submit` or `reset` still wins; `buttonType` says more.\n {...(Component === 'button' ? { type: buttonType(rest.type) } : {})}\n >\n {children}\n </Component>\n );\n}) as PolymorphicComponent<NavbarItemOwnProps, 'a'>;\n\nNavbarItem.displayName = 'NavbarItem';\n\n/**\n * Props for the NavbarBurger component.\n * @extraProp {React.Ref<HTMLButtonElement>} [ref] - Ref forwarded to the burger button element.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a burger 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 */\nexport interface NavbarBurgerProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the burger. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `.navbar-burger.is-<color>` rule, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Whether the burger is active. */\n active?: boolean;\n /**\n * Custom content inside the burger, rendered after its four bar spans.\n * Bulma styles every `<span>` in the burger as a bar, so an extra span here\n * draws an extra bar.\n */\n children?: React.ReactNode;\n /**\n * Accessible name. Pass your own to replace it. An empty one, or a spread\n * carrying `'aria-label': undefined`, keeps the default rather than leaving\n * the button unnamed.\n * @defaultValue 'menu'\n */\n 'aria-label'?: string;\n /**\n * Expanded state for assistive technology. It follows `active` unless you\n * pass `true` or `false`; a spread carrying `'aria-expanded': undefined`\n * still follows `active`.\n * @defaultValue active\n */\n 'aria-expanded'?: boolean;\n /** Click handler. */\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n}\n\n/**\n * Responsive menu toggle (mobile)\n *\n * @function\n * @param {NavbarBurgerProps} props - Props for the NavbarBurger component.\n * @param {React.Ref<HTMLButtonElement>} ref - Forwarded ref to the burger button element.\n * @returns {JSX.Element} The rendered burger.\n */\nexport const NavbarBurger = forwardRef<HTMLButtonElement, NavbarBurgerProps>(\n function NavbarBurger(\n { className, active, textColor, color, children, ...props },\n ref\n ) {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n\n return (\n <button\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-burger', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n // After the spread, reading through it: a key the spread carries with\n // no value would otherwise erase the default, leaving a nameless\n // button that submits the form around it. An empty label falls back\n // too: the button is drawn as an icon, so `''` would leave it unnamed.\n // A caller's own value still wins; `buttonType` says more.\n aria-label={rest['aria-label'] || 'menu'}\n aria-expanded={rest['aria-expanded'] ?? !!active}\n type={buttonType(rest.type)}\n >\n {/* Bulma v1's burger mixin positions four spans: the first two meet\n in the middle (they rotate into the X), the third and fourth draw\n the top and bottom bars. */}\n <span aria-hidden=\"true\"></span>\n <span aria-hidden=\"true\"></span>\n <span aria-hidden=\"true\"></span>\n <span aria-hidden=\"true\"></span>\n {children}\n </button>\n );\n }\n);\n\nNavbarBurger.displayName = 'NavbarBurger';\n\n/**\n * Props for the NavbarMenu component.\n */\nexport interface NavbarMenuProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color for the menu. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `.navbar-menu.is-<color>` rule, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Whether the menu is active. */\n active?: boolean;\n /** Menu content. */\n children?: React.ReactNode;\n}\n\n/**\n * Collapsible content (contains `Navbar.Start` and `Navbar.End`)\n *\n * @function\n * @param {NavbarMenuProps} props - Props for the NavbarMenu component.\n * @returns {JSX.Element} The rendered menu.\n */\nexport const NavbarMenu: React.FC<NavbarMenuProps> = ({\n className,\n active,\n textColor,\n color,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-menu', {\n 'is-active': active,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Props for the NavbarStartEnd component.\n */\nexport interface NavbarStartEndProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes. */\n className?: string;\n /** Text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Renders `has-text-<color>`, exactly like `textColor`. Bulma has no\n * `is-<color>` rule for this area, so this is not a filled variant.\n * `textColor` takes precedence when both are set, and is the one that\n * reaches the full color list.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Content. */\n children?: React.ReactNode;\n}\n\n/**\n * Left-aligned menu area\n *\n * @function\n * @param {NavbarStartEndProps} props - Props for the NavbarStart component.\n * @returns {JSX.Element} The rendered start area.\n */\nexport const NavbarStart: React.FC<NavbarStartEndProps> = ({\n className,\n textColor,\n color,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-start'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * Right-aligned menu area\n *\n * @function\n * @param {NavbarStartEndProps} props - Props for the NavbarEnd component.\n * @returns {JSX.Element} The rendered end area.\n */\nexport const NavbarEnd: React.FC<NavbarStartEndProps> = ({\n className,\n textColor,\n color,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor ?? color,\n ...props,\n });\n return (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-end'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n};\n\n/**\n * The NavbarLink component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface NavbarLinkOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor'\n> {\n /**\n * Not accepted. `color` here would be the deprecated presentational HTML\n * attribute, and `useBulmaClasses` consumes any `color` key as a Bulma helper\n * before the target could see it — so it is declared unavailable rather than\n * silently eaten. Use `textColor` / `bgColor`.\n * @internal\n */\n color?: never;\n /**\n * Not accepted under this name. `useBulmaClasses` consumes any\n * `backgroundColor` key before `rest` is spread, so a custom `as` target\n * declaring one would never receive it. Use `bgColor`.\n * @internal\n */\n backgroundColor?: never;\n /** Additional CSS classes. */\n className?: string;\n /** Remove the dropdown arrow indicator. */\n arrowless?: boolean;\n /** Text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Link content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the NavbarLink component. The DOM attributes and the `ref` both\n * follow `as`: `as=\"button\"` accepts the button attributes and a button ref,\n * and `as=\"span\"` rejects `href` and `target`. Not `rel` — React declares it on\n * `HTMLAttributes<T>`, so it is valid on every element, and rejecting it would\n * mean diverging from React's own typing.\n *\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders, typed from `as`: the DOM node for an intrinsic tag, or whatever handle a custom component exposes.\n */\nexport type NavbarLinkProps<T extends React.ElementType = 'a'> =\n NavbarLinkOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof NavbarLinkOwnProps | 'as'> & {\n /**\n * Render as another intrinsic element (`'button'`, `'span'`) or a custom component. Defaults to `'a'`.\n *\n * Inside a `Navbar.Dropdown` this also decides the trigger's semantics. A custom\n * component is taken to be interactive already — a router link, typically — so it\n * keeps its own role and click behaviour. An intrinsic tag is judged on what it is:\n * `'button'`, or anything carrying an `href`, is left alone, and everything else\n * (`'span'`, a bare `'a'`, a custom element) gets `role=\"button\"`, `tabIndex` and a\n * click that opens the dropdown.\n *\n * If your custom component renders something non-interactive, pass `role=\"button\"` and\n * it takes that fallback too — `tabIndex` and click included. The keyboard path is\n * attached either way.\n *\n * `'button'` renders `type=\"button\"`, so a link inside a form does not submit it. Pass\n * `type=\"submit\"` or `type=\"reset\"` and yours is used; any other value, or a spread\n * carrying `type: undefined`, renders `type=\"button\"`.\n */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `NavbarLinkProps<T>` above — the body cannot see through `T`, so it names the\n * handful of DOM props it actually reads back off `rest`.\n */\ntype NavbarLinkImplProps = NavbarLinkOwnProps & {\n as?: React.ElementType;\n href?: string;\n role?: React.AriaRole;\n onKeyDown?: React.KeyboardEventHandler<HTMLAnchorElement>;\n onClick?: React.MouseEventHandler<HTMLAnchorElement>;\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n};\n\n/**\n * Dropdown trigger with arrow indicator (use as first child of `Navbar.Dropdown`)\n *\n * @function\n * @param {NavbarLinkProps} props - Props for the NavbarLink component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered navbar link.\n */\nexport const NavbarLink = forwardRef(function NavbarLink(\n linkProps: NavbarLinkProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n className,\n as: Component = 'a',\n arrowless,\n textColor,\n bgColor,\n children,\n ...props\n } = linkProps as NavbarLinkImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const dropdownContext = useContext(NavbarDropdownContext);\n const hasHref = rest.href !== undefined;\n // What a custom component renders cannot be read off its input props, and the\n // prop that ends in an anchor belongs to the router, not to us — `to`, `state`,\n // `params` and a dozen further spellings all get there. Sniffing for more names\n // trades one wrong guess for another, so a non-string `as` counts as\n // interactive: announcing a real anchor as a button, and layering a synthetic\n // click over its navigation, is the worse of the two failures (#668).\n //\n // A custom ELEMENT stays out of it. A hyphenated tag is a real DOM element and\n // none of those is natively interactive, so `<x-trigger>` keeps the fallback\n // exactly like `as=\"span\"` — the same line `Avatar` draws for `role=\"img\"`.\n //\n // Where we are guessing, the caller settles it: a custom target that declares\n // `role=\"button\"` is saying it is a button and not a link, so it takes the\n // whole fallback — including the click, which is the half it could not supply\n // itself. `Avatar` gives the same escape hatch to the same guess. An `href`\n // still wins: a target with somewhere to navigate is a link whatever role it\n // claims.\n const customTargetIsButton =\n typeof Component !== 'string' && rest.role === 'button';\n\n const isNativeInteractive =\n Component === 'button' ||\n (typeof Component !== 'string' && !customTargetIsButton) ||\n hasHref;\n\n // Guarded like Button's disabled blocker: these run on whatever `as` renders,\n // and a custom target's callback need not take a DOM event. One declaring\n // `onKeyDown: (k: {key: string}) => void` reaches `e.preventDefault()` and\n // throws. Composing the caller's handler is unconditional; acting on the\n // event is not ours to do when the payload is foreign.\n const isDomEvent = (e: unknown): e is { preventDefault: () => void } =>\n typeof (e as { preventDefault?: unknown })?.preventDefault === 'function';\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n rest.onKeyDown?.(e);\n if (!isDomEvent(e)) return;\n if (!dropdownContext || e.defaultPrevented) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n dropdownContext.toggle();\n } else if (e.key === 'Escape' && dropdownContext.active) {\n e.preventDefault();\n dropdownContext.close();\n }\n };\n\n // When the link is not natively interactive (no `href`, not a `<button>`) it\n // renders as `role=\"button\"`, so a mouse/touch click has no default action to\n // open the dropdown. Compose the caller's handler and toggle the dropdown\n // unless the caller prevented the default. Native links/buttons keep their own\n // click semantics (navigation / the caller's handler).\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n rest.onClick?.(e);\n if (!isDomEvent(e)) return;\n if (!dropdownContext || isNativeInteractive || e.defaultPrevented) return;\n dropdownContext.toggle();\n };\n\n return (\n <Component\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-link', {\n 'is-arrowless': arrowless,\n }),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n {...(dropdownContext && {\n 'aria-haspopup': 'true',\n 'aria-expanded': dropdownContext.active,\n onKeyDown: handleKeyDown,\n ...(!isNativeInteractive && {\n role: 'button',\n tabIndex: 0,\n onClick: handleClick,\n }),\n })}\n // The same button type default as `Navbar.Item`, for the same reason.\n {...(Component === 'button' ? { type: buttonType(rest.type) } : {})}\n >\n {children}\n </Component>\n );\n}) as PolymorphicComponent<NavbarLinkOwnProps, 'a'>;\n\nNavbarLink.displayName = 'NavbarLink';\n\n/**\n * Props for the NavbarDropdown component.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the dropdown container element.\n */\nexport interface NavbarDropdownProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Dropdown aligned right. */\n right?: boolean;\n /** Dropdown opens upwards. */\n up?: boolean;\n /** Dropdown opens on hover. */\n hoverable?: boolean;\n /** Dropdown is open. */\n active?: boolean;\n /** Callback when dropdown active state changes. */\n onActiveChange?: (active: boolean) => void;\n /** Dropdown content. */\n children?: React.ReactNode;\n}\n\n/**\n * Dropdown parent (with options for hover, up, right, active)\n *\n * @function\n * @param {NavbarDropdownProps} props - Props for the NavbarDropdown component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the dropdown container element.\n * @returns {JSX.Element} The rendered dropdown.\n */\nexport const NavbarDropdown = forwardRef<HTMLDivElement, NavbarDropdownProps>(\n function NavbarDropdown(\n {\n className,\n right,\n up,\n hoverable,\n active: activeProp,\n onActiveChange,\n children,\n ...props\n },\n ref\n ) {\n const [active, setActive] = useState<boolean>(!!activeProp);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- syncing to controlled prop\n if (typeof activeProp === 'boolean') setActive(activeProp);\n }, [activeProp]);\n\n // Keep `onActiveChange` out of the state updater (a pure function) so Strict\n // Mode's double-invoked updaters don't double-fire it — mirrors `Dropdown`.\n const toggle = () => {\n const next = !active;\n setActive(next);\n onActiveChange?.(next);\n };\n\n const close = () => {\n /* istanbul ignore next: close() is only invoked once already active */\n if (!active) return;\n setActive(false);\n onActiveChange?.(false);\n };\n\n return (\n <NavbarDropdownContext.Provider value={{ active, toggle, close }}>\n <div\n ref={ref}\n className={classNames(\n usePrefixedClassNames('navbar-item', 'has-dropdown', {\n 'has-dropdown-up': up,\n 'is-right': right,\n 'is-hoverable': hoverable,\n 'is-active': active,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n </NavbarDropdownContext.Provider>\n );\n }\n);\n\nNavbarDropdown.displayName = 'NavbarDropdown';\n\n/**\n * Props for the NavbarDropdownMenu component.\n */\nexport interface NavbarDropdownMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Additional CSS classes. */\n className?: string;\n /** Dropdown aligned right. */\n right?: boolean;\n /** Dropdown opens upwards. */\n up?: boolean;\n /** Dropdown menu content. */\n children?: React.ReactNode;\n}\n\n/**\n * Dropdown menu container\n *\n * @function\n * @param {NavbarDropdownMenuProps} props - Props for the NavbarDropdownMenu component.\n * @returns {JSX.Element} The rendered dropdown menu.\n */\nexport const NavbarDropdownMenu: React.FC<NavbarDropdownMenuProps> = ({\n className,\n right,\n up,\n children,\n ...props\n}) => (\n <div\n className={classNames(\n usePrefixedClassNames('navbar-dropdown', {\n 'is-right': right,\n 'is-up': up,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n\n/**\n * Divider in dropdown menus.\n *\n * @function\n * @param {React.HTMLAttributes<HTMLHRElement>} props - Standard hr props.\n * @returns {JSX.Element} The rendered divider.\n */\nexport const NavbarDivider: React.FC<React.HTMLAttributes<HTMLHRElement>> = ({\n className,\n ...props\n}) => (\n <hr\n className={classNames(usePrefixedClassNames('navbar-divider'), className)}\n {...props}\n />\n);\n\n// Attach subcomponents\nexport const Navbar = withSubComponents(\n NavbarComponent,\n {\n Brand: NavbarBrand,\n Item: NavbarItem,\n Link: NavbarLink,\n Burger: NavbarBurger,\n Menu: NavbarMenu,\n Start: NavbarStart,\n End: NavbarEnd,\n Dropdown: NavbarDropdown,\n DropdownMenu: NavbarDropdownMenu,\n Divider: NavbarDivider,\n },\n 'Navbar'\n);\n\nexport default Navbar;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -10,7 +10,7 @@ import { usePortalContainer } from '../helpers/portal.js';
10
10
  import { useConfig } from '../helpers/Config.js';
11
11
  import { buttonType } from '../helpers/buttonType.js';
12
12
  import { useLatestRef } from '../helpers/useLatestRef.js';
13
- import { useOverlayStack } from '../helpers/overlayStack.js';
13
+ import { useOverlayStack, isModalOverlayOpen } from '../helpers/overlayStack.js';
14
14
  import { trapTab, firstTabStop } from '../helpers/useFocusTrap.js';
15
15
  import { inertProps } from '../helpers/inertProps.js';
16
16
  import { getDeepestActiveElement, getActiveElementInTree } from '../helpers/shadowDom.js';
@@ -69,8 +69,10 @@ const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width
69
69
  // the parent.
70
70
  const handleCloseRef = useLatestRef(handleClose);
71
71
  // Joins the stack of open overlays, so the sidebar answers Escape only
72
- // while it's the topmost overlay, and keeps it from those under it.
73
- const isTopmost = useOverlayStack(isOpen);
72
+ // while it's the topmost overlay, and keeps it from those under it. It's
73
+ // modal with an overlay: without one it leaves Tab to a modal overlay
74
+ // under it.
75
+ const isTopmost = useOverlayStack(isOpen, overlay);
74
76
  const closesOnEscape = escapeClose && canCancel && Boolean(onClose);
75
77
  // Handle escape key. On `window`, as in `Modal`, so everything inside the
76
78
  // sidebar has had the key first, and an Escape it used is left to it. One
@@ -89,18 +91,19 @@ const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width
89
91
  }, [isOpen, closesOnEscape, handleCloseRef, isTopmost]);
90
92
  // Keep Tab inside while there's an overlay, as `Modal` does:
91
93
  // `aria-modal` hides the rest of the page from assistive technology, so
92
- // the keyboard order has to agree. Only while it's the topmost overlay,
93
- // so a Modal or Dialog opened over the sidebar, even one rendered inside
94
- // it, holds Tab instead until it closes. On `window` for the same reason
95
- // as Escape: a trap inside, such as a portaled popup's, has had the Tab
96
- // first, and one it used is left where it put focus. It's the trap
94
+ // the keyboard order has to agree. Only while it's the topmost modal
95
+ // overlay, so a Modal or Dialog opened over the sidebar, even one
96
+ // rendered inside it, holds Tab instead until it closes, and a sidebar
97
+ // without an overlay opened over it doesn't. On `window` for the same
98
+ // reason as Escape: a trap inside, such as a portaled popup's, has had
99
+ // the Tab first, and one it used is left where it put focus. It's the trap
97
100
  // `useFocusTrap` sets, so a Tab the browser still takes out, as Safari
98
101
  // does past links, is sent back in.
99
102
  useEffect(() => {
100
103
  const node = sidebarRef.current;
101
104
  if (!isOpen || !overlay || !node)
102
105
  return undefined;
103
- return trapTab(node, window, isTopmost);
106
+ return trapTab(node, window, () => isTopmost('modal'));
104
107
  // A different `defaultTarget`, or switching `inline`, remounts the
105
108
  // aside, so the trap moves to the new node.
106
109
  }, [isOpen, overlay, isTopmost, defaultTarget, inline]);
@@ -111,7 +114,9 @@ const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width
111
114
  // the sidebar itself, and hand it back on close, as `Modal` does. A
112
115
  // different `defaultTarget` remounts the portaled sidebar: the cleanup
113
116
  // hands focus back from the old nodes, which left it on <body>, and the
114
- // re-run records the same opener and focuses the new nodes.
117
+ // re-run records the same opener and focuses the new nodes. Whether it
118
+ // takes focus is decided as it opens, so `overlay` changing while it's
119
+ // open leaves focus where the user has it.
115
120
  useEffect(() => {
116
121
  if (!isOpen)
117
122
  return undefined;
@@ -123,7 +128,13 @@ const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width
123
128
  // renders under `document.body` while its opener can be inside a
124
129
  // shadow root.
125
130
  const opener = getDeepestActiveElement();
126
- (firstTabStop(element) ?? element).focus();
131
+ // Without an overlay the sidebar holds no Tab, so with a modal overlay
132
+ // open under it, the first Tab would take focus back there and leave
133
+ // the sidebar's other controls out of reach. It leaves focus alone
134
+ // then, and the cleanup below finds focus outside and leaves it too.
135
+ if (overlay || !isModalOverlayOpen()) {
136
+ (firstTabStop(element) ?? element).focus();
137
+ }
127
138
  return () => {
128
139
  // Only while the sidebar still holds focus: closing one under another
129
140
  // overlay mustn't pull focus out of the one on top, and focus moved
@@ -134,6 +145,7 @@ const SidebarComponent = forwardRef(({ isOpen, onClose, position = 'left', width
134
145
  opener?.focus();
135
146
  }
136
147
  };
148
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- `overlay` is read as the sidebar opens, on purpose
137
149
  }, [isOpen, defaultTarget]);
138
150
  // Use combined ref
139
151
  const combinedRef = useCallback((node) => {