@allxsmith/bestax-bulma 5.64.0 → 5.65.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/Carousel.js +12 -66
- package/dist/esm/components/Carousel.js.map +1 -1
- package/dist/esm/components/Lightbox.js +756 -0
- package/dist/esm/components/Lightbox.js.map +1 -0
- package/dist/esm/components/Navbar.js.map +1 -1
- package/dist/esm/components/Reveal.js +1 -24
- package/dist/esm/components/Reveal.js.map +1 -1
- package/dist/esm/helpers/chevronIcons.js +24 -0
- package/dist/esm/helpers/chevronIcons.js.map +1 -0
- package/dist/esm/helpers/usePrefersReducedMotion.js +34 -0
- package/dist/esm/helpers/usePrefersReducedMotion.js.map +1 -0
- package/dist/esm/helpers/useSwipe.js +82 -0
- package/dist/esm/helpers/useSwipe.js.map +1 -0
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +924 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Lightbox.d.ts +244 -0
- package/dist/types/components/Navbar.d.ts +10 -0
- package/dist/types/helpers/chevronIcons.d.ts +14 -0
- package/dist/types/helpers/usePrefersReducedMotion.d.ts +10 -0
- package/dist/types/helpers/useSwipe.d.ts +66 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types-cjs/components/Lightbox.d.ts +244 -0
- package/dist/types-cjs/components/Navbar.d.ts +10 -0
- package/dist/types-cjs/helpers/chevronIcons.d.ts +14 -0
- package/dist/types-cjs/helpers/usePrefersReducedMotion.d.ts +10 -0
- package/dist/types-cjs/helpers/useSwipe.d.ts +66 -0
- package/dist/types-cjs/index.d.ts +1 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +6 -6
- package/src/scss/CLAUDE.md +1 -1
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/components/_lightbox.scss +392 -0
- package/src/scss/elements/_button.scss +49 -0
- package/src/scss/elements/_index.scss +1 -0
- package/src/scss/elements/_loader.scss +10 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Lightbox.js","sources":["../../../src/components/Lightbox.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { buttonType } from '../helpers/buttonType';\nimport { type PolymorphicRef } from '../helpers/polymorphic';\nimport { isDev, warnOnce } from '../helpers/devWarnings';\nimport { useLatestRef } from '../helpers/useLatestRef';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useNumberFormat } from '../helpers/localeFormat';\nimport { visuallyHidden } from '../helpers/statusRegion';\nimport { usePrefersReducedMotion } from '../helpers/usePrefersReducedMotion';\nimport { useSwipe } from '../helpers/useSwipe';\nimport { ChevronNextIcon, ChevronPrevIcon } from '../helpers/chevronIcons';\nimport { Modal } from './Modal';\nimport { Button } from '../elements/Button';\nimport { Buttons } from '../elements/Buttons';\nimport { Figure } from '../elements/Figure';\nimport { Loader } from '../elements/Loader';\n\n/** One image a Lightbox shows. */\nexport interface LightboxItem {\n /** The full-size image's URL. */\n src: string;\n /**\n * The image's text alternative, which the status line reads after each\n * move. In a viewer the image is the content, so `''` is almost never\n * right; a development build warns once for an item without one.\n */\n alt: string;\n /** Shown under the image as its `<figcaption>`. */\n caption?: React.ReactNode;\n /** The `<img>`'s `srcSet`, so the browser picks a size for the screen. Preloading uses it too. */\n srcSet?: string;\n /** The `<img>`'s `sizes`, read with `srcSet`. */\n sizes?: string;\n}\n\n/**\n * The words a Lightbox writes. Each is English unless you give your own,\n * and the numbers in the default progress line are written in the\n * `LocaleProvider`'s locale.\n */\nexport interface LightboxLabels {\n /**\n * The close button's name.\n * @defaultValue 'Close'\n */\n close?: string;\n /**\n * The previous button's name.\n * @defaultValue 'Previous image'\n */\n previous?: string;\n /**\n * The next button's name.\n * @defaultValue 'Next image'\n */\n next?: string;\n /**\n * The zoom-in button's name.\n * @defaultValue 'Zoom in'\n */\n zoomIn?: string;\n /**\n * The zoom-out button's name.\n * @defaultValue 'Zoom out'\n */\n zoomOut?: string;\n /**\n * The button that fits the image again.\n * @defaultValue 'Reset zoom'\n */\n resetZoom?: string;\n /**\n * The `Loader`'s name while an image loads.\n * @defaultValue 'Loading image'\n */\n loading?: string;\n /**\n * Shown, above the alt text, when an image fails to load. The status line\n * for a failed image starts with it, then a space and the line a loaded\n * image gets, so write it as a whole sentence, punctuated as your language\n * does.\n * @defaultValue \"This image didn't load.\"\n */\n loadError?: string;\n /**\n * The button that tries a failed image again.\n * @defaultValue 'Retry'\n */\n retry?: string;\n /**\n * The start of the status line read after each move, which goes on with\n * a colon and the image's alt: \"Image 3 of 10: Harbour at dusk\". For a\n * failed image, `loadError` and a space come first. It gets the image's\n * place counting from 1, and the number of images.\n * @defaultValue (current, total) => 'Image ' + current + ' of ' + total\n */\n progress?: (current: number, total: number) => string;\n}\n\n/**\n * Props for the Lightbox component. Its children render where it stands,\n * with no wrapper. The helper props, the other attributes and the `ref`\n * land on the viewer's `.modal` element while it's open.\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the viewer's `.modal` element, `null` while it's closed.\n */\nexport interface LightboxProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** **Required.** The images, in order. */\n items: LightboxItem[];\n /** Rendered in place: usually `Lightbox.Trigger`s, in whatever layout you like. */\n children?: React.ReactNode;\n /** Whether the viewer is open (controlled). With no `items` it shows nothing. */\n open?: boolean;\n /**\n * Whether the viewer starts open (uncontrolled).\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called when a trigger, the close button, Escape, a click on the\n * background or a swipe down opens or closes the viewer, and with `false`\n * when `items` goes from some to none while it's open.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The index of the image shown (controlled). A value past either end is\n * shown as the last or the first image, or wrapped round with `repeat`,\n * without calling `onChange`.\n */\n value?: number;\n /**\n * The image an uncontrolled viewer shows when something other than a\n * trigger opens it. A trigger opens at its own `index`.\n * @defaultValue 0\n */\n defaultValue?: number;\n /**\n * Called with the new index when an arrow, a key or a swipe changes the\n * image, and when a trigger opens the viewer, with the trigger's `index`\n * even when that's the image already shown, before `onOpenChange(true)`.\n * A parent that opens the viewer from `value` hears the trigger that way.\n */\n onChange?: (value: number) => void;\n /**\n * Go from the last image to the first and back, as Carousel does. Off,\n * the previous and next buttons are `aria-disabled` at the ends.\n * @defaultValue true\n */\n repeat?: boolean;\n /**\n * Zoom with the buttons, the wheel, a double click or tap, pinch and the\n * `+`, `-` and `0` keys, and pan a zoomed image by dragging or with the\n * arrow keys. Zoom waits for the image to load. `false` drops the zoom\n * buttons and all of it.\n * @defaultValue true\n */\n zoomable?: boolean;\n /**\n * How far an image zooms, as a multiple of its fitted size. The smallest\n * zoom is always the fitted size.\n * @defaultValue 3\n */\n maxZoom?: number;\n /**\n * Close on Escape. Only the topmost open overlay answers, as with Modal.\n * @defaultValue true\n */\n closeOnEscape?: boolean;\n /**\n * Close on a click on the dark background around the image. The space\n * around the image, beside the toolbar's buttons and under the caption is\n * all background.\n * @defaultValue true\n */\n closeOnClickOutside?: boolean;\n /**\n * Renders the viewer into a portal: `true` for the `ConfigProvider`'s\n * `portalContainer` (`document.body` by default), a selector string, or an\n * element. `false` renders it in place. It's on by default, unlike Modal's,\n * Dialog's and Command.Dialog's, because its triggers sit in gallery\n * cells, and a cell with a transform or a filter would trap a viewer\n * rendered in place.\n * @defaultValue true\n */\n portal?: boolean | string | HTMLElement;\n /**\n * The dialog's accessible name. It stays the same from image to image;\n * the status line says which image is shown.\n * @defaultValue 'Image viewer'\n */\n ariaLabel?: string;\n /** The words it writes, for another language. */\n labels?: LightboxLabels;\n}\n\n/**\n * The Lightbox.Trigger component's own props, on top of the attributes of\n * whatever element `as` renders.\n */\nexport interface LightboxTriggerOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor'\n> {\n /** **Required.** The index in `items` the viewer opens at. */\n index: number;\n /**\n * What the button shows: a thumbnail, or text such as \"View all photos\".\n * A ratio `Image` here takes `as=\"div\"`, since its `<figure>` would keep\n * the image's alt from naming the button.\n */\n children?: React.ReactNode;\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * Props for Lightbox.Trigger, a `<button type=\"button\"\n * aria-haspopup=\"dialog\">` that opens the viewer. Its content names it, so\n * give the thumbnail inside a real `alt`. A ratio `Image` renders a\n * `<figure>`, and an image inside a figure doesn't name the button around\n * it, so give that `Image` `as=\"div\"`. A development build warns for a\n * trigger outside a `Lightbox` or with no name.\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders: the `<button>`, or what `Button` renders.\n */\nexport type LightboxTriggerProps<T extends React.ElementType = 'button'> =\n LightboxTriggerOwnProps &\n Omit<\n React.ComponentPropsWithoutRef<T>,\n keyof LightboxTriggerOwnProps | 'as' | ElementColor<T>\n > & {\n /**\n * Renders the trigger through another component, which gets its class,\n * `aria-haspopup`, `type=\"button\"`, click handler and ref along with\n * its own props. `as={Button} color=\"link\"` draws it as Bulma's link\n * button. `color` is taken only with a component: on an element it\n * would be HTML's old presentational attribute.\n */\n as?: T;\n };\n\n/**\n * `color`, for an element `as`: a `<button>` or another tag takes no\n * `color`, as Link and Navbar.Item take none, while a component such as\n * Button keeps its own.\n */\ntype ElementColor<T extends React.ElementType> = T extends string\n ? 'color'\n : never;\n\n/**\n * Lightbox.Trigger's call signatures, those of `PolymorphicComponent` over\n * `LightboxTriggerProps`, so `color` follows `as` as described there.\n */\ninterface LightboxTriggerComponent {\n <T extends React.ElementType = 'button'>(\n props: LightboxTriggerProps<T> & { ref?: PolymorphicRef<T> }\n ): React.ReactElement | null;\n // The derivation overload `PolymorphicComponent` documents.\n (\n props: LightboxTriggerProps & { ref?: PolymorphicRef<'button'> }\n ): React.ReactElement | null;\n displayName?: string;\n}\n\n/**\n * The shape the implementation destructures. The public contract is the\n * generic `LightboxTriggerProps<T>` above.\n */\ntype LightboxTriggerImplProps = LightboxTriggerOwnProps & {\n as?: React.ElementType;\n color?: string;\n type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];\n onClick?: React.MouseEventHandler<HTMLElement>;\n};\n\n/** What a trigger asks of the Lightbox around it. */\ninterface LightboxContextValue {\n openAt: (index: number) => void;\n}\n\nconst LightboxContext = createContext<LightboxContextValue | null>(null);\n\n/** Each zoom button or key multiplies or divides the zoom by this. */\nconst ZOOM_STEP = 1.5;\n/** Where a double click or a double tap zooms to. */\nconst DOUBLE_ZOOM = 2;\n/** How far an arrow key pans a zoomed image, in CSS pixels. */\nconst PAN_STEP = 50;\n/** How long an image can take before the Loader shows, in milliseconds. */\nconst LOADER_DELAY = 300;\n/** How long the status line waits after a change, so a quick run of moves is read once. */\nconst STATUS_DELAY = 500;\n/** How far a finger can move and still tap, in CSS pixels. */\nconst TAP_SLOP = 10;\n/** The longest gap between the two taps of a double tap, in milliseconds. */\nconst DOUBLE_TAP_TIME = 300;\n/** How far apart the two taps of a double tap can land, in CSS pixels. */\nconst DOUBLE_TAP_SLOP = 30;\n/** A pinch that ends this close to the fitted size snaps back to it. */\nconst SNAP_ZOOM = 1.01;\n\n/**\n * The zoom and pan of the image shown: `zoom` as a multiple of its fitted\n * size, and `x` and `y` how far its centre has moved from where it rests.\n * `animate` is off while a gesture drives it, so the image follows the\n * pointer rather than easing after it.\n */\ninterface View {\n zoom: number;\n x: number;\n y: number;\n animate: boolean;\n}\n\nconst FITTED: View = { zoom: 1, x: 0, y: 0, animate: true };\n\n/**\n * Where the image rests and how much room the viewer has, in the viewer's\n * own coordinates. Read from the layout, which a transform doesn't change,\n * so it holds while the image is zoomed or easing.\n */\ninterface Geometry {\n /** The image's centre at rest. */\n cx: number;\n cy: number;\n /** Its fitted size. */\n width: number;\n height: number;\n /** The viewer's size. */\n viewWidth: number;\n viewHeight: number;\n /** Where the viewer sits on screen, to turn a pointer into its coordinates. */\n left: number;\n top: number;\n}\n\n/**\n * Reads the image's resting box and the viewer's size.\n *\n * @function\n * @param {HTMLElement} image - The image shown.\n * @param {HTMLElement} root - The viewer, its `.modal` element.\n * @returns {Geometry} The geometry the zoom and pan are kept within.\n */\nfunction measure(image: HTMLElement, root: HTMLElement): Geometry {\n let x = 0;\n let y = 0;\n for (\n let node: HTMLElement | null = image;\n node && node !== root;\n node = node.offsetParent as HTMLElement | null\n ) {\n x += node.offsetLeft;\n y += node.offsetTop;\n }\n const box = root.getBoundingClientRect();\n return {\n cx: x + image.offsetWidth / 2,\n cy: y + image.offsetHeight / 2,\n width: image.offsetWidth,\n height: image.offsetHeight,\n viewWidth: root.clientWidth,\n viewHeight: root.clientHeight,\n left: box.left,\n top: box.top,\n };\n}\n\nconst clamp = (value: number, min: number, max: number) =>\n Math.min(Math.max(value, min), max);\n\n/**\n * An offset along one axis, kept to the image's edges: a zoomed image wider\n * than the viewer can't leave a gap at either side, and one that still fits\n * stays where it rests, moved only as far as it takes to keep it in view.\n */\nfunction fitAxis(\n offset: number,\n centre: number,\n size: number,\n room: number,\n zoom: number\n): number {\n const half = (size * zoom) / 2;\n // The offsets that put the image's start edge on the viewer's, and its end edge.\n const start = half - centre;\n const end = room - centre - half;\n return half * 2 > room ? clamp(offset, end, start) : clamp(0, start, end);\n}\n\n/** The view, with its offsets kept to the image's edges. */\nfunction fitView(view: View, geometry: Geometry): View {\n return {\n ...view,\n x: fitAxis(\n view.x,\n geometry.cx,\n geometry.width,\n geometry.viewWidth,\n view.zoom\n ),\n y: fitAxis(\n view.y,\n geometry.cy,\n geometry.height,\n geometry.viewHeight,\n view.zoom\n ),\n };\n}\n\n/**\n * The view at another zoom, with the point under `(px, py)`, in the\n * viewer's coordinates, still there.\n */\nfunction zoomView(\n view: View,\n zoom: number,\n px: number,\n py: number,\n geometry: Geometry,\n animate: boolean\n): View {\n if (zoom <= 1) return { ...FITTED, animate };\n const ratio = zoom / view.zoom;\n const dx = px - geometry.cx;\n const dy = py - geometry.cy;\n return fitView(\n {\n zoom,\n x: dx - (dx - view.x) * ratio,\n y: dy - (dy - view.y) * ratio,\n animate,\n },\n geometry\n );\n}\n\n/**\n * Whether a button has an accessible name from what it holds: its own\n * label, text, an image's alt or a label on an element inside, leaving out\n * what's hidden from assistive technology and what's inside a `<figure>`,\n * whose content doesn't name the button around it. A development check, so\n * it reads the common sources rather than the whole name computation.\n */\nfunction hasName(element: Element): boolean {\n if (\n (element.getAttribute('aria-label') || '').trim() ||\n (element.getAttribute('aria-labelledby') || '').trim() ||\n (element.getAttribute('title') || '').trim()\n ) {\n return true;\n }\n return Array.from(element.childNodes).some(node =>\n node instanceof Element\n ? node.getAttribute('aria-hidden') !== 'true' &&\n node.tagName !== 'FIGURE' &&\n ((node instanceof HTMLImageElement && !!node.alt.trim()) ||\n hasName(node))\n : !!(node.textContent as string).trim()\n );\n}\n\n/** Text a key typed into a field is that field's, not the viewer's. */\nconst isTextEntry = (target: EventTarget) =>\n (target as Element).matches(\n 'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"])'\n );\n\nconst ZoomInIcon = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M21 21l-5-5M11 8v6M8 11h6\" />\n </svg>\n);\n\nconst ZoomOutIcon = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M21 21l-5-5M8 11h6\" />\n </svg>\n);\n\nconst ResetZoomIcon = () => (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5\" />\n </svg>\n);\n\n/**\n * A button around a thumbnail, or a line of text, that opens the viewer at its `index`.\n *\n * @function\n * @param {LightboxTriggerProps} props - Props for the trigger.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered button.\n */\nexport const LightboxTrigger = forwardRef(function LightboxTrigger(\n triggerProps: LightboxTriggerProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n as: Component = 'button',\n index,\n className,\n children,\n onClick,\n // Kept from the helper classes, which read `color` as a text color: it\n // belongs to a component `as`, as Button's `color=\"link\"` does.\n color,\n ...props\n } = triggerProps as LightboxTriggerImplProps;\n const lightbox = useContext(LightboxContext);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const triggerClass = usePrefixedClassNames('lightbox-trigger');\n const buttonRef = useRef<HTMLElement | null>(null);\n\n const setRefs = useCallback(\n (node: HTMLElement | null) => {\n buttonRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) {\n (ref as React.MutableRefObject<HTMLElement | null>).current = node;\n }\n return undefined;\n },\n [ref]\n );\n\n if (!lightbox) {\n warnOnce(\n 'Lightbox.Trigger:outside',\n '[bestax-bulma] <Lightbox.Trigger> is outside a <Lightbox>, so it ' +\n 'opens nothing. Put it inside the Lightbox whose items it opens.'\n );\n }\n\n // Its content is its name, and a thumbnail with `alt=\"\"` leaves it\n // nameless. Checked after each commit, since the content can change.\n useEffect(() => {\n // An `as` component that keeps its ref, or hands back a handle of its\n // own, leaves no element to check.\n const button = buttonRef.current;\n if (isDev() && button instanceof Element && !hasName(button)) {\n warnOnce(\n 'Lightbox.Trigger:no-name',\n '[bestax-bulma] <Lightbox.Trigger> has no accessible name. Give ' +\n 'the image inside it an alt, or the button some text or an ' +\n 'aria-label. An image inside a <figure>, which a ratio Image ' +\n 'renders, doesn\\'t name a button, so give that Image as=\"div\".'\n );\n }\n });\n\n return (\n <Component\n ref={setRefs}\n className={classNames(triggerClass, bulmaHelperClasses, className)}\n aria-haspopup=\"dialog\"\n {...rest}\n // Never on an element, where it would be HTML's presentational\n // attribute, even from a caller the types don't check.\n {...(typeof Component === 'string' ? {} : { color })}\n // A component such as Button renders a <button> too, and needs the\n // type as much, so a trigger in a form doesn't submit it.\n {...(Component === 'button' || typeof Component !== 'string'\n ? { type: buttonType(rest.type) }\n : {})}\n onClick={(event: React.MouseEvent<HTMLElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || !lightbox) return;\n // Safari doesn't focus a button that's clicked, and the viewer hands\n // focus back to whatever had it when it opened.\n event.currentTarget.focus({ preventScroll: true });\n lightbox.openAt(index);\n }}\n >\n {children}\n </Component>\n );\n}) as LightboxTriggerComponent;\n\nLightboxTrigger.displayName = 'Lightbox.Trigger';\n\n/** What the viewer takes from the Lightbox around it. */\ninterface LightboxViewerProps extends Omit<\n LightboxProps,\n | 'items'\n | 'children'\n | 'open'\n | 'defaultOpen'\n | 'onOpenChange'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n> {\n items: LightboxItem[];\n index: number;\n onIndexChange: (index: number) => void;\n onClose: () => void;\n}\n\n/**\n * The open viewer: a modal dialog showing one image, mounted only while the\n * Lightbox is open, so each opening starts fitted.\n *\n * @function\n * @param {LightboxViewerProps} props - The Lightbox's props and its state.\n * @returns {JSX.Element} The rendered dialog.\n */\nconst LightboxViewer = forwardRef<HTMLDivElement, LightboxViewerProps>(\n function LightboxViewer(\n {\n items,\n index,\n onIndexChange,\n onClose,\n repeat,\n zoomable = true,\n maxZoom = 3,\n closeOnEscape = true,\n closeOnClickOutside = true,\n portal = true,\n ariaLabel = 'Image viewer',\n labels,\n className,\n onKeyDown,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onPointerCancel,\n ...props\n },\n ref\n ) {\n const count = items.length;\n const item = items[index];\n const limit = Math.max(1, Number.isFinite(maxZoom) ? maxZoom : 3);\n const formatNumber = useNumberFormat();\n const number = (value: number) =>\n formatNumber ? formatNumber(value) : String(value);\n const words = {\n close: labels?.close || 'Close',\n previous: labels?.previous || 'Previous image',\n next: labels?.next || 'Next image',\n zoomIn: labels?.zoomIn || 'Zoom in',\n zoomOut: labels?.zoomOut || 'Zoom out',\n resetZoom: labels?.resetZoom || 'Reset zoom',\n loading: labels?.loading || 'Loading image',\n loadError: labels?.loadError || \"This image didn't load.\",\n retry: labels?.retry || 'Retry',\n progress:\n labels?.progress ??\n ((current: number, total: number) =>\n `Image ${number(current)} of ${number(total)}`),\n };\n\n const reducedMotion = usePrefersReducedMotion();\n const hydrated = useIsHydrated();\n\n const rootRef = useRef<HTMLDivElement | null>(null);\n const setRoot = useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n return undefined;\n },\n [ref]\n );\n const [image, setImage] = useState<HTMLImageElement | null>(null);\n\n // The image shown and how it's doing. `leaving` is the image before it,\n // kept on screen while the new one loads and then faded out over it. The\n // fades are CSS animations, which start when the stylesheet's selector\n // first matches, even for an image that was already loaded, where a\n // transition wouldn't run.\n const [shown, setShown] = useState({ index, item });\n const [status, setStatus] = useState<\n 'loading' | 'slow' | 'loaded' | 'error'\n >('loading');\n const [attempt, setAttempt] = useState(0);\n const [leaving, setLeaving] = useState<LightboxItem>();\n const [view, setView] = useState<View>(FITTED);\n const zoomed = view.zoom > 1;\n // The view as last set, for a gesture to go on from: pointer events can\n // arrive faster than React renders.\n const viewRef = useRef(view);\n useClientLayoutEffect(() => {\n viewRef.current = view;\n });\n const updateView = (next: (current: View) => View) => {\n viewRef.current = next(viewRef.current);\n setView(viewRef.current);\n };\n\n // A move starts the new image fitted and loading, and so does another\n // image at the same index after `items` changes. Adjusted while rendering,\n // React's pattern for state that follows a prop, so the old zoom or load\n // state never paints on the new image.\n if (\n shown.index !== index ||\n shown.item.src !== item.src ||\n shown.item.srcSet !== item.srcSet\n ) {\n setShown({ index, item });\n setLeaving(\n reducedMotion ? undefined : status === 'loaded' ? shown.item : leaving\n );\n setStatus('loading');\n setAttempt(0);\n setView(FITTED);\n }\n\n const fail = () => {\n setStatus('error');\n setLeaving(undefined);\n };\n\n // An image the server rendered loads or fails before hydration, so its\n // event comes before React listens for it. A broken image is complete\n // and has no size, and so is a loaded SVG with none of its own, so\n // `decode()` tells those two apart.\n useClientLayoutEffect(() => {\n if (!image?.complete) return undefined;\n if (image.naturalWidth > 0) {\n setStatus('loaded');\n return undefined;\n }\n let live = true;\n image.decode().then(\n () => live && setStatus('loaded'),\n () => {\n if (!live) return;\n setStatus('error');\n setLeaving(undefined);\n }\n );\n return () => {\n live = false;\n };\n }, [image]);\n\n // The Loader shows only for an image that takes a while.\n useEffect(() => {\n if (status !== 'loading') return undefined;\n // Cleared by any change of status, so it only fires on a load still\n // under way.\n const timer = setTimeout(() => {\n setStatus('slow');\n setLeaving(undefined);\n }, LOADER_DELAY);\n return () => clearTimeout(timer);\n }, [status, shown, attempt]);\n\n // The images either side, fetched ahead so a move shows them at once.\n // With `repeat` and two images, both sides are the one other image, so\n // the indexes are deduplicated and it's fetched once.\n const neighbours = Array.from(\n new Set(\n [index - 1, index + 1].map(i => (repeat ? (i + count) % count : i))\n )\n )\n .filter(i => i >= 0 && i < count && i !== index)\n .map(i => items[i]);\n // None, one or two of them, in no particular order.\n const [firstNeighbour, secondNeighbour] = neighbours;\n const firstSrc = firstNeighbour?.src;\n const firstSrcSet = firstNeighbour?.srcSet;\n const firstSizes = firstNeighbour?.sizes;\n const secondSrc = secondNeighbour?.src;\n const secondSrcSet = secondNeighbour?.srcSet;\n const secondSizes = secondNeighbour?.sizes;\n useEffect(() => {\n const fetchAhead = (src?: string, srcSet?: string, sizes?: string) => {\n if (!src) return;\n const img = document.createElement('img');\n if (sizes) img.sizes = sizes;\n if (srcSet) img.srcset = srcSet;\n img.src = src;\n };\n fetchAhead(firstSrc, firstSrcSet, firstSizes);\n fetchAhead(secondSrc, secondSrcSet, secondSizes);\n }, [\n firstSrc,\n firstSrcSet,\n firstSizes,\n secondSrc,\n secondSrcSet,\n secondSizes,\n ]);\n\n // The status line, written a moment after it changes, so a quick run of\n // moves is read once. It's written on opening too, which says which image\n // the viewer opened at.\n const progress = words.progress(index + 1, count);\n const position = item.alt ? `${progress}: ${item.alt}` : progress;\n // A failed image's line says which image failed too, so a move from one\n // failed image to another still changes it.\n const message =\n status === 'error' ? `${words.loadError} ${position}` : position;\n const [said, setSaid] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setSaid(message), STATUS_DELAY);\n return () => clearTimeout(timer);\n }, [message]);\n\n // ---- Moving -------------------------------------------------------------\n\n const canPrev = repeat ? count > 1 : index > 0;\n const canNext = repeat ? count > 1 : index < count - 1;\n const go = (next: number) => {\n if (next !== index) onIndexChange(next);\n };\n const step = (delta: 1 | -1) => {\n if (delta < 0 ? !canPrev : !canNext) return;\n go((index + delta + count) % count);\n };\n const isRtl = (element: Element) =>\n getComputedStyle(element).direction === 'rtl';\n\n const swipe = useSwipe<HTMLElement>({\n enabled: !zoomed,\n vertical: true,\n onSwipe: direction => {\n if (direction === 'down') {\n onClose();\n } else if (direction !== 'up') {\n // A swipe left brings the next image in from the right, and right\n // to left the other way round.\n const forward = isRtl(rootRef.current as HTMLDivElement)\n ? 'right'\n : 'left';\n step(direction === forward ? 1 : -1);\n }\n },\n });\n\n // ---- Zooming and panning --------------------------------------------------\n\n // Zoom waits for the image: a loading one has no size to zoom, and a\n // failed one isn't there.\n const canZoom = zoomable && status === 'loaded';\n\n // Only called with an image on screen: every way to zoom or pan checks\n // `canZoom` first, and a pan needs a zoom.\n const geometry = () =>\n measure(image as HTMLImageElement, rootRef.current as HTMLDivElement);\n\n /** Zooms to `zoom`, kept within the limits, about the viewer's centre. */\n const zoomTo = (next: (zoom: number) => number) => {\n if (!canZoom) return;\n const g = geometry();\n updateView(v =>\n zoomView(\n v,\n clamp(next(v.zoom), 1, limit),\n g.viewWidth / 2,\n g.viewHeight / 2,\n g,\n true\n )\n );\n };\n const zoomIn = () => zoomTo(zoom => zoom * ZOOM_STEP);\n const zoomOut = () => zoomTo(zoom => zoom / ZOOM_STEP);\n const resetZoom = () => updateView(() => FITTED);\n\n /** A double click or tap: fitted to 2x at the pointer, and back. */\n const toggleZoomAt = (clientX: number, clientY: number) => {\n const g = geometry();\n updateView(v =>\n v.zoom > 1\n ? FITTED\n : zoomView(\n v,\n Math.min(DOUBLE_ZOOM, limit),\n clientX - g.left,\n clientY - g.top,\n g,\n true\n )\n );\n };\n\n const pan = (dx: number, dy: number) => {\n const g = geometry();\n updateView(v =>\n fitView({ ...v, x: v.x + dx, y: v.y + dy, animate: true }, g)\n );\n };\n\n // The wheel zooms at the pointer. A listener of its own, since React's\n // wheel handlers are passive and can't stop the page from zooming too.\n const handleWheel = useLatestRef((event: WheelEvent) => {\n const g = geometry();\n const lines = event.deltaMode === 1 ? 16 : 1;\n const delta = clamp(event.deltaY * lines, -100, 100);\n updateView(v =>\n zoomView(\n v,\n clamp(v.zoom * Math.exp(-delta / 300), 1, limit),\n event.clientX - g.left,\n event.clientY - g.top,\n g,\n false\n )\n );\n });\n useEffect(() => {\n if (!canZoom) return undefined;\n const target = image as HTMLImageElement;\n const onWheel = (event: WheelEvent) => {\n event.preventDefault();\n handleWheel.current(event);\n };\n target.addEventListener('wheel', onWheel, { passive: false });\n return () => target.removeEventListener('wheel', onWheel);\n }, [image, canZoom, handleWheel]);\n\n // Pointers on the image: one pans a zoomed image, two pinch. The first\n // has to land on the image; the second can land anywhere in the viewer.\n const pointersRef = useRef(new Map<number, { x: number; y: number }>());\n const gestureRef = useRef<\n | {\n kind: 'pan';\n x: number;\n y: number;\n from: View;\n geometry: Geometry;\n }\n | {\n kind: 'pinch';\n distance: number;\n x: number;\n y: number;\n from: View;\n geometry: Geometry;\n }\n | null\n >(null);\n const tapRef = useRef<{ x: number; y: number } | null>(null);\n const lastTapRef = useRef<{ x: number; y: number; time: number } | null>(\n null\n );\n const lastPointerTypeRef = useRef('');\n\n const startPan = (x: number, y: number) => {\n gestureRef.current = {\n kind: 'pan',\n x,\n y,\n from: viewRef.current,\n geometry: geometry(),\n };\n };\n\n const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n lastPointerTypeRef.current = event.pointerType;\n // A second finger is a pinch, never a swipe, whether or not anything\n // zooms, and wherever in the viewer it lands.\n if (!event.isPrimary) swipe.cancel();\n if (!canZoom || event.defaultPrevented) return;\n const onImage = event.target === image;\n if (!onImage && pointersRef.current.size === 0) return;\n pointersRef.current.set(event.pointerId, {\n x: event.clientX,\n y: event.clientY,\n });\n\n // Two or more is a pinch, between the first two.\n if (pointersRef.current.size > 1) {\n const g = geometry();\n const [a, b] = Array.from(pointersRef.current.values());\n tapRef.current = null;\n swipe.cancel();\n gestureRef.current = {\n kind: 'pinch',\n distance: Math.hypot(a.x - b.x, a.y - b.y) || 1,\n x: (a.x + b.x) / 2 - g.left,\n y: (a.y + b.y) / 2 - g.top,\n from: viewRef.current,\n geometry: g,\n };\n } else {\n tapRef.current = { x: event.clientX, y: event.clientY };\n if (zoomed) {\n // So the pan follows a mouse that leaves the image.\n (event.target as Element).setPointerCapture(event.pointerId);\n startPan(event.clientX, event.clientY);\n }\n }\n };\n\n const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n onPointerMove?.(event);\n const point = pointersRef.current.get(event.pointerId);\n if (!point) return;\n point.x = event.clientX;\n point.y = event.clientY;\n if (\n tapRef.current &&\n Math.hypot(\n event.clientX - tapRef.current.x,\n event.clientY - tapRef.current.y\n ) > TAP_SLOP\n ) {\n tapRef.current = null;\n }\n\n const current = gestureRef.current;\n if (current?.kind === 'pinch') {\n const [a, b] = Array.from(pointersRef.current.values());\n const g = current.geometry;\n const zoom = clamp(\n (current.from.zoom * Math.hypot(a.x - b.x, a.y - b.y)) /\n current.distance,\n 1,\n limit\n );\n // The point of the image under the pinch's start stays between the\n // fingers, so they can pan as they pinch.\n const midX = (a.x + b.x) / 2 - g.left;\n const midY = (a.y + b.y) / 2 - g.top;\n const imageX = (current.x - g.cx - current.from.x) / current.from.zoom;\n const imageY = (current.y - g.cy - current.from.y) / current.from.zoom;\n updateView(() =>\n fitView(\n {\n zoom,\n x: midX - g.cx - imageX * zoom,\n y: midY - g.cy - imageY * zoom,\n animate: false,\n },\n g\n )\n );\n } else if (current) {\n updateView(() =>\n fitView(\n {\n ...current.from,\n x: current.from.x + event.clientX - current.x,\n y: current.from.y + event.clientY - current.y,\n animate: false,\n },\n current.geometry\n )\n );\n }\n };\n\n const handlePointerEnd = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!pointersRef.current.delete(event.pointerId)) return;\n const wasPinch = gestureRef.current?.kind === 'pinch';\n gestureRef.current = null;\n if (wasPinch) {\n if (viewRef.current.zoom < SNAP_ZOOM) {\n updateView(() => FITTED);\n } else {\n // A finger left down after a pinch carries on as a pan.\n const [point] = Array.from(pointersRef.current.values());\n startPan(point.x, point.y);\n }\n }\n\n // Two quick taps in the same place zoom, the touch screen's double click.\n if (\n event.type === 'pointerup' &&\n event.pointerType === 'touch' &&\n tapRef.current\n ) {\n const previous = lastTapRef.current;\n if (\n previous &&\n event.timeStamp - previous.time < DOUBLE_TAP_TIME &&\n Math.hypot(event.clientX - previous.x, event.clientY - previous.y) <\n DOUBLE_TAP_SLOP\n ) {\n lastTapRef.current = null;\n toggleZoomAt(event.clientX, event.clientY);\n } else {\n lastTapRef.current = {\n x: event.clientX,\n y: event.clientY,\n time: event.timeStamp,\n };\n }\n }\n tapRef.current = null;\n };\n\n // ---- Keys -----------------------------------------------------------------\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n // A key from content React portals elsewhere, such as a popover's,\n // is that content's.\n !event.currentTarget.contains(event.target as Node) ||\n isTextEntry(event.target)\n ) {\n return;\n }\n const forward = isRtl(event.currentTarget) ? -1 : 1;\n switch (event.key) {\n case 'ArrowLeft':\n if (zoomed) pan(PAN_STEP, 0);\n else step(forward === 1 ? -1 : 1);\n break;\n case 'ArrowRight':\n if (zoomed) pan(-PAN_STEP, 0);\n else step(forward === 1 ? 1 : -1);\n break;\n case 'ArrowUp':\n case 'ArrowDown':\n if (!zoomed) return;\n pan(0, event.key === 'ArrowUp' ? PAN_STEP : -PAN_STEP);\n break;\n case 'Home':\n go(0);\n break;\n case 'End':\n go(count - 1);\n break;\n case '+':\n case '=':\n case '-':\n case '0':\n if (!canZoom) return;\n if (event.key === '0') resetZoom();\n else if (event.key === '-') zoomOut();\n else zoomIn();\n break;\n default:\n return;\n }\n event.preventDefault();\n };\n\n // ---- Loading ----------------------------------------------------------------\n\n const retry = () => {\n setAttempt(n => n + 1);\n setStatus('loading');\n // Cleared, so a Retry that fails again is announced again.\n setSaid('');\n // The Retry button goes with the error, so focus waits on the dialog.\n (rootRef.current as HTMLDivElement).focus();\n };\n\n // ---- Rendering --------------------------------------------------------------\n\n const rootClass = usePrefixedClassNames('lightbox', {\n 'is-zoomed': zoomed,\n });\n const toolbarClass = usePrefixedClassNames('lightbox-toolbar');\n const progressClass = usePrefixedClassNames('lightbox-progress');\n const figureClass = usePrefixedClassNames('lightbox-figure');\n const imageClass = usePrefixedClassNames('lightbox-image');\n const loadingClass = usePrefixedClassNames('is-loading');\n const leavingClass = usePrefixedClassNames('lightbox-image', 'is-leaving');\n const captionClass = usePrefixedClassNames('lightbox-caption');\n const startsSwipe = (target: EventTarget) =>\n !(target as Element).closest(\n `button, a, input, select, textarea, .${captionClass}`\n );\n const errorClass = usePrefixedClassNames('lightbox-error');\n const previousClass = usePrefixedClassNames('lightbox-arrow', 'is-prev');\n const nextClass = usePrefixedClassNames('lightbox-arrow', 'is-next');\n\n const imageStyle: React.CSSProperties | undefined = zoomed\n ? {\n transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`,\n transition: view.animate ? undefined : 'none',\n }\n : view.animate\n ? undefined\n : { transition: 'none' };\n const figureStyle: React.CSSProperties | undefined = swipe.isSwiping\n ? {\n // A swipe up doesn't go anywhere, so the image doesn't follow it.\n transform: `translate(${swipe.offsetX}px, ${Math.max(0, swipe.offsetY)}px)`,\n transition: 'none',\n }\n : undefined;\n\n return (\n <Modal\n ref={setRoot}\n isActive\n onClose={onClose}\n closeOnEscape={closeOnEscape}\n portal={portal}\n className={classNames(rootClass, className)}\n aria-label={ariaLabel}\n {...props}\n onKeyDown={handleKeyDown}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={event => {\n onPointerUp?.(event);\n handlePointerEnd(event);\n }}\n onPointerCancel={event => {\n onPointerCancel?.(event);\n handlePointerEnd(event);\n }}\n >\n <Modal.Background onClick={closeOnClickOutside ? onClose : undefined} />\n <Modal.Close variant=\"floating\" size=\"large\" aria-label={words.close} />\n <div className={toolbarClass}>\n {count > 1 && (\n <bdi className={progressClass} aria-hidden=\"true\">\n {`${number(index + 1)} / ${number(count)}`}\n </bdi>\n )}\n {zoomable && (\n <Buttons>\n <Button\n type=\"button\"\n aria-label={words.zoomOut}\n aria-disabled={!zoomed || undefined}\n onClick={zoomOut}\n >\n <ZoomOutIcon />\n </Button>\n <Button\n type=\"button\"\n aria-label={words.zoomIn}\n aria-disabled={!canZoom || view.zoom >= limit || undefined}\n onClick={zoomIn}\n >\n <ZoomInIcon />\n </Button>\n <Button\n type=\"button\"\n aria-label={words.resetZoom}\n aria-disabled={!zoomed || undefined}\n onClick={resetZoom}\n >\n <ResetZoomIcon />\n </Button>\n </Buttons>\n )}\n </div>\n <Modal.Content>\n <Figure\n className={figureClass}\n style={figureStyle}\n // A swipe starts on the image or a failed image's message, so\n // the caption keeps its text selection and Retry and links\n // their focus.\n {...swipe.handlers}\n onMouseDown={event => {\n if (startsSwipe(event.target)) swipe.handlers.onMouseDown(event);\n }}\n onTouchStart={event => {\n // A second finger is a pinch, not a swipe.\n if (event.touches.length > 1) swipe.cancel();\n else if (startsSwipe(event.target)) {\n swipe.handlers.onTouchStart(event);\n }\n }}\n >\n {status !== 'error' && (\n <img\n // The index as well as the file: a move between two items\n // with the same file still makes a new element, whose load\n // event clears the Loader.\n key={`${index}-${item.src}-${item.srcSet}-${attempt}`}\n ref={setImage}\n className={classNames(\n imageClass,\n hydrated && status !== 'loaded' && loadingClass\n )}\n src={item.src}\n srcSet={item.srcSet}\n sizes={item.sizes}\n alt={item.alt}\n draggable={false}\n style={imageStyle}\n onLoad={() => setStatus('loaded')}\n onError={fail}\n onDoubleClick={event => {\n // A touch screen's double tap is handled as it lands.\n if (canZoom && lastPointerTypeRef.current !== 'touch') {\n toggleZoomAt(event.clientX, event.clientY);\n }\n }}\n />\n )}\n {/* Over the new image, so it fades out as that one fades in. The\n stylesheet starts both once the new image has loaded. */}\n {leaving && (\n <img\n className={leavingClass}\n src={leaving.src}\n srcSet={leaving.srcSet}\n sizes={leaving.sizes}\n alt=\"\"\n aria-hidden=\"true\"\n draggable={false}\n onAnimationEnd={() => setLeaving(undefined)}\n />\n )}\n {status === 'slow' && <Loader ariaLabel={words.loading} />}\n {status === 'error' && (\n <div className={errorClass}>\n <p>{words.loadError}</p>\n {item.alt && <p>{item.alt}</p>}\n <Button type=\"button\" onClick={retry}>\n {words.retry}\n </Button>\n </div>\n )}\n {item.caption ? (\n <Figure.Caption className={captionClass}>\n {item.caption}\n </Figure.Caption>\n ) : null}\n </Figure>\n </Modal.Content>\n {count > 1 && (\n <>\n <Button\n type=\"button\"\n className={previousClass}\n aria-label={words.previous}\n aria-disabled={!canPrev || undefined}\n onClick={() => step(-1)}\n >\n <ChevronPrevIcon />\n </Button>\n <Button\n type=\"button\"\n className={nextClass}\n aria-label={words.next}\n aria-disabled={!canNext || undefined}\n onClick={() => step(1)}\n >\n <ChevronNextIcon />\n </Button>\n </>\n )}\n <div role=\"status\" aria-live=\"polite\" style={visuallyHidden}>\n {said}\n </div>\n </Modal>\n );\n }\n);\n\n/**\n * The `Lightbox` component shows a set of images one at a time in a modal viewer, with previous and next, a counter, captions and zoom, opened from the `Lightbox.Trigger` buttons you place.\n *\n * It renders its children where it stands, with no wrapper, and the\n * viewer only while it's open, into a portal by default. The viewer is a\n * `Modal`: focus moves to its close button, Tab stays inside, Escape and a\n * click on the background close it, and focus goes back to the trigger.\n *\n * @function\n * @param {LightboxProps} props - Props for the Lightbox component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the viewer's `.modal` element, `null` while it's closed.\n * @returns {JSX.Element} The children, and the viewer while it's open.\n *\n * @example\n * <Lightbox items={photos}>\n * {photos.map((photo, i) => (\n * <Lightbox.Trigger key={photo.src} index={i}>\n * <Image as=\"div\" src={photo.src} alt={photo.alt} size=\"4by3\" />\n * </Lightbox.Trigger>\n * ))}\n * </Lightbox>\n */\nconst LightboxRoot = forwardRef<HTMLDivElement, LightboxProps>(\n (\n {\n items,\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n value: controlledValue,\n defaultValue = 0,\n onChange,\n repeat = true,\n ...props\n },\n ref\n ) => {\n const [ownOpen, setOwnOpen] = useState(defaultOpen);\n const open = controlledOpen ?? ownOpen;\n const [ownValue, setOwnValue] = useState(defaultValue);\n const count = items.length;\n\n if (items.some(item => typeof item.alt !== 'string')) {\n warnOnce(\n 'Lightbox:no-alt',\n '[bestax-bulma] <Lightbox> has an item with no alt. In a viewer the ' +\n 'image is the content, so give each one a text alternative.'\n );\n }\n\n /** An index as one of the images: rounded, then held to the ends or wrapped. */\n const fit = (value: number) => {\n const whole = Number.isFinite(value) ? Math.trunc(value) : 0;\n return repeat\n ? ((whole % count) + count) % count\n : clamp(whole, 0, count - 1);\n };\n const index = fit(controlledValue ?? ownValue);\n\n const setOpen = (next: boolean) => {\n if (controlledOpen === undefined) setOwnOpen(next);\n onOpenChange?.(next);\n };\n const setValue = (next: number) => {\n if (controlledValue === undefined) setOwnValue(next);\n onChange?.(next);\n };\n\n // Read when a trigger is pressed, so the context stays the same object\n // and the triggers don't re-render with every change here.\n const openAt = useLatestRef((at: number) => {\n if (!count) return;\n setValue(fit(at));\n if (!open) setOpen(true);\n });\n\n // When the images run out while it's open, it closes the way a user's\n // close does, so an uncontrolled viewer doesn't open again by itself when\n // they return. Only on the drop to none, so a viewer that opens before its\n // images arrive (a deep link, or `defaultOpen` over data still loading)\n // stays open for them.\n const closeEmpty = useLatestRef(() => setOpen(false));\n const countRef = useRef(count);\n useEffect(() => {\n const had = countRef.current;\n countRef.current = count;\n if (open && had > 0 && count === 0) closeEmpty.current();\n }, [open, count, closeEmpty]);\n const context = useMemo<LightboxContextValue>(\n () => ({ openAt: at => openAt.current(at) }),\n [openAt]\n );\n\n return (\n <LightboxContext.Provider value={context}>\n {children}\n {open && count > 0 && (\n <LightboxViewer\n {...props}\n ref={ref}\n items={items}\n repeat={repeat}\n index={index}\n onIndexChange={setValue}\n onClose={() => setOpen(false)}\n />\n )}\n </LightboxContext.Provider>\n );\n }\n);\n\nLightboxRoot.displayName = 'Lightbox';\n\nexport const Lightbox = withSubComponents(\n LightboxRoot,\n { Trigger: LightboxTrigger },\n 'Lightbox'\n);\n\nexport default Lightbox;\n"],"names":["clamp","_jsxs","_jsx","_Fragment"],"mappings":"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"}
|
|
@@ -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 /**\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 Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'aria-expanded'>,\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`, and `null` leaves it off, for a burger whose\n * state isn't known yet; a spread carrying `'aria-expanded': undefined`\n * still follows `active`.\n * @defaultValue active\n */\n 'aria-expanded'?: boolean | null;\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={\n rest['aria-expanded'] === null\n ? undefined\n : (rest['aria-expanded'] ?? !!active)\n }\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 * Accessible name. Defaults to `main navigation`. A screen reader announces\n * it with the landmark's role, and since the name holds the role word,\n * \"navigation\" is heard twice. Pass a name without it (`aria-label=\"Site\"`),\n * and a different name on each Navbar when a page has more than one. A\n * passed `aria-label` replaces the default, and `aria-label={undefined}`\n * removes it, leaving the landmark unnamed.\n * @defaultValue 'main navigation'\n */\n 'aria-label'?: React.AriaAttributes['aria-label'];\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 Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'aria-expanded'>,\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`, and `null` leaves it off, for a burger whose\n * state isn't known yet; a spread carrying `'aria-expanded': undefined`\n * still follows `active`.\n * @defaultValue active\n */\n 'aria-expanded'?: boolean | null;\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={\n rest['aria-expanded'] === null\n ? undefined\n : (rest['aria-expanded'] ?? !!active)\n }\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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"}
|
|
@@ -5,31 +5,8 @@ import React, { useState, useEffect, Children, isValidElement, cloneElement } fr
|
|
|
5
5
|
import { prefixedClassNames, classNames, usePrefixedClassNames } from '../helpers/classNames.js';
|
|
6
6
|
import { useClassPrefix } from '../helpers/Config.js';
|
|
7
7
|
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
8
|
+
import { usePrefersReducedMotion } from '../helpers/usePrefersReducedMotion.js';
|
|
8
9
|
|
|
9
|
-
/**
|
|
10
|
-
* Detects the user's `prefers-reduced-motion` preference. Always `false` on
|
|
11
|
-
* the server and on the very first client render, so SSR output and the
|
|
12
|
-
* initial hydration pass always agree.
|
|
13
|
-
*
|
|
14
|
-
* @function
|
|
15
|
-
* @returns {boolean} Whether the user has requested reduced motion.
|
|
16
|
-
*/
|
|
17
|
-
function usePrefersReducedMotion() {
|
|
18
|
-
const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
if (typeof window === 'undefined' || !window.matchMedia)
|
|
21
|
-
return undefined;
|
|
22
|
-
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
23
|
-
// eslint-disable-next-line react-hooks/set-state-in-effect -- reads the live media query on mount
|
|
24
|
-
setPrefersReducedMotion(mediaQuery.matches);
|
|
25
|
-
const handleChange = (event) => {
|
|
26
|
-
setPrefersReducedMotion(event.matches);
|
|
27
|
-
};
|
|
28
|
-
mediaQuery.addEventListener('change', handleChange);
|
|
29
|
-
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
30
|
-
}, []);
|
|
31
|
-
return prefersReducedMotion;
|
|
32
|
-
}
|
|
33
10
|
/**
|
|
34
11
|
* The `Reveal` component animates its content into view as it scrolls into the viewport, backed by `IntersectionObserver`.
|
|
35
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Reveal.js","sources":["../../../src/components/Reveal.tsx"],"sourcesContent":["import React, {\n Children,\n cloneElement,\n isValidElement,\n useEffect,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport type { PolymorphicComponentWithoutRef } from '../helpers/polymorphic';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\n\n/**\n * Animation styles available for the Reveal component.\n */\nexport type RevealAnimation =\n | 'fade'\n | 'fade-up'\n | 'fade-down'\n | 'slide-left'\n | 'slide-right'\n | 'zoom'\n | 'flip';\n\n/**\n * The Reveal component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface RevealOwnProps extends BulmaClassesProps {\n /** Animation style applied when the element enters the viewport. */\n animation?: RevealAnimation;\n /** Delay in milliseconds before the animation starts. Default: 0. */\n delay?: number;\n /** Animation duration in milliseconds. Default: 600. */\n duration?: number;\n /** Fraction (0-1) of the element that must be visible to trigger the reveal. Clamped to the 0-1 range; non-finite values fall back to `0.15`. */\n threshold?: number;\n /** Animate only the first time the element enters the viewport. If `false`, it re-animates on every entry/exit. */\n once?: boolean;\n /** Stagger direct children with an incrementing delay instead of animating this element as a single block. */\n cascade?: boolean;\n /** Milliseconds added to each successive child's delay when `cascade` is set. Default: 80. */\n cascadeInterval?: number;\n /** Content to reveal. */\n children?: React.ReactNode;\n /** Additional CSS classes. Applied to the observed element (the wrapper `div` when `as` is a component). */\n className?: string;\n /** Inline styles, merged after the animation's own. Applied to the observed element. */\n style?: React.CSSProperties;\n}\n\n/**\n * Props for the Reveal component. The DOM attributes follow `as`.\n *\n * Reveal forwards no `ref`: it owns the node it observes for scroll\n * intersection, and when `as` is a component that node is a wrapper `div`\n * rather than the element `as` names — so a ref derived from `as` would point\n * at the wrong thing.\n */\nexport type RevealProps<T extends React.ElementType = 'div'> = RevealOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof RevealOwnProps | 'as'> & {\n /** Element or component to render as. Default: 'div'. When `as` is a plain intrinsic tag (e.g. `'section'`), your `className`, `style`, and Bulma helper classes plus everything in `...rest` all land on that single element. When `as` is a component (e.g. `Section`, `Card`), scroll detection needs a real DOM node with a ref, so `Reveal` wraps it in an observed `div`: `className`/`style`/helper classes go on that wrapper `div`, while `...rest` (`id`, `aria-*`, `data-*`, event handlers) is forwarded to the inner component. */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `RevealProps<T>` above — the body cannot see through `T`.\n */\ntype RevealImplProps = RevealOwnProps & { as?: React.ElementType };\n\n/**\n * Detects the user's `prefers-reduced-motion` preference. Always `false` on\n * the server and on the very first client render, so SSR output and the\n * initial hydration pass always agree.\n *\n * @function\n * @returns {boolean} Whether the user has requested reduced motion.\n */\nfunction usePrefersReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return undefined;\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n // eslint-disable-next-line react-hooks/set-state-in-effect -- reads the live media query on mount\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setPrefersReducedMotion(event.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n\n/**\n * The `Reveal` component animates its content into view as it scrolls into the viewport, backed by `IntersectionObserver`.\n *\n * @function\n * @param {RevealProps} props - Props for the Reveal component.\n * @returns {JSX.Element} The rendered reveal wrapper.\n *\n * @example\n * // Fade a section up into view\n * <Reveal animation=\"fade-up\" as={Section}>\n * <Title>Why Grass Doctor</Title>\n * </Reveal>\n *\n * @example\n * // Stagger a set of cards as they enter the viewport\n * <Reveal animation=\"fade-up\" cascade cascadeInterval={80}>\n * {services.map(service => (\n * <Card key={service.name}>{service.name}</Card>\n * ))}\n * </Reveal>\n */\nfunction RevealImpl(revealProps: RevealProps) {\n const {\n animation = 'fade-up',\n delay = 0,\n duration = 600,\n threshold = 0.15,\n once = true,\n as: Component = 'div',\n cascade = false,\n cascadeInterval = 80,\n className,\n style,\n children,\n ...props\n } = revealProps as RevealImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n const prefersReducedMotion = usePrefersReducedMotion();\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [isMounted, setIsMounted] = useState(false);\n const [isRevealed, setIsRevealed] = useState(false);\n\n // IntersectionObserver throws a RangeError for NaN or thresholds outside\n // 0-1, so clamp valid numbers and fall back to the default for anything else.\n const observerThreshold = Number.isFinite(threshold)\n ? Math.min(Math.max(threshold, 0), 1)\n : 0.15;\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- flips to true once mounted on the client so SSR/first-paint markup matches the server\n setIsMounted(true);\n }, []);\n\n useEffect(() => {\n if (prefersReducedMotion) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- reduced motion skips straight to the revealed state\n setIsRevealed(true);\n return undefined;\n }\n\n if (typeof IntersectionObserver === 'undefined') {\n setIsRevealed(true);\n return undefined;\n }\n\n // The ref callback attaches after this effect's first pass; it re-runs\n // once `node` becomes available since it's a dependency.\n if (!node) return undefined;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsRevealed(true);\n if (once) observer.unobserve(node);\n } else if (!once) {\n setIsRevealed(false);\n }\n },\n { threshold: observerThreshold }\n );\n\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, prefersReducedMotion, once, observerThreshold]);\n\n // Only apply the hidden/animating state once mounted on the client with\n // motion allowed; otherwise render the final, visible state (SSR-safe).\n const isAnimated = isMounted && !prefersReducedMotion;\n const revealed = !isAnimated || isRevealed;\n\n const itemAnimationClasses = prefixedClassNames(classPrefix, {\n [`reveal-${animation}`]: isAnimated,\n 'is-revealed': revealed,\n });\n\n const combinedClasses = classNames(\n usePrefixedClassNames('reveal', { 'is-cascade': cascade }),\n !cascade && itemAnimationClasses,\n bulmaHelperClasses,\n className\n );\n\n const wrapperStyle: React.CSSProperties = cascade\n ? { ...style }\n : {\n ...style,\n transitionDelay: `${delay}ms`,\n transitionDuration: `${duration}ms`,\n };\n\n const content = cascade\n ? Children.toArray(children).map((child, index) => {\n const itemStyle: React.CSSProperties = {\n transitionDelay: `${delay + index * cascadeInterval}ms`,\n transitionDuration: `${duration}ms`,\n };\n\n if (\n isValidElement<{ className?: string; style?: React.CSSProperties }>(\n child\n )\n ) {\n return cloneElement(child, {\n // Children.toArray always assigns a key, generating one from\n // the position when the element doesn't already have one.\n key: child.key,\n className: classNames(itemAnimationClasses, child.props.className),\n style: { ...itemStyle, ...child.props.style },\n });\n }\n\n return (\n <span key={index} className={itemAnimationClasses} style={itemStyle}>\n {child}\n </span>\n );\n })\n : children;\n\n // Scroll observation needs a DOM node this component OWNS — the observer and\n // the animation classes both key off it. An intrinsic tag is that node, so\n // the ref goes straight on it. A component passed via `as` is not: whatever\n // it renders is its own business, and it may render several elements or\n // none. So it gets wrapped in an observed `div`.\n //\n // Not a statement about ref forwarding. Several components in this library\n // forward refs (#641 added four more), and that changes nothing here — a\n // forwarded ref would still point at the target's node rather than at one\n // this component controls.\n if (typeof Component === 'string') {\n // A plain createElement call sidesteps the combinatorial JSX prop types\n // for `ref` across every possible intrinsic tag `as` could be.\n return React.createElement(\n Component,\n {\n ...rest,\n ref: setNode,\n className: combinedClasses,\n style: wrapperStyle,\n },\n content\n );\n }\n\n return (\n <div ref={setNode} className={combinedClasses} style={wrapperStyle}>\n <Component {...rest}>{content}</Component>\n </div>\n );\n}\n\nexport const Reveal = RevealImpl as PolymorphicComponentWithoutRef<\n RevealOwnProps,\n 'div'\n>;\n\nReveal.displayName = 'Reveal';\n\nexport default Reveal;\n"],"names":["_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Reveal.js","sources":["../../../src/components/Reveal.tsx"],"sourcesContent":["import React, {\n Children,\n cloneElement,\n isValidElement,\n useEffect,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport type { PolymorphicComponentWithoutRef } from '../helpers/polymorphic';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { usePrefersReducedMotion } from '../helpers/usePrefersReducedMotion';\n\n/**\n * Animation styles available for the Reveal component.\n */\nexport type RevealAnimation =\n | 'fade'\n | 'fade-up'\n | 'fade-down'\n | 'slide-left'\n | 'slide-right'\n | 'zoom'\n | 'flip';\n\n/**\n * The Reveal component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface RevealOwnProps extends BulmaClassesProps {\n /** Animation style applied when the element enters the viewport. */\n animation?: RevealAnimation;\n /** Delay in milliseconds before the animation starts. Default: 0. */\n delay?: number;\n /** Animation duration in milliseconds. Default: 600. */\n duration?: number;\n /** Fraction (0-1) of the element that must be visible to trigger the reveal. Clamped to the 0-1 range; non-finite values fall back to `0.15`. */\n threshold?: number;\n /** Animate only the first time the element enters the viewport. If `false`, it re-animates on every entry/exit. */\n once?: boolean;\n /** Stagger direct children with an incrementing delay instead of animating this element as a single block. */\n cascade?: boolean;\n /** Milliseconds added to each successive child's delay when `cascade` is set. Default: 80. */\n cascadeInterval?: number;\n /** Content to reveal. */\n children?: React.ReactNode;\n /** Additional CSS classes. Applied to the observed element (the wrapper `div` when `as` is a component). */\n className?: string;\n /** Inline styles, merged after the animation's own. Applied to the observed element. */\n style?: React.CSSProperties;\n}\n\n/**\n * Props for the Reveal component. The DOM attributes follow `as`.\n *\n * Reveal forwards no `ref`: it owns the node it observes for scroll\n * intersection, and when `as` is a component that node is a wrapper `div`\n * rather than the element `as` names — so a ref derived from `as` would point\n * at the wrong thing.\n */\nexport type RevealProps<T extends React.ElementType = 'div'> = RevealOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof RevealOwnProps | 'as'> & {\n /** Element or component to render as. Default: 'div'. When `as` is a plain intrinsic tag (e.g. `'section'`), your `className`, `style`, and Bulma helper classes plus everything in `...rest` all land on that single element. When `as` is a component (e.g. `Section`, `Card`), scroll detection needs a real DOM node with a ref, so `Reveal` wraps it in an observed `div`: `className`/`style`/helper classes go on that wrapper `div`, while `...rest` (`id`, `aria-*`, `data-*`, event handlers) is forwarded to the inner component. */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `RevealProps<T>` above — the body cannot see through `T`.\n */\ntype RevealImplProps = RevealOwnProps & { as?: React.ElementType };\n\n/**\n * The `Reveal` component animates its content into view as it scrolls into the viewport, backed by `IntersectionObserver`.\n *\n * @function\n * @param {RevealProps} props - Props for the Reveal component.\n * @returns {JSX.Element} The rendered reveal wrapper.\n *\n * @example\n * // Fade a section up into view\n * <Reveal animation=\"fade-up\" as={Section}>\n * <Title>Why Grass Doctor</Title>\n * </Reveal>\n *\n * @example\n * // Stagger a set of cards as they enter the viewport\n * <Reveal animation=\"fade-up\" cascade cascadeInterval={80}>\n * {services.map(service => (\n * <Card key={service.name}>{service.name}</Card>\n * ))}\n * </Reveal>\n */\nfunction RevealImpl(revealProps: RevealProps) {\n const {\n animation = 'fade-up',\n delay = 0,\n duration = 600,\n threshold = 0.15,\n once = true,\n as: Component = 'div',\n cascade = false,\n cascadeInterval = 80,\n className,\n style,\n children,\n ...props\n } = revealProps as RevealImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n const prefersReducedMotion = usePrefersReducedMotion();\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [isMounted, setIsMounted] = useState(false);\n const [isRevealed, setIsRevealed] = useState(false);\n\n // IntersectionObserver throws a RangeError for NaN or thresholds outside\n // 0-1, so clamp valid numbers and fall back to the default for anything else.\n const observerThreshold = Number.isFinite(threshold)\n ? Math.min(Math.max(threshold, 0), 1)\n : 0.15;\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- flips to true once mounted on the client so SSR/first-paint markup matches the server\n setIsMounted(true);\n }, []);\n\n useEffect(() => {\n if (prefersReducedMotion) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- reduced motion skips straight to the revealed state\n setIsRevealed(true);\n return undefined;\n }\n\n if (typeof IntersectionObserver === 'undefined') {\n setIsRevealed(true);\n return undefined;\n }\n\n // The ref callback attaches after this effect's first pass; it re-runs\n // once `node` becomes available since it's a dependency.\n if (!node) return undefined;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsRevealed(true);\n if (once) observer.unobserve(node);\n } else if (!once) {\n setIsRevealed(false);\n }\n },\n { threshold: observerThreshold }\n );\n\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, prefersReducedMotion, once, observerThreshold]);\n\n // Only apply the hidden/animating state once mounted on the client with\n // motion allowed; otherwise render the final, visible state (SSR-safe).\n const isAnimated = isMounted && !prefersReducedMotion;\n const revealed = !isAnimated || isRevealed;\n\n const itemAnimationClasses = prefixedClassNames(classPrefix, {\n [`reveal-${animation}`]: isAnimated,\n 'is-revealed': revealed,\n });\n\n const combinedClasses = classNames(\n usePrefixedClassNames('reveal', { 'is-cascade': cascade }),\n !cascade && itemAnimationClasses,\n bulmaHelperClasses,\n className\n );\n\n const wrapperStyle: React.CSSProperties = cascade\n ? { ...style }\n : {\n ...style,\n transitionDelay: `${delay}ms`,\n transitionDuration: `${duration}ms`,\n };\n\n const content = cascade\n ? Children.toArray(children).map((child, index) => {\n const itemStyle: React.CSSProperties = {\n transitionDelay: `${delay + index * cascadeInterval}ms`,\n transitionDuration: `${duration}ms`,\n };\n\n if (\n isValidElement<{ className?: string; style?: React.CSSProperties }>(\n child\n )\n ) {\n return cloneElement(child, {\n // Children.toArray always assigns a key, generating one from\n // the position when the element doesn't already have one.\n key: child.key,\n className: classNames(itemAnimationClasses, child.props.className),\n style: { ...itemStyle, ...child.props.style },\n });\n }\n\n return (\n <span key={index} className={itemAnimationClasses} style={itemStyle}>\n {child}\n </span>\n );\n })\n : children;\n\n // Scroll observation needs a DOM node this component OWNS — the observer and\n // the animation classes both key off it. An intrinsic tag is that node, so\n // the ref goes straight on it. A component passed via `as` is not: whatever\n // it renders is its own business, and it may render several elements or\n // none. So it gets wrapped in an observed `div`.\n //\n // Not a statement about ref forwarding. Several components in this library\n // forward refs (#641 added four more), and that changes nothing here — a\n // forwarded ref would still point at the target's node rather than at one\n // this component controls.\n if (typeof Component === 'string') {\n // A plain createElement call sidesteps the combinatorial JSX prop types\n // for `ref` across every possible intrinsic tag `as` could be.\n return React.createElement(\n Component,\n {\n ...rest,\n ref: setNode,\n className: combinedClasses,\n style: wrapperStyle,\n },\n content\n );\n }\n\n return (\n <div ref={setNode} className={combinedClasses} style={wrapperStyle}>\n <Component {...rest}>{content}</Component>\n </div>\n );\n}\n\nexport const Reveal = RevealImpl as PolymorphicComponentWithoutRef<\n RevealOwnProps,\n 'div'\n>;\n\nReveal.displayName = 'Reveal';\n\nexport default Reveal;\n"],"names":["_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// INTERNAL: deliberately not exported from src/index.ts. The chevrons the
|
|
6
|
+
// Carousel's and the Lightbox's previous and next buttons draw, in one place
|
|
7
|
+
// so the two look the same.
|
|
8
|
+
/**
|
|
9
|
+
* Chevron pointing left, for a previous button.
|
|
10
|
+
*
|
|
11
|
+
* @function
|
|
12
|
+
* @returns {JSX.Element} The rendered SVG chevron-left icon.
|
|
13
|
+
*/
|
|
14
|
+
const ChevronPrevIcon = () => (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("polyline", { points: "15 18 9 12 15 6" }) }));
|
|
15
|
+
/**
|
|
16
|
+
* Chevron pointing right, for a next button.
|
|
17
|
+
*
|
|
18
|
+
* @function
|
|
19
|
+
* @returns {JSX.Element} The rendered SVG chevron-right icon.
|
|
20
|
+
*/
|
|
21
|
+
const ChevronNextIcon = () => (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("polyline", { points: "9 18 15 12 9 6" }) }));
|
|
22
|
+
|
|
23
|
+
export { ChevronNextIcon, ChevronPrevIcon };
|
|
24
|
+
//# sourceMappingURL=chevronIcons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chevronIcons.js","sources":["../../../src/helpers/chevronIcons.tsx"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts. The chevrons the\n// Carousel's and the Lightbox's previous and next buttons draw, in one place\n// so the two look the same.\n\n/**\n * Chevron pointing left, for a previous button.\n *\n * @function\n * @returns {JSX.Element} The rendered SVG chevron-left icon.\n */\nexport const ChevronPrevIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n);\n\n/**\n * Chevron pointing right, for a next button.\n *\n * @function\n * @returns {JSX.Element} The rendered SVG chevron-right icon.\n */\nexport const ChevronNextIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n"],"names":["_jsx"],"mappings":";;;;AAAA;AACA;AACA;AAEA;;;;;AAKG;AACI,MAAM,eAAe,GAAG,OAC7BA,GAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EAAA,QAAA,EAEfA,GAAA,CAAA,UAAA,EAAA,EAAU,MAAM,EAAC,iBAAiB,EAAA,CAAG,EAAA,CACjC;AAGR;;;;;AAKG;AACI,MAAM,eAAe,GAAG,OAC7BA,GAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EAAA,QAAA,EAEfA,GAAA,CAAA,UAAA,EAAA,EAAU,MAAM,EAAC,gBAAgB,EAAA,CAAG,EAAA,CAChC;;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
// INTERNAL: deliberately not exported from src/index.ts.
|
|
6
|
+
/**
|
|
7
|
+
* Detects the user's `prefers-reduced-motion` preference, for motion that
|
|
8
|
+
* runs in script, where a stylesheet's media query can't reach it. Always
|
|
9
|
+
* `false` on the server and on the very first client render, so SSR output
|
|
10
|
+
* and the initial hydration pass always agree.
|
|
11
|
+
*
|
|
12
|
+
* @function
|
|
13
|
+
* @returns {boolean} Whether the user has requested reduced motion.
|
|
14
|
+
*/
|
|
15
|
+
function usePrefersReducedMotion() {
|
|
16
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
|
|
17
|
+
// An effect, so it only ever runs in the browser.
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!window.matchMedia)
|
|
20
|
+
return undefined;
|
|
21
|
+
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
22
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect -- reads the live media query on mount
|
|
23
|
+
setPrefersReducedMotion(mediaQuery.matches);
|
|
24
|
+
const handleChange = (event) => {
|
|
25
|
+
setPrefersReducedMotion(event.matches);
|
|
26
|
+
};
|
|
27
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
28
|
+
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
29
|
+
}, []);
|
|
30
|
+
return prefersReducedMotion;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { usePrefersReducedMotion };
|
|
34
|
+
//# sourceMappingURL=usePrefersReducedMotion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePrefersReducedMotion.js","sources":["../../../src/helpers/usePrefersReducedMotion.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport { useEffect, useState } from 'react';\n\n/**\n * Detects the user's `prefers-reduced-motion` preference, for motion that\n * runs in script, where a stylesheet's media query can't reach it. Always\n * `false` on the server and on the very first client render, so SSR output\n * and the initial hydration pass always agree.\n *\n * @function\n * @returns {boolean} Whether the user has requested reduced motion.\n */\nexport function usePrefersReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n // An effect, so it only ever runs in the browser.\n useEffect(() => {\n if (!window.matchMedia) return undefined;\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n // eslint-disable-next-line react-hooks/set-state-in-effect -- reads the live media query on mount\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setPrefersReducedMotion(event.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n"],"names":[],"mappings":";;;;AAAA;AAGA;;;;;;;;AAQG;SACa,uBAAuB,GAAA;IACrC,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;;IAGvE,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,MAAM,CAAC,UAAU;AAAE,YAAA,OAAO,SAAS;QAExC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC;;AAExE,QAAA,uBAAuB,CAAC,UAAU,CAAC,OAAO,CAAC;AAE3C,QAAA,MAAM,YAAY,GAAG,CAAC,KAA0B,KAAI;AAClD,YAAA,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC;AACxC,QAAA,CAAC;AAED,QAAA,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC;QACnD,OAAO,MAAM,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC;IACrE,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,OAAO,oBAAoB;AAC7B;;"}
|