@allxsmith/bestax-bulma 5.67.8 → 5.67.10
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/README.md +3 -3
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/ContextMenu.js +2 -2
- package/dist/esm/components/ContextMenu.js.map +1 -1
- package/dist/esm/components/DataTable.js +2 -1
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/HoverCard.js.map +1 -1
- package/dist/esm/components/Panel.js.map +1 -1
- package/dist/esm/components/Popover.js.map +1 -1
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/form/ColorInputBase.js.map +1 -1
- package/dist/esm/form/Combobox.js.map +1 -1
- package/dist/esm/form/DateInputBase.js.map +1 -1
- package/dist/esm/form/DateRangeInputBase.js.map +1 -1
- package/dist/esm/form/DateTimeInputBase.js.map +1 -1
- package/dist/esm/form/TimeInputBase.js.map +1 -1
- package/dist/esm/form/TreeSelect.js.map +1 -1
- package/dist/esm/helpers/Config.js.map +1 -1
- package/dist/esm/helpers/portal.js +8 -3
- package/dist/esm/helpers/portal.js.map +1 -1
- package/dist/esm/layout/AppFrame.js +9 -3
- package/dist/esm/layout/AppFrame.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +19 -8
- package/dist/index.cjs.map +1 -1
- package/dist/types/components/DataTable.d.ts +2 -1
- package/dist/types/components/HoverCard.d.ts +11 -11
- package/dist/types/components/Panel.d.ts +6 -1
- package/dist/types/components/Popover.d.ts +6 -6
- package/dist/types/components/Sidebar.d.ts +10 -1
- package/dist/types/form/ColorInputBase.d.ts +2 -2
- package/dist/types/form/Combobox.d.ts +6 -6
- package/dist/types/form/DateInputBase.d.ts +2 -2
- package/dist/types/form/DateRangeInputBase.d.ts +2 -2
- package/dist/types/form/DateTimeInputBase.d.ts +2 -2
- package/dist/types/form/TimeInputBase.d.ts +2 -2
- package/dist/types/form/TreeSelect.d.ts +1 -1
- package/dist/types/helpers/Config.d.ts +9 -5
- package/dist/types/helpers/portal.d.ts +7 -3
- package/dist/types/layout/AppFrame.d.ts +5 -1
- package/dist/types-cjs/components/DataTable.d.ts +2 -1
- package/dist/types-cjs/components/HoverCard.d.ts +11 -11
- package/dist/types-cjs/components/Panel.d.ts +6 -1
- package/dist/types-cjs/components/Popover.d.ts +6 -6
- package/dist/types-cjs/components/Sidebar.d.ts +10 -1
- package/dist/types-cjs/form/ColorInputBase.d.ts +2 -2
- package/dist/types-cjs/form/Combobox.d.ts +6 -6
- package/dist/types-cjs/form/DateInputBase.d.ts +2 -2
- package/dist/types-cjs/form/DateRangeInputBase.d.ts +2 -2
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +2 -2
- package/dist/types-cjs/form/TimeInputBase.d.ts +2 -2
- package/dist/types-cjs/form/TreeSelect.d.ts +1 -1
- package/dist/types-cjs/helpers/Config.d.ts +9 -5
- package/dist/types-cjs/helpers/portal.d.ts +7 -3
- package/dist/types-cjs/layout/AppFrame.d.ts +5 -1
- 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 +2 -2
- package/src/scss/components/_datatable.scss +14 -2
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/components/_panel.scss +31 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.js","sources":["../../../src/components/Popover.tsx"],"sourcesContent":["import React, {\n cloneElement,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\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 { PopupPortal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { focusTabStop, useFocusTrap } from '../helpers/useFocusTrap';\nimport { marginGap, useAnchoredPosition } from '../helpers/useAnchoredPosition';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { getDeepestActiveElement } from '../helpers/shadowDom';\nimport { useOutsidePress } from '../helpers/useOutsidePress';\nimport { buttonType } from '../helpers/buttonType';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { Button, ButtonOwnProps } from '../elements/Button';\nimport type { PickerPosition } from '../form/_pickerInternals/pickerTypes';\n\n/**\n * Where the panel opens against its trigger: below (`bottom-*`) or above\n * (`top-*`), lined up with the trigger's left or right edge. `auto` picks the\n * one that keeps the panel in the viewport, preferring below and lined up on\n * the left. The same union the date and time pickers take.\n */\nexport type PopoverPosition = PickerPosition;\n\n/**\n * Props for the Popover component. `className`, `id`, the other HTML\n * attributes and the helper props land on the wrapper around the trigger,\n * not on the panel; `contentClassName` reaches the panel.\n * @extraProp {string} [className] - Additional classes for the wrapper around the trigger. The panel takes `contentClassName`.\n */\nexport interface PopoverProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'children'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The element that opens and closes the popover, such as a `Button`.\n * Popover gives it `aria-haspopup=\"dialog\"`, `aria-expanded`,\n * `aria-controls` while the panel is open, and click and key handlers that\n * run after its own (call `preventDefault()` in yours to keep the popover\n * from toggling). It has to be a single element that passes `onClick` and\n * `onKeyDown` to its DOM node. Enter and Space toggle a trigger the browser\n * doesn't click on its own, and an intrinsic element that isn't already a\n * control (a `<span>`) also gets `role=\"button\"` and `tabIndex={0}` unless\n * it sets them; a component that renders one has to take those itself.\n */\n trigger: React.ReactElement;\n /** The panel's content, usually `Popover.Header`, `Popover.Body` and `Popover.Footer`. */\n children?: React.ReactNode;\n /**\n * Controlled open state. When set, the trigger and every dismissal only\n * report through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled. Opening moves focus into the\n * panel, so a popover that starts open takes focus once the page loads.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the state asked for: `true` from the trigger opening it,\n * `false` from the trigger, `Popover.Close`, Escape or an outside\n * `pointerdown`. Fires in both controlled and uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Where the panel opens against the trigger. Left out, it opens below and\n * lines up with the trigger's start edge, which is its right edge on a\n * right-to-left page, so a trigger at the start of the line doesn't push\n * the panel off the screen. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges on either page.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Render the panel through `Portal`, into the `portalContainer` a\n * `ConfigProvider` sets, else the `Modal`, `Dialog` or `Command.Dialog`\n * it's in, else `document.body`, fixed to the viewport, so an ancestor's\n * `overflow`, `transform` or stacking context can't clip it. The panel\n * then shows from the commit after hydration, never in server markup.\n * Theming variables set on an ancestor of the trigger reach it only when\n * its container is inside that ancestor.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /**\n * Keep Tab and Shift+Tab inside the panel while it is open, as the ARIA\n * dialog pattern does for a non-modal dialog. Pointer focus leaves freely\n * and the page stays usable. With `false`, Tab moves past the panel and\n * the popover stays open. Focus moves into the panel on open and back to\n * the trigger on close either way.\n * @defaultValue true\n */\n trapFocus?: boolean;\n /**\n * Close on a `pointerdown` outside the trigger and the panel. Content the\n * panel renders through a portal (a nested `Popover`, a portaled picker)\n * still counts as inside.\n * @defaultValue true\n */\n closeOnClickOutside?: boolean;\n /**\n * Close on Escape while focus is in the panel or on the trigger. A dialog\n * nested in the panel, such as a date picker's calendar, takes its own\n * Escape first, and so does content that calls `preventDefault()` on it.\n * @defaultValue true\n */\n closeOnEscape?: boolean;\n /**\n * The panel's accessible name. Without it the panel is named by its\n * `Popover.Header`, and a development build warns when it has neither.\n */\n ariaLabel?: string;\n /** Additional classes for the panel (`.popover-content`). */\n contentClassName?: string;\n}\n\ninterface PopoverContextValue {\n /** The id `Popover.Header` takes, which names the panel. */\n titleId: string;\n /** Records a mounted `Popover.Header`; the returned function forgets it. */\n registerTitle: () => () => void;\n /** Asks the popover to close. */\n close: () => void;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\n/** The trigger props Popover reads before replacing them. */\ninterface TriggerProps {\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLElement>) => void;\n role?: string;\n tabIndex?: number;\n href?: unknown;\n}\n\n/** Intrinsic elements that are controls already, and keep their own role. */\nconst NATIVE_CONTROLS = new Set([\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'summary',\n]);\n\n/**\n * Whether the browser answers this key on `el` itself, by clicking it or by\n * using the key as input, so the trigger's click handler covers it.\n */\nfunction handlesKeyItself(el: Element, key: string): boolean {\n if (NATIVE_CONTROLS.has(el.localName)) return true;\n return el.localName === 'a' && key === 'Enter' && el.hasAttribute('href');\n}\n\n/** The innermost dialog the event passed through, which is the one its Escape belongs to. */\nfunction nearestDialog(event: Event): EventTarget | null {\n return (\n event.composedPath().find(node => {\n const role = (node as Element).getAttribute?.('role');\n return role === 'dialog' || role === 'alertdialog';\n }) ?? null\n );\n}\n\n/**\n * The `Popover` component opens a panel of interactive content, such as a filter form or a set of share options, anchored to the element that toggles it.\n *\n * The panel is a non-modal `role=\"dialog\"`: focus moves into it on open\n * and returns to the trigger on close, while the rest of the page stays\n * reachable by pointer and assistive technology. For hover-only hints use\n * `Tooltip`, and for a list of actions use `Dropdown`.\n *\n * @function\n * @param {PopoverProps} props - Props for the Popover component.\n * @returns {JSX.Element} The trigger in its wrapper, and the panel while open.\n *\n * @example\n * <Popover trigger={<Button>Filters</Button>}>\n * <Popover.Header>Filter rows</Popover.Header>\n * <Popover.Body>…</Popover.Body>\n * <Popover.Footer>\n * <Popover.Close>Done</Popover.Close>\n * </Popover.Footer>\n * </Popover>\n */\nconst PopoverComponent: React.FC<PopoverProps> = ({\n trigger,\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n position,\n appendToBody = false,\n trapFocus = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n contentClassName,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const baseId = useId();\n const panelId = `${baseId}-panel`;\n const titleId = `${baseId}-title`;\n\n const isControlled = controlledOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const isOpen = controlledOpen ?? internalOpen;\n\n const requestOpen = useCallback(\n (next: boolean) => {\n onOpenChange?.(next);\n if (!isControlled) setInternalOpen(next);\n },\n [isControlled, onOpenChange]\n );\n const close = useCallback(() => requestOpen(false), [requestOpen]);\n\n // A portaled panel has no server markup, so it only exists from the commit\n // after hydration. Everything that measures or focuses it waits for that.\n const hydrated = useIsHydrated();\n const panelMounted = isOpen && (hydrated || !appendToBody);\n\n const resolved = useAnchoredPosition(rootRef, panelRef, {\n active: panelMounted,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-popover-offset` in the stylesheet, so the\n // coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n });\n\n // The trigger renders first inside the wrapper. Read when needed rather\n // than held, so a trigger that remounted is still the one found.\n const triggerNode = useCallback((): HTMLElement | null => {\n const first = rootRef.current?.firstElementChild;\n return first && first !== panelRef.current ? (first as HTMLElement) : null;\n }, []);\n const restoreFocusRef = useMemo(\n () => ({\n get current() {\n return triggerNode();\n },\n }),\n [triggerNode]\n );\n\n useFocusTrap(panelRef, {\n active: panelMounted && trapFocus,\n restoreFocus: restoreFocusRef,\n });\n\n // Without the trap, focus still arrives in the panel and goes back to the\n // trigger, on the trap's terms: only while the panel still holds it.\n useEffect(() => {\n const panel = panelRef.current;\n if (!panelMounted || trapFocus || !panel) return undefined;\n focusTabStop(panel);\n return () => {\n const doc = panel.ownerDocument;\n const now = getDeepestActiveElement(doc);\n if (!now || now === doc.body || panel.contains(now)) {\n triggerNode()?.focus();\n }\n };\n }, [panelMounted, trapFocus, triggerNode]);\n\n // A press outside the wrapper, which holds the trigger and the panel,\n // closes it. One inside the panel's React tree counts as inside, so content\n // the panel portals elsewhere does too.\n const markInsidePress = useOutsidePress(\n rootRef,\n panelMounted && closeOnClickOutside,\n close\n );\n\n const handlePanelKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== 'Escape' || !closeOnEscape || e.defaultPrevented) return;\n // React bubbles the key here from portaled content as well, so a dialog\n // of its own on the way (a nested popover, a picker's calendar) owns it.\n const owner = nearestDialog(e.nativeEvent);\n if (owner && owner !== panelRef.current) return;\n e.preventDefault();\n close();\n };\n\n const triggerProps = trigger.props as TriggerProps;\n\n const handleTriggerClick = (e: React.MouseEvent<HTMLElement>) => {\n triggerProps.onClick?.(e);\n if (!e.defaultPrevented) requestOpen(!isOpen);\n };\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n triggerProps.onKeyDown?.(e);\n // A key on something inside the trigger is that element's to answer.\n if (e.defaultPrevented || e.target !== e.currentTarget) return;\n if (e.key === 'Escape') {\n if (isOpen && closeOnEscape) {\n e.preventDefault();\n close();\n }\n return;\n }\n if (e.key !== 'Enter' && e.key !== ' ') return;\n if (handlesKeyItself(e.currentTarget, e.key)) return;\n // Space would scroll the page; a held key repeats.\n e.preventDefault();\n if (!e.repeat) requestOpen(!isOpen);\n };\n\n const needsButtonRole =\n typeof trigger.type === 'string' &&\n !NATIVE_CONTROLS.has(trigger.type) &&\n !(trigger.type === 'a' && triggerProps.href != null);\n\n const clonedTrigger = cloneElement(\n trigger as React.ReactElement<Record<string, unknown>>,\n {\n ...(needsButtonRole\n ? {\n role: triggerProps.role ?? 'button',\n tabIndex: triggerProps.tabIndex ?? 0,\n }\n : {}),\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': panelMounted ? panelId : undefined,\n onClick: handleTriggerClick,\n onKeyDown: handleTriggerKeyDown,\n }\n );\n\n const rootClasses = classNames(\n usePrefixedClassNames('popover', { 'is-active': isOpen }),\n bulmaHelperClasses,\n className\n );\n const panelClasses = classNames(\n usePrefixedClassNames('popover-content', {\n [`is-${resolved.position}`]: true,\n // The default lines up with the trigger's inline start, so the\n // stylesheet moves it to the right edge on a right-to-left page.\n 'is-start-aligned': position === undefined,\n 'is-portal': appendToBody,\n }),\n contentClassName\n );\n\n return (\n // The ref after the spread: React 19 hands a function component a `ref`\n // prop like any other, and the wrapper has to stay ours.\n <div className={rootClasses} {...rest} ref={rootRef}>\n {clonedTrigger}\n {isOpen && (\n <PopupPortal disabled={!appendToBody}>\n <PopoverPanel\n panelRef={panelRef}\n titleId={titleId}\n ariaLabel={ariaLabel}\n close={close}\n id={panelId}\n className={panelClasses}\n style={\n appendToBody\n ? {\n position: 'fixed',\n top: resolved.top,\n left: resolved.left,\n }\n : undefined\n }\n onKeyDown={handlePanelKeyDown}\n onPointerDownCapture={markInsidePress}\n >\n {children}\n </PopoverPanel>\n </PopupPortal>\n )}\n </div>\n );\n};\n\ninterface PopoverPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n panelRef: React.RefObject<HTMLDivElement | null>;\n titleId: string;\n ariaLabel?: string;\n close: () => void;\n}\n\n/**\n * The open panel. It mounts with each opening, so it counts the\n * `Popover.Header`s inside it afresh every time.\n */\nfunction PopoverPanel({\n panelRef,\n titleId,\n ariaLabel,\n close,\n children,\n ...attrs\n}: PopoverPanelProps) {\n // Headers register in a layout effect, after this first render, and this\n // panel's own layout effect runs after theirs. Until then the panel assumes\n // it has one, so a panel that does is named from its first commit, before\n // focus moves in, and one that doesn't drops the reference before it paints.\n const [titlesCounted, setTitlesCounted] = useState(false);\n const [titleCount, setTitleCount] = useState(0);\n const registerTitle = useCallback(() => {\n setTitleCount(n => n + 1);\n return () => setTitleCount(n => n - 1);\n }, []);\n useClientLayoutEffect(() => {\n setTitlesCounted(true);\n }, []);\n const named = Boolean(ariaLabel) || titleCount > 0;\n\n useEffect(() => {\n if (titlesCounted && !named) {\n warnOnce(\n 'Popover:unnamed',\n '[bestax-bulma] <Popover> opened a panel with no accessible name. ' +\n 'Pass ariaLabel, or render a Popover.Header inside it.'\n );\n }\n }, [titlesCounted, named]);\n\n const context = useMemo(\n () => ({ titleId, registerTitle, close }),\n [titleId, registerTitle, close]\n );\n\n return (\n <PopoverContext.Provider value={context}>\n <div\n {...attrs}\n ref={panelRef}\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={\n !ariaLabel && (!titlesCounted || titleCount > 0) ? titleId : undefined\n }\n tabIndex={-1}\n >\n {children}\n </div>\n </PopoverContext.Provider>\n );\n}\n\n/**\n * Props for the Popover.Header component. Its `id` is the one the panel's\n * `aria-labelledby` names, so it isn't yours to set.\n */\nexport interface PopoverHeaderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'id'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * The popover's title, which names the panel for assistive technology.\n *\n * @function\n * @param {PopoverHeaderProps} props - Props for the Popover.Header component.\n * @returns {JSX.Element} The header element.\n */\nexport const PopoverHeader: React.FC<PopoverHeaderProps> = ({\n className,\n ...props\n}) => {\n const context = useContext(PopoverContext);\n const registerTitle = context?.registerTitle;\n // Before paint, so the panel is named by the time it shows.\n useClientLayoutEffect(() => registerTitle?.(), [registerTitle]);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-header'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n id={context?.titleId}\n />\n );\n};\n\n/**\n * Props for the Popover.Body component.\n */\nexport interface PopoverBodyProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * The popover's main content area.\n *\n * @function\n * @param {PopoverBodyProps} props - Props for the Popover.Body component.\n * @returns {JSX.Element} The body element.\n */\nexport const PopoverBody: React.FC<PopoverBodyProps> = ({\n className,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-body'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n />\n );\n};\n\n/**\n * Props for the Popover.Footer component.\n */\nexport interface PopoverFooterProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * A row of actions along the bottom of the popover, aligned to the end.\n *\n * @function\n * @param {PopoverFooterProps} props - Props for the Popover.Footer component.\n * @returns {JSX.Element} The footer element.\n */\nexport const PopoverFooter: React.FC<PopoverFooterProps> = ({\n className,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-footer'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n />\n );\n};\n\n/**\n * Props for the Popover.Close component: the props of a `Button` rendered as\n * a `<button>`.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a close button inside a form doesn't submit it.\n * @extraProp {React.MouseEventHandler<HTMLButtonElement>} [onClick] - Runs before the popover closes. Call `preventDefault()` to keep it open.\n */\nexport interface PopoverCloseProps\n extends\n ButtonOwnProps,\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps> {}\n\n/**\n * A `Button` that closes the popover, handing focus back to the trigger.\n *\n * @function\n * @param {PopoverCloseProps} props - Props for the Popover.Close component.\n * @returns {JSX.Element} The close button.\n */\nexport const PopoverClose: React.FC<PopoverCloseProps> = ({\n onClick,\n ...props\n}) => {\n const context = useContext(PopoverContext);\n return (\n <Button\n {...props}\n type={buttonType(props.type)}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) context?.close();\n }}\n />\n );\n};\n\n/** Popover with Header, Body, Footer and Close sub-components. */\nexport const Popover = withSubComponents(\n PopoverComponent,\n {\n Header: PopoverHeader,\n Body: PopoverBody,\n Footer: PopoverFooter,\n Close: PopoverClose,\n },\n 'Popover'\n);\n\nexport default Popover;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover.js","sources":["../../../src/components/Popover.tsx"],"sourcesContent":["import React, {\n cloneElement,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\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 { PopupPortal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { focusTabStop, useFocusTrap } from '../helpers/useFocusTrap';\nimport { marginGap, useAnchoredPosition } from '../helpers/useAnchoredPosition';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { getDeepestActiveElement } from '../helpers/shadowDom';\nimport { useOutsidePress } from '../helpers/useOutsidePress';\nimport { buttonType } from '../helpers/buttonType';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { Button, ButtonOwnProps } from '../elements/Button';\nimport type { PickerPosition } from '../form/_pickerInternals/pickerTypes';\n\n/**\n * Where the panel opens against its trigger: below (`bottom-*`) or above\n * (`top-*`), lined up with the trigger's left or right edge. `auto` picks the\n * one that keeps the panel in the viewport, preferring below and lined up on\n * the left. The same union the date and time pickers take.\n */\nexport type PopoverPosition = PickerPosition;\n\n/**\n * Props for the Popover component. `className`, `id`, the other HTML\n * attributes and the helper props land on the wrapper around the trigger,\n * not on the panel; `contentClassName` reaches the panel.\n * @extraProp {string} [className] - Additional classes for the wrapper around the trigger. The panel takes `contentClassName`.\n */\nexport interface PopoverProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'children'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The element that opens and closes the popover, such as a `Button`.\n * Popover gives it `aria-haspopup=\"dialog\"`, `aria-expanded`,\n * `aria-controls` while the panel is open, and click and key handlers that\n * run after its own (call `preventDefault()` in yours to keep the popover\n * from toggling). It has to be a single element that passes `onClick` and\n * `onKeyDown` to its DOM node. Enter and Space toggle a trigger the browser\n * doesn't click on its own, and an intrinsic element that isn't already a\n * control (a `<span>`) also gets `role=\"button\"` and `tabIndex={0}` unless\n * it sets them; a component that renders one has to take those itself.\n */\n trigger: React.ReactElement;\n /** The panel's content, usually `Popover.Header`, `Popover.Body` and `Popover.Footer`. */\n children?: React.ReactNode;\n /**\n * Controlled open state. When set, the trigger and every dismissal only\n * report through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled. Opening moves focus into the\n * panel, so a popover that starts open takes focus once the page loads.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the state asked for: `true` from the trigger opening it,\n * `false` from the trigger, `Popover.Close`, Escape or an outside\n * `pointerdown`. Fires in both controlled and uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Where the panel opens against the trigger. Left out, it opens below and\n * lines up with the trigger's start edge, which is its right edge on a\n * right-to-left page, so a trigger at the start of the line doesn't push\n * the panel off the screen. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges on either page.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Render the panel through `Portal`, into the `portalContainer` a\n * `ConfigProvider` sets, else the overlay it's in that takes its popups,\n * such as a `Modal`, else `document.body`, fixed to the viewport, so an\n * ancestor's `overflow`, `transform` or stacking context can't clip it.\n * The panel then shows from the commit after hydration, never in server\n * markup. Theming variables set on an ancestor of the trigger reach it\n * only when its container is inside that ancestor.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /**\n * Keep Tab and Shift+Tab inside the panel while it is open, as the ARIA\n * dialog pattern does for a non-modal dialog. Pointer focus leaves freely\n * and the page stays usable. With `false`, Tab moves past the panel and\n * the popover stays open. Focus moves into the panel on open and back to\n * the trigger on close either way.\n * @defaultValue true\n */\n trapFocus?: boolean;\n /**\n * Close on a `pointerdown` outside the trigger and the panel. Content the\n * panel renders through a portal (a nested `Popover`, a portaled picker)\n * still counts as inside.\n * @defaultValue true\n */\n closeOnClickOutside?: boolean;\n /**\n * Close on Escape while focus is in the panel or on the trigger. A dialog\n * nested in the panel, such as a date picker's calendar, takes its own\n * Escape first, and so does content that calls `preventDefault()` on it.\n * @defaultValue true\n */\n closeOnEscape?: boolean;\n /**\n * The panel's accessible name. Without it the panel is named by its\n * `Popover.Header`, and a development build warns when it has neither.\n */\n ariaLabel?: string;\n /** Additional classes for the panel (`.popover-content`). */\n contentClassName?: string;\n}\n\ninterface PopoverContextValue {\n /** The id `Popover.Header` takes, which names the panel. */\n titleId: string;\n /** Records a mounted `Popover.Header`; the returned function forgets it. */\n registerTitle: () => () => void;\n /** Asks the popover to close. */\n close: () => void;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\n/** The trigger props Popover reads before replacing them. */\ninterface TriggerProps {\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLElement>) => void;\n role?: string;\n tabIndex?: number;\n href?: unknown;\n}\n\n/** Intrinsic elements that are controls already, and keep their own role. */\nconst NATIVE_CONTROLS = new Set([\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'summary',\n]);\n\n/**\n * Whether the browser answers this key on `el` itself, by clicking it or by\n * using the key as input, so the trigger's click handler covers it.\n */\nfunction handlesKeyItself(el: Element, key: string): boolean {\n if (NATIVE_CONTROLS.has(el.localName)) return true;\n return el.localName === 'a' && key === 'Enter' && el.hasAttribute('href');\n}\n\n/** The innermost dialog the event passed through, which is the one its Escape belongs to. */\nfunction nearestDialog(event: Event): EventTarget | null {\n return (\n event.composedPath().find(node => {\n const role = (node as Element).getAttribute?.('role');\n return role === 'dialog' || role === 'alertdialog';\n }) ?? null\n );\n}\n\n/**\n * The `Popover` component opens a panel of interactive content, such as a filter form or a set of share options, anchored to the element that toggles it.\n *\n * The panel is a non-modal `role=\"dialog\"`: focus moves into it on open\n * and returns to the trigger on close, while the rest of the page stays\n * reachable by pointer and assistive technology. For hover-only hints use\n * `Tooltip`, and for a list of actions use `Dropdown`.\n *\n * @function\n * @param {PopoverProps} props - Props for the Popover component.\n * @returns {JSX.Element} The trigger in its wrapper, and the panel while open.\n *\n * @example\n * <Popover trigger={<Button>Filters</Button>}>\n * <Popover.Header>Filter rows</Popover.Header>\n * <Popover.Body>…</Popover.Body>\n * <Popover.Footer>\n * <Popover.Close>Done</Popover.Close>\n * </Popover.Footer>\n * </Popover>\n */\nconst PopoverComponent: React.FC<PopoverProps> = ({\n trigger,\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n position,\n appendToBody = false,\n trapFocus = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n contentClassName,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const baseId = useId();\n const panelId = `${baseId}-panel`;\n const titleId = `${baseId}-title`;\n\n const isControlled = controlledOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const isOpen = controlledOpen ?? internalOpen;\n\n const requestOpen = useCallback(\n (next: boolean) => {\n onOpenChange?.(next);\n if (!isControlled) setInternalOpen(next);\n },\n [isControlled, onOpenChange]\n );\n const close = useCallback(() => requestOpen(false), [requestOpen]);\n\n // A portaled panel has no server markup, so it only exists from the commit\n // after hydration. Everything that measures or focuses it waits for that.\n const hydrated = useIsHydrated();\n const panelMounted = isOpen && (hydrated || !appendToBody);\n\n const resolved = useAnchoredPosition(rootRef, panelRef, {\n active: panelMounted,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-popover-offset` in the stylesheet, so the\n // coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n });\n\n // The trigger renders first inside the wrapper. Read when needed rather\n // than held, so a trigger that remounted is still the one found.\n const triggerNode = useCallback((): HTMLElement | null => {\n const first = rootRef.current?.firstElementChild;\n return first && first !== panelRef.current ? (first as HTMLElement) : null;\n }, []);\n const restoreFocusRef = useMemo(\n () => ({\n get current() {\n return triggerNode();\n },\n }),\n [triggerNode]\n );\n\n useFocusTrap(panelRef, {\n active: panelMounted && trapFocus,\n restoreFocus: restoreFocusRef,\n });\n\n // Without the trap, focus still arrives in the panel and goes back to the\n // trigger, on the trap's terms: only while the panel still holds it.\n useEffect(() => {\n const panel = panelRef.current;\n if (!panelMounted || trapFocus || !panel) return undefined;\n focusTabStop(panel);\n return () => {\n const doc = panel.ownerDocument;\n const now = getDeepestActiveElement(doc);\n if (!now || now === doc.body || panel.contains(now)) {\n triggerNode()?.focus();\n }\n };\n }, [panelMounted, trapFocus, triggerNode]);\n\n // A press outside the wrapper, which holds the trigger and the panel,\n // closes it. One inside the panel's React tree counts as inside, so content\n // the panel portals elsewhere does too.\n const markInsidePress = useOutsidePress(\n rootRef,\n panelMounted && closeOnClickOutside,\n close\n );\n\n const handlePanelKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== 'Escape' || !closeOnEscape || e.defaultPrevented) return;\n // React bubbles the key here from portaled content as well, so a dialog\n // of its own on the way (a nested popover, a picker's calendar) owns it.\n const owner = nearestDialog(e.nativeEvent);\n if (owner && owner !== panelRef.current) return;\n e.preventDefault();\n close();\n };\n\n const triggerProps = trigger.props as TriggerProps;\n\n const handleTriggerClick = (e: React.MouseEvent<HTMLElement>) => {\n triggerProps.onClick?.(e);\n if (!e.defaultPrevented) requestOpen(!isOpen);\n };\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n triggerProps.onKeyDown?.(e);\n // A key on something inside the trigger is that element's to answer.\n if (e.defaultPrevented || e.target !== e.currentTarget) return;\n if (e.key === 'Escape') {\n if (isOpen && closeOnEscape) {\n e.preventDefault();\n close();\n }\n return;\n }\n if (e.key !== 'Enter' && e.key !== ' ') return;\n if (handlesKeyItself(e.currentTarget, e.key)) return;\n // Space would scroll the page; a held key repeats.\n e.preventDefault();\n if (!e.repeat) requestOpen(!isOpen);\n };\n\n const needsButtonRole =\n typeof trigger.type === 'string' &&\n !NATIVE_CONTROLS.has(trigger.type) &&\n !(trigger.type === 'a' && triggerProps.href != null);\n\n const clonedTrigger = cloneElement(\n trigger as React.ReactElement<Record<string, unknown>>,\n {\n ...(needsButtonRole\n ? {\n role: triggerProps.role ?? 'button',\n tabIndex: triggerProps.tabIndex ?? 0,\n }\n : {}),\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': panelMounted ? panelId : undefined,\n onClick: handleTriggerClick,\n onKeyDown: handleTriggerKeyDown,\n }\n );\n\n const rootClasses = classNames(\n usePrefixedClassNames('popover', { 'is-active': isOpen }),\n bulmaHelperClasses,\n className\n );\n const panelClasses = classNames(\n usePrefixedClassNames('popover-content', {\n [`is-${resolved.position}`]: true,\n // The default lines up with the trigger's inline start, so the\n // stylesheet moves it to the right edge on a right-to-left page.\n 'is-start-aligned': position === undefined,\n 'is-portal': appendToBody,\n }),\n contentClassName\n );\n\n return (\n // The ref after the spread: React 19 hands a function component a `ref`\n // prop like any other, and the wrapper has to stay ours.\n <div className={rootClasses} {...rest} ref={rootRef}>\n {clonedTrigger}\n {isOpen && (\n <PopupPortal disabled={!appendToBody}>\n <PopoverPanel\n panelRef={panelRef}\n titleId={titleId}\n ariaLabel={ariaLabel}\n close={close}\n id={panelId}\n className={panelClasses}\n style={\n appendToBody\n ? {\n position: 'fixed',\n top: resolved.top,\n left: resolved.left,\n }\n : undefined\n }\n onKeyDown={handlePanelKeyDown}\n onPointerDownCapture={markInsidePress}\n >\n {children}\n </PopoverPanel>\n </PopupPortal>\n )}\n </div>\n );\n};\n\ninterface PopoverPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n panelRef: React.RefObject<HTMLDivElement | null>;\n titleId: string;\n ariaLabel?: string;\n close: () => void;\n}\n\n/**\n * The open panel. It mounts with each opening, so it counts the\n * `Popover.Header`s inside it afresh every time.\n */\nfunction PopoverPanel({\n panelRef,\n titleId,\n ariaLabel,\n close,\n children,\n ...attrs\n}: PopoverPanelProps) {\n // Headers register in a layout effect, after this first render, and this\n // panel's own layout effect runs after theirs. Until then the panel assumes\n // it has one, so a panel that does is named from its first commit, before\n // focus moves in, and one that doesn't drops the reference before it paints.\n const [titlesCounted, setTitlesCounted] = useState(false);\n const [titleCount, setTitleCount] = useState(0);\n const registerTitle = useCallback(() => {\n setTitleCount(n => n + 1);\n return () => setTitleCount(n => n - 1);\n }, []);\n useClientLayoutEffect(() => {\n setTitlesCounted(true);\n }, []);\n const named = Boolean(ariaLabel) || titleCount > 0;\n\n useEffect(() => {\n if (titlesCounted && !named) {\n warnOnce(\n 'Popover:unnamed',\n '[bestax-bulma] <Popover> opened a panel with no accessible name. ' +\n 'Pass ariaLabel, or render a Popover.Header inside it.'\n );\n }\n }, [titlesCounted, named]);\n\n const context = useMemo(\n () => ({ titleId, registerTitle, close }),\n [titleId, registerTitle, close]\n );\n\n return (\n <PopoverContext.Provider value={context}>\n <div\n {...attrs}\n ref={panelRef}\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={\n !ariaLabel && (!titlesCounted || titleCount > 0) ? titleId : undefined\n }\n tabIndex={-1}\n >\n {children}\n </div>\n </PopoverContext.Provider>\n );\n}\n\n/**\n * Props for the Popover.Header component. Its `id` is the one the panel's\n * `aria-labelledby` names, so it isn't yours to set.\n */\nexport interface PopoverHeaderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'id'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * The popover's title, which names the panel for assistive technology.\n *\n * @function\n * @param {PopoverHeaderProps} props - Props for the Popover.Header component.\n * @returns {JSX.Element} The header element.\n */\nexport const PopoverHeader: React.FC<PopoverHeaderProps> = ({\n className,\n ...props\n}) => {\n const context = useContext(PopoverContext);\n const registerTitle = context?.registerTitle;\n // Before paint, so the panel is named by the time it shows.\n useClientLayoutEffect(() => registerTitle?.(), [registerTitle]);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-header'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n id={context?.titleId}\n />\n );\n};\n\n/**\n * Props for the Popover.Body component.\n */\nexport interface PopoverBodyProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * The popover's main content area.\n *\n * @function\n * @param {PopoverBodyProps} props - Props for the Popover.Body component.\n * @returns {JSX.Element} The body element.\n */\nexport const PopoverBody: React.FC<PopoverBodyProps> = ({\n className,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-body'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n />\n );\n};\n\n/**\n * Props for the Popover.Footer component.\n */\nexport interface PopoverFooterProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * A row of actions along the bottom of the popover, aligned to the end.\n *\n * @function\n * @param {PopoverFooterProps} props - Props for the Popover.Footer component.\n * @returns {JSX.Element} The footer element.\n */\nexport const PopoverFooter: React.FC<PopoverFooterProps> = ({\n className,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-footer'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n />\n );\n};\n\n/**\n * Props for the Popover.Close component: the props of a `Button` rendered as\n * a `<button>`.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a close button inside a form doesn't submit it.\n * @extraProp {React.MouseEventHandler<HTMLButtonElement>} [onClick] - Runs before the popover closes. Call `preventDefault()` to keep it open.\n */\nexport interface PopoverCloseProps\n extends\n ButtonOwnProps,\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps> {}\n\n/**\n * A `Button` that closes the popover, handing focus back to the trigger.\n *\n * @function\n * @param {PopoverCloseProps} props - Props for the Popover.Close component.\n * @returns {JSX.Element} The close button.\n */\nexport const PopoverClose: React.FC<PopoverCloseProps> = ({\n onClick,\n ...props\n}) => {\n const context = useContext(PopoverContext);\n return (\n <Button\n {...props}\n type={buttonType(props.type)}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) context?.close();\n }}\n />\n );\n};\n\n/** Popover with Header, Body, Footer and Close sub-components. */\nexport const Popover = withSubComponents(\n PopoverComponent,\n {\n Header: PopoverHeader,\n Body: PopoverBody,\n Footer: PopoverFooter,\n Close: PopoverClose,\n },\n 'Popover'\n);\n\nexport default Popover;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.js","sources":["../../../src/components/Sidebar.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useCallback, useRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useScrollLock } from '../helpers/scrollLock';\nimport { Portal, usePortalProp } from '../helpers/portal';\nimport { buttonType } from '../helpers/buttonType';\nimport { useOverlayEscape, useOverlayStack } from '../helpers/overlayStack';\nimport { trapTab } from '../helpers/useFocusTrap';\nimport { useOverlayFocus } from '../helpers/useOverlayFocus';\nimport { inertProps } from '../helpers/inertProps';\n\n/** Position of the sidebar relative to the viewport. */\nexport type SidebarPosition = 'left' | 'right';\n\n/**\n * Props for the Sidebar component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the sidebar element.\n */\nexport interface SidebarProps\n extends\n Omit<React.HTMLAttributes<HTMLElement>, 'children' | 'color'>,\n BulmaClassesProps {\n /**\n * Whether the sidebar is open (required). Opening moves focus into the\n * sidebar, to its first tab stop or the sidebar itself, except for a sidebar\n * without an overlay opened while a modal overlay, such as a Modal, is open:\n * that one leaves focus where it is. That's decided as it opens, and\n * changing `overlay` while it's open doesn't move focus. Closing hands\n * focus back to whatever had it when the sidebar opened, unless focus has\n * already left the sidebar, as it does for an overlay opened over it. A\n * closed sidebar stays in the page, so it can slide out, and is `inert` and\n * `aria-hidden` there: Tab passes over its content and assistive\n * technology doesn't read it.\n */\n isOpen: boolean;\n /** Callback when sidebar should close. */\n onClose?: () => void;\n /** Which side the sidebar appears from. Default: 'left'. */\n position?: SidebarPosition;\n /** Custom width of the sidebar. */\n width?: string;\n /** Sidebar takes full width (mobile-style). */\n isFullwidth?: boolean;\n /** Sidebar takes full width (mobile-style). @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n fullWidth?: boolean;\n /**\n * Show an overlay behind the sidebar, which makes it modal: it gets\n * `aria-modal=\"true\"`, locks page scroll, and keeps Tab and Shift+Tab\n * inside it while it is the topmost modal overlay. A Modal or Dialog opened\n * over it, even one rendered inside it, holds Tab until it closes. Without\n * an overlay the sidebar isn't modal and holds no Tab: on the page, Tab\n * moves in and out of it freely, and opened over a Modal, it leaves the\n * Modal holding Tab, and focus, while still taking Escape first. Whether\n * the sidebar takes focus is decided as it opens: changing this while it's\n * open moves the Tab trap, not focus. Default: true.\n */\n overlay?: boolean;\n /** Close sidebar when overlay is clicked. Default: true. */\n overlayClose?: boolean;\n /**\n * Close sidebar on Escape key. Only the topmost open overlay responds,\n * whichever Modal, Dialog, Sidebar or full-page Loading opened last, so\n * Escape closes one layer at a time. The sidebar marks the Escape it closes\n * on as used with `preventDefault()`, and a Toast waits until no overlay is\n * open. Turned off, a sidebar on top still keeps Escape from the layers\n * under it. A popup inside it, such as a Dropdown's menu or a date picker's\n * calendar, takes its own Escape first, and so does content that calls\n * `preventDefault()` on it. Default: true.\n */\n escapeClose?: boolean;\n /** Allow closing the sidebar. Default: true. */\n canCancel?: boolean;\n /** Content to display in the sidebar. */\n children?: React.ReactNode;\n /**\n * Renders inline instead of using a portal. Without it, the sidebar renders\n * inline on the server and while hydrating, moving into the portal once the\n * client takes over, so hydration matches.\n */\n inline?: boolean;\n}\n\n/**\n * The `Sidebar` component provides a slide-out navigation panel that appears from the left or right side of the screen.\n *\n * @function\n * @param {SidebarProps} props - Props for the Sidebar component.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the sidebar element.\n * @returns {JSX.Element | null} The rendered sidebar component.\n *\n * @example\n * // Basic sidebar\n * const [isOpen, setIsOpen] = useState(false);\n * <Sidebar isOpen={isOpen} onClose={() => setIsOpen(false)}>\n * <Menu>...</Menu>\n * </Sidebar>\n *\n * @example\n * // Right-side sidebar with custom width\n * <Sidebar\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * position=\"right\"\n * width=\"320px\"\n * >\n * <div>Panel content</div>\n * </Sidebar>\n */\nconst SidebarComponent = forwardRef<HTMLElement, SidebarProps>(\n (\n {\n isOpen,\n onClose,\n position = 'left',\n width = '260px',\n isFullwidth,\n fullWidth,\n overlay = true,\n overlayClose = true,\n escapeClose = true,\n canCancel = true,\n children,\n inline = false,\n className,\n style,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n // A portal has no server-rendered counterpart, so the sidebar renders in\n // place on the server and while hydrating, and moves into its portal once\n // the client takes over, as Modal's `portal` does. An `inline` one stays\n // in place, so a change to the configured default moves nothing.\n const { isPortaled, defaultTarget } = usePortalProp(!inline);\n const sidebarRef = useRef<HTMLElement>(null);\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const resolvedFullwidth = isFullwidth ?? fullWidth ?? false;\n\n // Close handler\n const handleClose = useCallback(() => {\n if (canCancel && onClose) {\n onClose();\n }\n }, [canCancel, onClose]);\n\n // Handle overlay click\n const handleOverlayClick = useCallback(() => {\n if (overlayClose) {\n handleClose();\n }\n }, [overlayClose, handleClose]);\n\n // Joins the stack of open overlays, so the sidebar answers Escape only\n // while it's the topmost overlay, and keeps it from those under it. It's\n // modal with an overlay: without one it leaves Tab to a modal overlay\n // under it.\n const isTopmost = useOverlayStack(isOpen, overlay);\n const closesOnEscape = escapeClose && canCancel && Boolean(onClose);\n\n // Escape closes it, on `window`, as in `Modal`, so everything inside the\n // sidebar has had the key first, and an Escape it used is left to it.\n useOverlayEscape(isOpen && closesOnEscape, isTopmost, handleClose);\n\n // Keep Tab inside while there's an overlay, as `Modal` does:\n // `aria-modal` hides the rest of the page from assistive technology, so\n // the keyboard order has to agree. Only while it's the topmost modal\n // overlay, so a Modal or Dialog opened over the sidebar, even one\n // rendered inside it, holds Tab instead until it closes, and a sidebar\n // without an overlay opened over it doesn't. On `window` for the same\n // reason as Escape: a trap inside, such as a portaled popup's, has had\n // the Tab first, and one it used is left where it put focus. It's the trap\n // `useFocusTrap` sets, so a Tab the browser still takes out, as Safari\n // does past links, is sent back in. It reads the aside as each key\n // arrives, so one remounted while the sidebar is open, by a new portal\n // target or by switching `inline`, stays trapped.\n useEffect(() => {\n if (!isOpen || !overlay) return undefined;\n return trapTab(\n () => sidebarRef.current,\n window,\n () => isTopmost('modal')\n );\n }, [isOpen, overlay, isTopmost]);\n\n // Lock the page's scrolling when sidebar is open. Ref-counted through the\n // shared helper so an overlapping Modal/Dialog/Loading doesn't unlock\n // underneath.\n useScrollLock(isOpen && overlay);\n\n // Move focus into the sidebar on open, to the first stop Tab wraps to or\n // the sidebar itself, and hand it back on close, as `Modal` does. Moving\n // into the portal after hydration, or to a different `defaultTarget`,\n // remounts the sidebar: focus is handed back from the old nodes and moved\n // into the new ones. Whether it takes focus is decided as it opens, so\n // `overlay` changing while it's open leaves focus where the user has it.\n // Without an overlay the sidebar holds no Tab, so with a modal overlay\n // open under it, it leaves focus alone: the first Tab would take focus\n // back there and leave the sidebar's other controls out of reach.\n useOverlayFocus(sidebarRef, isOpen, {\n modal: overlay,\n // In place it's `false`, which no portal target is.\n remountKey: isPortaled ? defaultTarget : false,\n });\n\n // Use combined ref\n const combinedRef = useCallback(\n (node: HTMLElement | null) => {\n (sidebarRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches by\n // running it instead of calling the ref with `null`; React 18 discards the\n // return value entirely. Returning it from here would be a React-19-only\n // contract, so we hold the cleanup and run it ourselves on detach — the\n // same shape as `Dropdown`, `Modal`, `Dialog`, `Toast` and `Carousel`.\n // The form controls that merge a forwarded ref still discard the cleanup\n // and detach with `ref(null)`, so this is not yet library-wide — grep\n // `typeof ref === 'function'` for the current split.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLElement | null>).current = node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const sidebarClasses = usePrefixedClassNames('sidebar', {\n 'is-active': isOpen,\n [`is-${position}`]: position,\n 'is-fullwidth': resolvedFullwidth,\n });\n const backgroundClass = usePrefixedClassNames('sidebar-background', {\n 'is-active': isOpen,\n });\n const contentClass = usePrefixedClassNames('sidebar-content');\n\n const combinedClasses = classNames(\n sidebarClasses,\n bulmaHelperClasses,\n className\n );\n\n // Custom style for width\n const sidebarStyle: React.CSSProperties = {\n ...style,\n '--bulma-sidebar-width': resolvedFullwidth ? '100%' : width,\n } as React.CSSProperties;\n\n const sidebarContent = (\n <>\n {overlay && (\n <div\n className={backgroundClass}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <aside\n ref={combinedRef}\n className={combinedClasses}\n style={sidebarStyle}\n role=\"dialog\"\n aria-modal={overlay ? 'true' : undefined}\n aria-hidden={!isOpen}\n // React commits this before the effect that moves focus in runs, so\n // an opening sidebar is no longer inert by then.\n {...inertProps(!isOpen)}\n tabIndex={-1}\n {...rest}\n >\n <div className={contentClass}>{children}</div>\n </aside>\n </>\n );\n\n // In a portal for proper stacking.\n return <Portal disabled={!isPortaled}>{sidebarContent}</Portal>;\n }\n);\n\n// Sub-components\n\n/**\n * Props for the SidebarHeader component.\n */\nexport interface SidebarHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Header content. */\n children?: React.ReactNode;\n}\n\n/**\n * Container for the sidebar header.\n *\n * @function\n * @param {SidebarHeaderProps} props - Props for the SidebarHeader component.\n * @returns {JSX.Element} The rendered sidebar header.\n */\nexport const SidebarHeader: React.FC<SidebarHeaderProps> = ({\n className,\n children,\n ...props\n}) => {\n const headerClass = usePrefixedClassNames('sidebar-header');\n return (\n <div className={classNames(headerClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n/**\n * Props for the SidebarTitle component.\n */\nexport interface SidebarTitleProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Title content. */\n children?: React.ReactNode;\n}\n\n/**\n * Title text inside the header.\n *\n * @function\n * @param {SidebarTitleProps} props - Props for the SidebarTitle component.\n * @returns {JSX.Element} The rendered sidebar title.\n */\nexport const SidebarTitle: React.FC<SidebarTitleProps> = ({\n className,\n children,\n ...props\n}) => {\n const titleClass = usePrefixedClassNames('sidebar-title');\n return (\n <p className={classNames(titleClass, className)} {...props}>\n {children}\n </p>\n );\n};\n\n/**\n * Props for the SidebarClose component.\n * Extends standard button attributes.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a close button inside a form does not submit it. Pass `'submit'` or `'reset'` and yours is used; any other value, or a spread carrying `type: undefined`, renders `'button'`.\n * @extraProp {string} [aria-label='Close'] - Accessible name. Pass your own to replace it. An empty one, or a spread carrying `'aria-label': undefined`, keeps the default rather than leaving the button unnamed.\n */\nexport type SidebarCloseProps = React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Close button for the sidebar.\n *\n * @function\n * @param {SidebarCloseProps} props - Props for the SidebarClose component.\n * @returns {JSX.Element} The rendered close button.\n */\nexport const SidebarClose: React.FC<SidebarCloseProps> = ({\n className,\n children,\n ...props\n}) => {\n const closeClass = usePrefixedClassNames('sidebar-close');\n return (\n <button\n className={classNames(closeClass, className)}\n {...props}\n // After the spread, reading through it: a key the spread carries with no\n // value would otherwise erase the default, leaving a nameless button\n // that submits the form around it. An empty label falls back too: the\n // button is drawn as an icon, so `''` would leave it unnamed. A caller's\n // own value still wins; `buttonType` says more.\n aria-label={props['aria-label'] || 'Close'}\n type={buttonType(props.type)}\n >\n {children}\n </button>\n );\n};\n\n/**\n * Props for the SidebarBody component.\n */\nexport interface SidebarBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Body content. */\n children?: React.ReactNode;\n}\n\n/**\n * Main content area of the sidebar.\n *\n * @function\n * @param {SidebarBodyProps} props - Props for the SidebarBody component.\n * @returns {JSX.Element} The rendered sidebar body.\n */\nexport const SidebarBody: React.FC<SidebarBodyProps> = ({\n className,\n children,\n ...props\n}) => {\n const bodyClass = usePrefixedClassNames('sidebar-body');\n return (\n <div className={classNames(bodyClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n/**\n * Props for the SidebarFooter component.\n */\nexport interface SidebarFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content. */\n children?: React.ReactNode;\n}\n\n/**\n * Footer area of the sidebar.\n *\n * @function\n * @param {SidebarFooterProps} props - Props for the SidebarFooter component.\n * @returns {JSX.Element} The rendered sidebar footer.\n */\nexport const SidebarFooter: React.FC<SidebarFooterProps> = ({\n className,\n children,\n ...props\n}) => {\n const footerClass = usePrefixedClassNames('sidebar-footer');\n return (\n <div className={classNames(footerClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n// Attach static subcomponents\nexport const Sidebar = withSubComponents(\n SidebarComponent,\n {\n Header: SidebarHeader,\n Title: SidebarTitle,\n Close: SidebarClose,\n Body: SidebarBody,\n Footer: SidebarFooter,\n },\n 'Sidebar'\n);\n\nexport default Sidebar;\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Sidebar.js","sources":["../../../src/components/Sidebar.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useCallback, useRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useScrollLock } from '../helpers/scrollLock';\nimport { Portal, usePortalProp } from '../helpers/portal';\nimport { buttonType } from '../helpers/buttonType';\nimport { useOverlayEscape, useOverlayStack } from '../helpers/overlayStack';\nimport { trapTab } from '../helpers/useFocusTrap';\nimport { useOverlayFocus } from '../helpers/useOverlayFocus';\nimport { inertProps } from '../helpers/inertProps';\n\n/** Position of the sidebar relative to the viewport. */\nexport type SidebarPosition = 'left' | 'right';\n\n/**\n * Props for the Sidebar component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the sidebar element.\n */\nexport interface SidebarProps\n extends\n Omit<React.HTMLAttributes<HTMLElement>, 'children' | 'color'>,\n BulmaClassesProps {\n /**\n * Whether the sidebar is open (required). Opening moves focus into the\n * sidebar, to its first tab stop or the sidebar itself, except for a sidebar\n * without an overlay opened while a modal overlay, such as a Modal, is open:\n * that one leaves focus where it is. That's decided as it opens, and\n * changing `overlay` while it's open doesn't move focus. Closing hands\n * focus back to whatever had it when the sidebar opened, unless focus has\n * already left the sidebar, as it does for an overlay opened over it. A\n * closed sidebar stays in the page, so it can slide out, and is `inert` and\n * `aria-hidden` there: Tab passes over its content and assistive\n * technology doesn't read it.\n */\n isOpen: boolean;\n /** Callback when sidebar should close. */\n onClose?: () => void;\n /** Which side the sidebar appears from. Default: 'left'. */\n position?: SidebarPosition;\n /** Custom width of the sidebar. */\n width?: string;\n /** Sidebar takes full width (mobile-style). */\n isFullwidth?: boolean;\n /** Sidebar takes full width (mobile-style). @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n fullWidth?: boolean;\n /**\n * Show an overlay behind the sidebar, which makes it modal: it gets\n * `aria-modal=\"true\"`, locks page scroll, and keeps Tab and Shift+Tab\n * inside it while it is the topmost modal overlay. A Modal or Dialog opened\n * over it, even one rendered inside it, holds Tab until it closes. Without\n * an overlay the sidebar isn't modal and holds no Tab: on the page, Tab\n * moves in and out of it freely, and opened over a Modal, it leaves the\n * Modal holding Tab, and focus, while still taking Escape first. Whether\n * the sidebar takes focus is decided as it opens: changing this while it's\n * open moves the Tab trap, not focus. Default: true.\n */\n overlay?: boolean;\n /** Close sidebar when overlay is clicked. Default: true. */\n overlayClose?: boolean;\n /**\n * Close sidebar on Escape key. Only the topmost open overlay responds,\n * whichever Modal, Dialog, Sidebar or full-page Loading opened last, so\n * Escape closes one layer at a time. The sidebar marks the Escape it closes\n * on as used with `preventDefault()`, and a Toast waits until no overlay is\n * open. Turned off, a sidebar on top still keeps Escape from the layers\n * under it. A popup inside it, such as a Dropdown's menu or a date picker's\n * calendar, takes its own Escape first, and so does content that calls\n * `preventDefault()` on it. Default: true.\n */\n escapeClose?: boolean;\n /** Allow closing the sidebar. Default: true. */\n canCancel?: boolean;\n /**\n * Content to display in the sidebar. A popup in it that portals, such as a\n * Popover's or a date picker's panel with `appendToBody`, goes to the end\n * of the page and renders under an open sidebar. To show it above, wrap\n * the popup in a `ConfigProvider` whose `portalContainer` is an element of\n * your own outside the sidebar that stacks above it, such as one with\n * `position: relative` and a higher `z-index`. With an overlay, the\n * sidebar's `aria-modal` still hides the popup there from screen readers\n * that honor it.\n */\n children?: React.ReactNode;\n /**\n * Renders inline instead of using a portal. Without it, the sidebar renders\n * inline on the server and while hydrating, moving into the portal once the\n * client takes over, so hydration matches.\n */\n inline?: boolean;\n}\n\n/**\n * The `Sidebar` component provides a slide-out navigation panel that appears from the left or right side of the screen.\n *\n * @function\n * @param {SidebarProps} props - Props for the Sidebar component.\n * @param {React.Ref<HTMLElement>} ref - Forwarded ref to the sidebar element.\n * @returns {JSX.Element | null} The rendered sidebar component.\n *\n * @example\n * // Basic sidebar\n * const [isOpen, setIsOpen] = useState(false);\n * <Sidebar isOpen={isOpen} onClose={() => setIsOpen(false)}>\n * <Menu>...</Menu>\n * </Sidebar>\n *\n * @example\n * // Right-side sidebar with custom width\n * <Sidebar\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * position=\"right\"\n * width=\"320px\"\n * >\n * <div>Panel content</div>\n * </Sidebar>\n */\nconst SidebarComponent = forwardRef<HTMLElement, SidebarProps>(\n (\n {\n isOpen,\n onClose,\n position = 'left',\n width = '260px',\n isFullwidth,\n fullWidth,\n overlay = true,\n overlayClose = true,\n escapeClose = true,\n canCancel = true,\n children,\n inline = false,\n className,\n style,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n // A portal has no server-rendered counterpart, so the sidebar renders in\n // place on the server and while hydrating, and moves into its portal once\n // the client takes over, as Modal's `portal` does. An `inline` one stays\n // in place, so a change to the configured default moves nothing.\n const { isPortaled, defaultTarget } = usePortalProp(!inline);\n const sidebarRef = useRef<HTMLElement>(null);\n // Cleanup returned by a consumer's callback ref on attach, held until detach.\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const resolvedFullwidth = isFullwidth ?? fullWidth ?? false;\n\n // Close handler\n const handleClose = useCallback(() => {\n if (canCancel && onClose) {\n onClose();\n }\n }, [canCancel, onClose]);\n\n // Handle overlay click\n const handleOverlayClick = useCallback(() => {\n if (overlayClose) {\n handleClose();\n }\n }, [overlayClose, handleClose]);\n\n // Joins the stack of open overlays, so the sidebar answers Escape only\n // while it's the topmost overlay, and keeps it from those under it. It's\n // modal with an overlay: without one it leaves Tab to a modal overlay\n // under it.\n const isTopmost = useOverlayStack(isOpen, overlay);\n const closesOnEscape = escapeClose && canCancel && Boolean(onClose);\n\n // Escape closes it, on `window`, as in `Modal`, so everything inside the\n // sidebar has had the key first, and an Escape it used is left to it.\n useOverlayEscape(isOpen && closesOnEscape, isTopmost, handleClose);\n\n // Keep Tab inside while there's an overlay, as `Modal` does:\n // `aria-modal` hides the rest of the page from assistive technology, so\n // the keyboard order has to agree. Only while it's the topmost modal\n // overlay, so a Modal or Dialog opened over the sidebar, even one\n // rendered inside it, holds Tab instead until it closes, and a sidebar\n // without an overlay opened over it doesn't. On `window` for the same\n // reason as Escape: a trap inside, such as a portaled popup's, has had\n // the Tab first, and one it used is left where it put focus. It's the trap\n // `useFocusTrap` sets, so a Tab the browser still takes out, as Safari\n // does past links, is sent back in. It reads the aside as each key\n // arrives, so one remounted while the sidebar is open, by a new portal\n // target or by switching `inline`, stays trapped.\n useEffect(() => {\n if (!isOpen || !overlay) return undefined;\n return trapTab(\n () => sidebarRef.current,\n window,\n () => isTopmost('modal')\n );\n }, [isOpen, overlay, isTopmost]);\n\n // Lock the page's scrolling when sidebar is open. Ref-counted through the\n // shared helper so an overlapping Modal/Dialog/Loading doesn't unlock\n // underneath.\n useScrollLock(isOpen && overlay);\n\n // Move focus into the sidebar on open, to the first stop Tab wraps to or\n // the sidebar itself, and hand it back on close, as `Modal` does. Moving\n // into the portal after hydration, or to a different `defaultTarget`,\n // remounts the sidebar: focus is handed back from the old nodes and moved\n // into the new ones. Whether it takes focus is decided as it opens, so\n // `overlay` changing while it's open leaves focus where the user has it.\n // Without an overlay the sidebar holds no Tab, so with a modal overlay\n // open under it, it leaves focus alone: the first Tab would take focus\n // back there and leave the sidebar's other controls out of reach.\n useOverlayFocus(sidebarRef, isOpen, {\n modal: overlay,\n // In place it's `false`, which no portal target is.\n remountKey: isPortaled ? defaultTarget : false,\n });\n\n // Use combined ref\n const combinedRef = useCallback(\n (node: HTMLElement | null) => {\n (sidebarRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n if (typeof ref === 'function') {\n // React 19 lets a callback ref return a cleanup function and detaches by\n // running it instead of calling the ref with `null`; React 18 discards the\n // return value entirely. Returning it from here would be a React-19-only\n // contract, so we hold the cleanup and run it ourselves on detach — the\n // same shape as `Dropdown`, `Modal`, `Dialog`, `Toast` and `Carousel`.\n // The form controls that merge a forwarded ref still discard the cleanup\n // and detach with `ref(null)`, so this is not yet library-wide — grep\n // `typeof ref === 'function'` for the current split.\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) {\n consumerCleanup();\n } else {\n ref(null);\n }\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLElement | null>).current = node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const sidebarClasses = usePrefixedClassNames('sidebar', {\n 'is-active': isOpen,\n [`is-${position}`]: position,\n 'is-fullwidth': resolvedFullwidth,\n });\n const backgroundClass = usePrefixedClassNames('sidebar-background', {\n 'is-active': isOpen,\n });\n const contentClass = usePrefixedClassNames('sidebar-content');\n\n const combinedClasses = classNames(\n sidebarClasses,\n bulmaHelperClasses,\n className\n );\n\n // Custom style for width\n const sidebarStyle: React.CSSProperties = {\n ...style,\n '--bulma-sidebar-width': resolvedFullwidth ? '100%' : width,\n } as React.CSSProperties;\n\n const sidebarContent = (\n <>\n {overlay && (\n <div\n className={backgroundClass}\n onClick={handleOverlayClick}\n aria-hidden=\"true\"\n />\n )}\n <aside\n ref={combinedRef}\n className={combinedClasses}\n style={sidebarStyle}\n role=\"dialog\"\n aria-modal={overlay ? 'true' : undefined}\n aria-hidden={!isOpen}\n // React commits this before the effect that moves focus in runs, so\n // an opening sidebar is no longer inert by then.\n {...inertProps(!isOpen)}\n tabIndex={-1}\n {...rest}\n >\n <div className={contentClass}>{children}</div>\n </aside>\n </>\n );\n\n // In a portal for proper stacking.\n return <Portal disabled={!isPortaled}>{sidebarContent}</Portal>;\n }\n);\n\n// Sub-components\n\n/**\n * Props for the SidebarHeader component.\n */\nexport interface SidebarHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Header content. */\n children?: React.ReactNode;\n}\n\n/**\n * Container for the sidebar header.\n *\n * @function\n * @param {SidebarHeaderProps} props - Props for the SidebarHeader component.\n * @returns {JSX.Element} The rendered sidebar header.\n */\nexport const SidebarHeader: React.FC<SidebarHeaderProps> = ({\n className,\n children,\n ...props\n}) => {\n const headerClass = usePrefixedClassNames('sidebar-header');\n return (\n <div className={classNames(headerClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n/**\n * Props for the SidebarTitle component.\n */\nexport interface SidebarTitleProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Title content. */\n children?: React.ReactNode;\n}\n\n/**\n * Title text inside the header.\n *\n * @function\n * @param {SidebarTitleProps} props - Props for the SidebarTitle component.\n * @returns {JSX.Element} The rendered sidebar title.\n */\nexport const SidebarTitle: React.FC<SidebarTitleProps> = ({\n className,\n children,\n ...props\n}) => {\n const titleClass = usePrefixedClassNames('sidebar-title');\n return (\n <p className={classNames(titleClass, className)} {...props}>\n {children}\n </p>\n );\n};\n\n/**\n * Props for the SidebarClose component.\n * Extends standard button attributes.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a close button inside a form does not submit it. Pass `'submit'` or `'reset'` and yours is used; any other value, or a spread carrying `type: undefined`, renders `'button'`.\n * @extraProp {string} [aria-label='Close'] - Accessible name. Pass your own to replace it. An empty one, or a spread carrying `'aria-label': undefined`, keeps the default rather than leaving the button unnamed.\n */\nexport type SidebarCloseProps = React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * Close button for the sidebar.\n *\n * @function\n * @param {SidebarCloseProps} props - Props for the SidebarClose component.\n * @returns {JSX.Element} The rendered close button.\n */\nexport const SidebarClose: React.FC<SidebarCloseProps> = ({\n className,\n children,\n ...props\n}) => {\n const closeClass = usePrefixedClassNames('sidebar-close');\n return (\n <button\n className={classNames(closeClass, className)}\n {...props}\n // After the spread, reading through it: a key the spread carries with no\n // value would otherwise erase the default, leaving a nameless button\n // that submits the form around it. An empty label falls back too: the\n // button is drawn as an icon, so `''` would leave it unnamed. A caller's\n // own value still wins; `buttonType` says more.\n aria-label={props['aria-label'] || 'Close'}\n type={buttonType(props.type)}\n >\n {children}\n </button>\n );\n};\n\n/**\n * Props for the SidebarBody component.\n */\nexport interface SidebarBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Body content. */\n children?: React.ReactNode;\n}\n\n/**\n * Main content area of the sidebar.\n *\n * @function\n * @param {SidebarBodyProps} props - Props for the SidebarBody component.\n * @returns {JSX.Element} The rendered sidebar body.\n */\nexport const SidebarBody: React.FC<SidebarBodyProps> = ({\n className,\n children,\n ...props\n}) => {\n const bodyClass = usePrefixedClassNames('sidebar-body');\n return (\n <div className={classNames(bodyClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n/**\n * Props for the SidebarFooter component.\n */\nexport interface SidebarFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content. */\n children?: React.ReactNode;\n}\n\n/**\n * Footer area of the sidebar.\n *\n * @function\n * @param {SidebarFooterProps} props - Props for the SidebarFooter component.\n * @returns {JSX.Element} The rendered sidebar footer.\n */\nexport const SidebarFooter: React.FC<SidebarFooterProps> = ({\n className,\n children,\n ...props\n}) => {\n const footerClass = usePrefixedClassNames('sidebar-footer');\n return (\n <div className={classNames(footerClass, className)} {...props}>\n {children}\n </div>\n );\n};\n\n// Attach static subcomponents\nexport const Sidebar = withSubComponents(\n SidebarComponent,\n {\n Header: SidebarHeader,\n Title: SidebarTitle,\n Close: SidebarClose,\n Body: SidebarBody,\n Footer: SidebarFooter,\n },\n 'Sidebar'\n);\n\nexport default Sidebar;\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorInputBase.js","sources":["../../../src/form/ColorInputBase.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useFieldHelperClasses } from '../helpers/useFieldHelperClasses';\nimport { Icon } from '../elements/Icon';\nimport { ColorSwatch } from '../elements/ColorSwatch';\nimport {\n ColorPickerAlphaSlider,\n ColorPickerArea,\n ColorPickerHueSlider,\n ColorPickerSwatches,\n type ColorFormat,\n type ColorPickerLabels,\n type ColorPickerSwatch,\n} from './ColorPicker';\nimport { formatColor, parseColor } from './_colorInternals/colorMath';\nimport {\n BLACK,\n ColorPickerContext,\n keepingChannels,\n mergeColorLabels,\n useColorPicker,\n} from './_colorInternals/pickerState';\nimport { EyeDropperButton } from './_colorInternals/EyeDropperButton';\nimport { PickerPopover } from './_pickerInternals/PickerPopover';\nimport {\n isPopoverToggleKey,\n type PickerPosition,\n} from './_pickerInternals/pickerTypes';\nimport { usePickerLocaleScope } from './_pickerInternals/useLocaleDefaults';\nimport { useControlLoading } from './controlLoading';\nimport { useFieldLabelTarget, useFieldsetDisabled } from './FormContext';\n\n/**\n * Props for the raw ColorInput base. Use the higher-level `ColorInput` for\n * Field/Control composition; `ColorInputBase` is the field and its popover\n * only.\n *\n * @helperProps Helper props go on the `.colorinput` `<div>`, with\n * `className`, except that the background helpers go on the text `<input>`,\n * and the text helpers on both, since Bulma's `.input` sets its own\n * background and font, and the popover inside the `<div>` takes the text\n * ones. The other attributes go on the `<input>`.\n * @extraProp {string} [name] - Form field name. The field submits the text it shows, the value in `format`, or nothing when it's empty.\n * @extraProp {boolean} [required=false] - Marks the field required, so an empty one fails the form's constraint validation.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Forwarded to the text `<input>`.\n */\nexport interface ColorInputBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'size'\n | 'color'\n | 'type'\n | 'popover'\n >,\n Omit<BulmaClassesProps, 'color'> {\n /**\n * The color, controlled, as a CSS color the picker reads (hex, `rgb()`,\n * `hsl()` or a color name), or `''` for none.\n */\n value?: string;\n /** The color to start with, uncontrolled; empty without one. */\n defaultValue?: string;\n /**\n * Called with the color, in `format`, as it changes: on every step of a\n * drag in the panel, on a key or a swatch, and when typed text is\n * committed. Clearing the field calls it with `''`.\n */\n onChange?: (value: string) => void;\n /**\n * Called with the color, in `format`, once a change is done: when a drag\n * ends, and with `onChange` for everything else. The place to save it.\n */\n onChangeEnd?: (value: string) => void;\n /**\n * How the value is written: `'hsl'` (`hsl(171, 100%, 41%)`), `'hex'` or\n * `'rgb'`, with alpha as `hsla()`, `#rrggbbaa` and `rgba()`. Typed text in\n * any of them is written back in this one.\n * @defaultValue 'hsl'\n */\n format?: ColorFormat;\n /** Adds an alpha slider to the panel and writes the alpha into the value. */\n alpha?: boolean;\n /**\n * Preset colors in the panel: a list of CSS colors, each a string or\n * `{ color, label }`, or `\"bulma\"` for the page's theme colors.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n /**\n * Adds a button to the panel that picks a color from anywhere on the\n * screen, where the browser has the EyeDropper API.\n */\n eyeDropper?: boolean;\n /** Fired when the panel opens. */\n onOpen?: () => void;\n /** Fired when the panel closes. */\n onClose?: () => void;\n /**\n * Opens the panel when the field takes focus, and moves focus into it.\n * Off by default, since typing a value is the quick way in and the\n * launcher, a click on the swatch or Alt+ArrowDown open it.\n */\n openOnFocus?: boolean;\n /** Closes the panel once a swatch is chosen. */\n closeOnSwatchClick?: boolean;\n /**\n * Where the panel opens against the field. Left out, it opens below and\n * lines up with the field's start edge, which is its right edge when the\n * picker reads right to left. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges either way.\n * @defaultValue 'bottom-left'\n */\n position?: PickerPosition;\n /**\n * Renders the panel through a portal, into the `portalContainer` a\n * `ConfigProvider` sets, else the `Modal`, `Dialog` or `Command.Dialog` it's\n * in, else `document.body`.\n */\n appendToBody?: boolean;\n /** Bulma color modifier for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** The field's size. */\n size?: 'small' | 'medium' | 'large';\n /** Renders the field with rounded ends. */\n isRounded?: boolean;\n /** Disables the field and its panel. A disabled `Fieldset` does too. */\n disabled?: boolean;\n /** Makes the field read-only, with no panel. */\n readOnly?: boolean;\n /** Text shown while the field is empty. */\n placeholder?: string;\n /**\n * Shows the launcher on the field's end that toggles the panel. Hidden by\n * default while a `Control` it sits in shows its `isLoading` spinner,\n * which shares that edge.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** The launcher's glyph. */\n triggerIconName?: string;\n /** The strings it says, each with an English default. */\n labels?: ColorPickerLabels;\n}\n\n/**\n * The raw ColorInput: a text field with a swatch and a launcher that opens a color picker in a popover, without Field/Control wrapping.\n *\n * Use `ColorInput` for the convenience wrapper.\n *\n * @function\n * @param {ColorInputBaseProps} props - Props for ColorInputBase.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the text `<input>`.\n * @returns {JSX.Element} The rendered field.\n */\nexport const ColorInputBase = forwardRef<HTMLInputElement, ColorInputBaseProps>(\n (props, ref) => {\n const {\n value: controlledValue,\n defaultValue,\n onChange,\n onChangeEnd,\n format = 'hsl',\n alpha = false,\n swatches,\n eyeDropper = false,\n onOpen,\n onClose,\n openOnFocus = false,\n closeOnSwatchClick = false,\n position,\n appendToBody = false,\n color,\n size,\n isRounded,\n disabled: disabledProp,\n readOnly,\n placeholder,\n triggerIcon: triggerIconProp,\n triggerIconName = 'chevron-down',\n labels,\n className,\n id: idProp,\n onFocus,\n onBlur,\n onKeyDown,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n const id = useFieldLabelTarget(idProp, true);\n const localeScope = usePickerLocaleScope(undefined, props.dir);\n const controlLoading = useControlLoading();\n const triggerIcon = triggerIconProp ?? !controlLoading;\n const t = mergeColorLabels(labels);\n // The field takes the background and text helpers, since Bulma's `.input`\n // sets its own background and font. The container keeps the rest, and the\n // text helpers too where a popover inside it takes them.\n const {\n backgroundClasses,\n textClasses,\n otherClasses,\n rest: cleanRest,\n } = useFieldHelperClasses(rest);\n\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? '');\n const value = isControlled ? controlledValue : internalValue;\n // What's been typed and not yet committed, or null while the field\n // shows the value.\n const [draft, setDraft] = useState<string | null>(null);\n // The last color it held, which the panel shows while the field is\n // empty, so clearing the field doesn't send the picker back to black.\n const [remembered, setRemembered] = useState(value);\n if (value && value !== remembered) setRemembered(value);\n\n const [open, setOpenState] = useState(false);\n const canOpen = !disabled && !readOnly;\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n // Focus a closing panel hands back to the field opens nothing.\n const returningRef = useRef(false);\n const reactId = useId();\n const popoverId = id ? `${id}-popover` : `colorinput-${reactId}`;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (next === open) return;\n if (!next) returningRef.current = true;\n setOpenState(next);\n if (next) onOpen?.();\n else onClose?.();\n },\n [open, onOpen, onClose]\n );\n\n // Cleared once the close has handed focus back, or hasn't.\n useEffect(() => {\n if (!open) returningRef.current = false;\n }, [open]);\n\n const setValue = (next: string, end = true) => {\n if (!isControlled) setInternalValue(next);\n if (next !== value) onChange?.(next);\n if (end) onChangeEnd?.(next);\n };\n\n // The picker in the panel, controlled by this field's value.\n const picker = useColorPicker({\n value: value || remembered || formatColor(BLACK, format, alpha),\n defaultValue: undefined,\n onChange: next => setValue(next, false),\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n // Empty, the panel shows the last color the field held, or black, and\n // choosing that same color still fills the field.\n empty: value === '',\n });\n\n const commit = () => {\n if (draft === null) return;\n const typed = draft.trim();\n setDraft(null);\n if (typed === '') {\n if (value !== '') setValue('');\n return;\n }\n const parsed = parseColor(typed);\n if (!parsed) return;\n // A gray typed as hex, rgb() or a name keeps the panel's hue, as the\n // picker's own field does; one typed as hsl() names its own.\n const kept = keepingChannels(parsed, picker.color, typed);\n setValue(formatColor(alpha ? kept : { ...kept, a: 1 }, format, alpha));\n };\n const invalid = draft !== null && draft.trim() !== '' && !parseColor(draft);\n // The value as the field writes it: in `format`, however it was given.\n const parsedValue = parseColor(value);\n const valueText = parsedValue\n ? formatColor(\n alpha ? parsedValue : { ...parsedValue, a: 1 },\n format,\n alpha\n )\n : value;\n // What the swatch shows: a readable draft as it's typed, else the value.\n const shown = draft !== null && !invalid ? draft.trim() : value;\n\n const inputClass = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': !!isRounded,\n 'is-danger': invalid && !color,\n });\n const containerClass = usePrefixedClassNames('colorinput', {\n 'has-trigger': triggerIcon,\n });\n const swatchClass = usePrefixedClassNames('colorinput-swatch');\n const triggerClass = usePrefixedClassNames('colorinput-trigger');\n const panelClass = usePrefixedClassNames('color-picker');\n const eyeDropperClass = usePrefixedClassNames('colorinput-eyedropper');\n\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref]\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (isPopoverToggleKey(event) && event.key === 'ArrowDown') {\n event.preventDefault();\n if (canOpen) setOpen(true);\n } else if (draft !== null && event.key === 'Enter') {\n // Commits rather than submitting a form; an unreadable value stays\n // to be fixed.\n event.preventDefault();\n if (!invalid) commit();\n } else if (draft !== null && event.key === 'Escape') {\n // Puts the value back, and keeps a Modal around it open.\n event.preventDefault();\n event.stopPropagation();\n setDraft(null);\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n const returning = returningRef.current;\n returningRef.current = false;\n if (openOnFocus && canOpen && !returning) setOpen(true);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n onBlur?.(event);\n commit();\n };\n\n const popupAttrs = {\n 'aria-haspopup': 'dialog',\n 'aria-controls': popoverId,\n 'aria-expanded': open,\n } as const;\n\n return (\n <div\n ref={containerRef}\n className={classNames(\n containerClass,\n otherClasses,\n textClasses,\n className\n )}\n {...localeScope.rootAttrs}\n >\n <input\n {...cleanRest}\n ref={combinedRef}\n type=\"text\"\n role=\"combobox\"\n {...popupAttrs}\n autoComplete=\"off\"\n spellCheck={false}\n autoCapitalize=\"off\"\n className={classNames(inputClass, textClasses, backgroundClasses)}\n value={draft ?? valueText}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={invalid || cleanRest['aria-invalid'] || undefined}\n id={id}\n onChange={event => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n {/* For the pointer: the launcher does the same from the keyboard. */}\n <button\n type=\"button\"\n className={swatchClass}\n tabIndex={-1}\n aria-hidden=\"true\"\n disabled={!canOpen}\n onMouseDown={event => event.preventDefault()}\n onClick={() => setOpen(true)}\n >\n <ColorSwatch color={shown || 'transparent'} aria-hidden=\"true\" />\n </button>\n {triggerIcon && (\n <button\n type=\"button\"\n className={triggerClass}\n {...popupAttrs}\n aria-label={t.chooseColor}\n disabled={!canOpen}\n onClick={() => setOpen(!open)}\n >\n <Icon name={triggerIconName} size={size} />\n </button>\n )}\n <PickerPopover\n localeScope={localeScope.panel}\n isOpen={open}\n onClose={() => setOpen(false)}\n anchorRef={containerRef}\n position={position}\n appendToBody={appendToBody}\n ariaLabel={t.chooseColor}\n id={popoverId}\n restoreFocusRef={inputRef}\n >\n <ColorPickerContext.Provider value={picker}>\n <div className={panelClass}>\n <ColorPickerArea />\n <ColorPickerHueSlider />\n {alpha && <ColorPickerAlphaSlider />}\n {swatches && (\n <ColorPickerSwatches\n // A click on a swatch, or Enter or Space on one, closes\n // the panel when asked to; the arrows only choose.\n onClick={event => {\n const target = event.target as Element;\n if (\n closeOnSwatchClick &&\n target.closest('[role=\"radio\"]')\n ) {\n setOpen(false);\n }\n }}\n />\n )}\n <EyeDropperButton className={eyeDropperClass} />\n </div>\n </ColorPickerContext.Provider>\n </PickerPopover>\n </div>\n );\n }\n);\n\nColorInputBase.displayName = 'ColorInputBase';\n\nexport default ColorInputBase;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ColorInputBase.js","sources":["../../../src/form/ColorInputBase.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useFieldHelperClasses } from '../helpers/useFieldHelperClasses';\nimport { Icon } from '../elements/Icon';\nimport { ColorSwatch } from '../elements/ColorSwatch';\nimport {\n ColorPickerAlphaSlider,\n ColorPickerArea,\n ColorPickerHueSlider,\n ColorPickerSwatches,\n type ColorFormat,\n type ColorPickerLabels,\n type ColorPickerSwatch,\n} from './ColorPicker';\nimport { formatColor, parseColor } from './_colorInternals/colorMath';\nimport {\n BLACK,\n ColorPickerContext,\n keepingChannels,\n mergeColorLabels,\n useColorPicker,\n} from './_colorInternals/pickerState';\nimport { EyeDropperButton } from './_colorInternals/EyeDropperButton';\nimport { PickerPopover } from './_pickerInternals/PickerPopover';\nimport {\n isPopoverToggleKey,\n type PickerPosition,\n} from './_pickerInternals/pickerTypes';\nimport { usePickerLocaleScope } from './_pickerInternals/useLocaleDefaults';\nimport { useControlLoading } from './controlLoading';\nimport { useFieldLabelTarget, useFieldsetDisabled } from './FormContext';\n\n/**\n * Props for the raw ColorInput base. Use the higher-level `ColorInput` for\n * Field/Control composition; `ColorInputBase` is the field and its popover\n * only.\n *\n * @helperProps Helper props go on the `.colorinput` `<div>`, with\n * `className`, except that the background helpers go on the text `<input>`,\n * and the text helpers on both, since Bulma's `.input` sets its own\n * background and font, and the popover inside the `<div>` takes the text\n * ones. The other attributes go on the `<input>`.\n * @extraProp {string} [name] - Form field name. The field submits the text it shows, the value in `format`, or nothing when it's empty.\n * @extraProp {boolean} [required=false] - Marks the field required, so an empty one fails the form's constraint validation.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Forwarded to the text `<input>`.\n */\nexport interface ColorInputBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'size'\n | 'color'\n | 'type'\n | 'popover'\n >,\n Omit<BulmaClassesProps, 'color'> {\n /**\n * The color, controlled, as a CSS color the picker reads (hex, `rgb()`,\n * `hsl()` or a color name), or `''` for none.\n */\n value?: string;\n /** The color to start with, uncontrolled; empty without one. */\n defaultValue?: string;\n /**\n * Called with the color, in `format`, as it changes: on every step of a\n * drag in the panel, on a key or a swatch, and when typed text is\n * committed. Clearing the field calls it with `''`.\n */\n onChange?: (value: string) => void;\n /**\n * Called with the color, in `format`, once a change is done: when a drag\n * ends, and with `onChange` for everything else. The place to save it.\n */\n onChangeEnd?: (value: string) => void;\n /**\n * How the value is written: `'hsl'` (`hsl(171, 100%, 41%)`), `'hex'` or\n * `'rgb'`, with alpha as `hsla()`, `#rrggbbaa` and `rgba()`. Typed text in\n * any of them is written back in this one.\n * @defaultValue 'hsl'\n */\n format?: ColorFormat;\n /** Adds an alpha slider to the panel and writes the alpha into the value. */\n alpha?: boolean;\n /**\n * Preset colors in the panel: a list of CSS colors, each a string or\n * `{ color, label }`, or `\"bulma\"` for the page's theme colors.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n /**\n * Adds a button to the panel that picks a color from anywhere on the\n * screen, where the browser has the EyeDropper API.\n */\n eyeDropper?: boolean;\n /** Fired when the panel opens. */\n onOpen?: () => void;\n /** Fired when the panel closes. */\n onClose?: () => void;\n /**\n * Opens the panel when the field takes focus, and moves focus into it.\n * Off by default, since typing a value is the quick way in and the\n * launcher, a click on the swatch or Alt+ArrowDown open it.\n */\n openOnFocus?: boolean;\n /** Closes the panel once a swatch is chosen. */\n closeOnSwatchClick?: boolean;\n /**\n * Where the panel opens against the field. Left out, it opens below and\n * lines up with the field's start edge, which is its right edge when the\n * picker reads right to left. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges either way.\n * @defaultValue 'bottom-left'\n */\n position?: PickerPosition;\n /**\n * Renders the panel through a portal, into the `portalContainer` a\n * `ConfigProvider` sets, else the overlay it's in that takes its popups,\n * such as a `Modal`, else `document.body`.\n */\n appendToBody?: boolean;\n /** Bulma color modifier for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** The field's size. */\n size?: 'small' | 'medium' | 'large';\n /** Renders the field with rounded ends. */\n isRounded?: boolean;\n /** Disables the field and its panel. A disabled `Fieldset` does too. */\n disabled?: boolean;\n /** Makes the field read-only, with no panel. */\n readOnly?: boolean;\n /** Text shown while the field is empty. */\n placeholder?: string;\n /**\n * Shows the launcher on the field's end that toggles the panel. Hidden by\n * default while a `Control` it sits in shows its `isLoading` spinner,\n * which shares that edge.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** The launcher's glyph. */\n triggerIconName?: string;\n /** The strings it says, each with an English default. */\n labels?: ColorPickerLabels;\n}\n\n/**\n * The raw ColorInput: a text field with a swatch and a launcher that opens a color picker in a popover, without Field/Control wrapping.\n *\n * Use `ColorInput` for the convenience wrapper.\n *\n * @function\n * @param {ColorInputBaseProps} props - Props for ColorInputBase.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the text `<input>`.\n * @returns {JSX.Element} The rendered field.\n */\nexport const ColorInputBase = forwardRef<HTMLInputElement, ColorInputBaseProps>(\n (props, ref) => {\n const {\n value: controlledValue,\n defaultValue,\n onChange,\n onChangeEnd,\n format = 'hsl',\n alpha = false,\n swatches,\n eyeDropper = false,\n onOpen,\n onClose,\n openOnFocus = false,\n closeOnSwatchClick = false,\n position,\n appendToBody = false,\n color,\n size,\n isRounded,\n disabled: disabledProp,\n readOnly,\n placeholder,\n triggerIcon: triggerIconProp,\n triggerIconName = 'chevron-down',\n labels,\n className,\n id: idProp,\n onFocus,\n onBlur,\n onKeyDown,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n const id = useFieldLabelTarget(idProp, true);\n const localeScope = usePickerLocaleScope(undefined, props.dir);\n const controlLoading = useControlLoading();\n const triggerIcon = triggerIconProp ?? !controlLoading;\n const t = mergeColorLabels(labels);\n // The field takes the background and text helpers, since Bulma's `.input`\n // sets its own background and font. The container keeps the rest, and the\n // text helpers too where a popover inside it takes them.\n const {\n backgroundClasses,\n textClasses,\n otherClasses,\n rest: cleanRest,\n } = useFieldHelperClasses(rest);\n\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? '');\n const value = isControlled ? controlledValue : internalValue;\n // What's been typed and not yet committed, or null while the field\n // shows the value.\n const [draft, setDraft] = useState<string | null>(null);\n // The last color it held, which the panel shows while the field is\n // empty, so clearing the field doesn't send the picker back to black.\n const [remembered, setRemembered] = useState(value);\n if (value && value !== remembered) setRemembered(value);\n\n const [open, setOpenState] = useState(false);\n const canOpen = !disabled && !readOnly;\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n // Focus a closing panel hands back to the field opens nothing.\n const returningRef = useRef(false);\n const reactId = useId();\n const popoverId = id ? `${id}-popover` : `colorinput-${reactId}`;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (next === open) return;\n if (!next) returningRef.current = true;\n setOpenState(next);\n if (next) onOpen?.();\n else onClose?.();\n },\n [open, onOpen, onClose]\n );\n\n // Cleared once the close has handed focus back, or hasn't.\n useEffect(() => {\n if (!open) returningRef.current = false;\n }, [open]);\n\n const setValue = (next: string, end = true) => {\n if (!isControlled) setInternalValue(next);\n if (next !== value) onChange?.(next);\n if (end) onChangeEnd?.(next);\n };\n\n // The picker in the panel, controlled by this field's value.\n const picker = useColorPicker({\n value: value || remembered || formatColor(BLACK, format, alpha),\n defaultValue: undefined,\n onChange: next => setValue(next, false),\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n // Empty, the panel shows the last color the field held, or black, and\n // choosing that same color still fills the field.\n empty: value === '',\n });\n\n const commit = () => {\n if (draft === null) return;\n const typed = draft.trim();\n setDraft(null);\n if (typed === '') {\n if (value !== '') setValue('');\n return;\n }\n const parsed = parseColor(typed);\n if (!parsed) return;\n // A gray typed as hex, rgb() or a name keeps the panel's hue, as the\n // picker's own field does; one typed as hsl() names its own.\n const kept = keepingChannels(parsed, picker.color, typed);\n setValue(formatColor(alpha ? kept : { ...kept, a: 1 }, format, alpha));\n };\n const invalid = draft !== null && draft.trim() !== '' && !parseColor(draft);\n // The value as the field writes it: in `format`, however it was given.\n const parsedValue = parseColor(value);\n const valueText = parsedValue\n ? formatColor(\n alpha ? parsedValue : { ...parsedValue, a: 1 },\n format,\n alpha\n )\n : value;\n // What the swatch shows: a readable draft as it's typed, else the value.\n const shown = draft !== null && !invalid ? draft.trim() : value;\n\n const inputClass = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': !!isRounded,\n 'is-danger': invalid && !color,\n });\n const containerClass = usePrefixedClassNames('colorinput', {\n 'has-trigger': triggerIcon,\n });\n const swatchClass = usePrefixedClassNames('colorinput-swatch');\n const triggerClass = usePrefixedClassNames('colorinput-trigger');\n const panelClass = usePrefixedClassNames('color-picker');\n const eyeDropperClass = usePrefixedClassNames('colorinput-eyedropper');\n\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref]\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (isPopoverToggleKey(event) && event.key === 'ArrowDown') {\n event.preventDefault();\n if (canOpen) setOpen(true);\n } else if (draft !== null && event.key === 'Enter') {\n // Commits rather than submitting a form; an unreadable value stays\n // to be fixed.\n event.preventDefault();\n if (!invalid) commit();\n } else if (draft !== null && event.key === 'Escape') {\n // Puts the value back, and keeps a Modal around it open.\n event.preventDefault();\n event.stopPropagation();\n setDraft(null);\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n const returning = returningRef.current;\n returningRef.current = false;\n if (openOnFocus && canOpen && !returning) setOpen(true);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n onBlur?.(event);\n commit();\n };\n\n const popupAttrs = {\n 'aria-haspopup': 'dialog',\n 'aria-controls': popoverId,\n 'aria-expanded': open,\n } as const;\n\n return (\n <div\n ref={containerRef}\n className={classNames(\n containerClass,\n otherClasses,\n textClasses,\n className\n )}\n {...localeScope.rootAttrs}\n >\n <input\n {...cleanRest}\n ref={combinedRef}\n type=\"text\"\n role=\"combobox\"\n {...popupAttrs}\n autoComplete=\"off\"\n spellCheck={false}\n autoCapitalize=\"off\"\n className={classNames(inputClass, textClasses, backgroundClasses)}\n value={draft ?? valueText}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={invalid || cleanRest['aria-invalid'] || undefined}\n id={id}\n onChange={event => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n {/* For the pointer: the launcher does the same from the keyboard. */}\n <button\n type=\"button\"\n className={swatchClass}\n tabIndex={-1}\n aria-hidden=\"true\"\n disabled={!canOpen}\n onMouseDown={event => event.preventDefault()}\n onClick={() => setOpen(true)}\n >\n <ColorSwatch color={shown || 'transparent'} aria-hidden=\"true\" />\n </button>\n {triggerIcon && (\n <button\n type=\"button\"\n className={triggerClass}\n {...popupAttrs}\n aria-label={t.chooseColor}\n disabled={!canOpen}\n onClick={() => setOpen(!open)}\n >\n <Icon name={triggerIconName} size={size} />\n </button>\n )}\n <PickerPopover\n localeScope={localeScope.panel}\n isOpen={open}\n onClose={() => setOpen(false)}\n anchorRef={containerRef}\n position={position}\n appendToBody={appendToBody}\n ariaLabel={t.chooseColor}\n id={popoverId}\n restoreFocusRef={inputRef}\n >\n <ColorPickerContext.Provider value={picker}>\n <div className={panelClass}>\n <ColorPickerArea />\n <ColorPickerHueSlider />\n {alpha && <ColorPickerAlphaSlider />}\n {swatches && (\n <ColorPickerSwatches\n // A click on a swatch, or Enter or Space on one, closes\n // the panel when asked to; the arrows only choose.\n onClick={event => {\n const target = event.target as Element;\n if (\n closeOnSwatchClick &&\n target.closest('[role=\"radio\"]')\n ) {\n setOpen(false);\n }\n }}\n />\n )}\n <EyeDropperButton className={eyeDropperClass} />\n </div>\n </ColorPickerContext.Provider>\n </PickerPopover>\n </div>\n );\n }\n);\n\nColorInputBase.displayName = 'ColorInputBase';\n\nexport default ColorInputBase;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|