@allxsmith/bestax-bulma 5.59.0 → 5.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/Affix.js +46 -0
- package/dist/esm/components/Affix.js.map +1 -0
- package/dist/esm/components/Carousel.js +3 -43
- package/dist/esm/components/Carousel.js.map +1 -1
- package/dist/esm/components/Command.js +3 -3
- package/dist/esm/components/Dialog.js +2 -6
- package/dist/esm/components/Dialog.js.map +1 -1
- package/dist/esm/components/Modal.js +12 -24
- package/dist/esm/components/Modal.js.map +1 -1
- package/dist/esm/components/Navbar.js +3 -1
- package/dist/esm/components/Navbar.js.map +1 -1
- package/dist/esm/components/Popover.js +7 -27
- package/dist/esm/components/Popover.js.map +1 -1
- package/dist/esm/components/Sidebar.js +17 -58
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/form/ColorPicker.js +4 -4
- package/dist/esm/form/ColorPicker.js.map +1 -1
- package/dist/esm/form/Combobox.js +3 -3
- package/dist/esm/helpers/overlayStack.js +33 -1
- package/dist/esm/helpers/overlayStack.js.map +1 -1
- package/dist/esm/helpers/portal.js +28 -1
- package/dist/esm/helpers/portal.js.map +1 -1
- package/dist/esm/helpers/useBulmaViewport.js +82 -0
- package/dist/esm/helpers/useBulmaViewport.js.map +1 -0
- package/dist/esm/helpers/useInertSiblings.js +7 -3
- package/dist/esm/helpers/useInertSiblings.js.map +1 -1
- package/dist/esm/helpers/useOutsidePress.js +53 -0
- package/dist/esm/helpers/useOutsidePress.js.map +1 -0
- package/dist/esm/helpers/useOverlayFocus.js +74 -0
- package/dist/esm/helpers/useOverlayFocus.js.map +1 -0
- package/dist/esm/layout/AppFrame.js +438 -0
- package/dist/esm/layout/AppFrame.js.map +1 -0
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +754 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Affix.d.ts +67 -0
- package/dist/types/components/Navbar.d.ts +4 -3
- package/dist/types/helpers/overlayStack.d.ts +17 -0
- package/dist/types/helpers/portal.d.ts +42 -0
- package/dist/types/helpers/useBulmaViewport.d.ts +34 -0
- package/dist/types/helpers/useInertSiblings.d.ts +4 -1
- package/dist/types/helpers/useOutsidePress.d.ts +24 -0
- package/dist/types/helpers/useOverlayFocus.d.ts +44 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/layout/AppFrame.d.ts +306 -0
- package/dist/types-cjs/components/Affix.d.ts +67 -0
- package/dist/types-cjs/components/Navbar.d.ts +4 -3
- package/dist/types-cjs/helpers/overlayStack.d.ts +17 -0
- package/dist/types-cjs/helpers/portal.d.ts +42 -0
- package/dist/types-cjs/helpers/useBulmaViewport.d.ts +34 -0
- package/dist/types-cjs/helpers/useInertSiblings.d.ts +4 -1
- package/dist/types-cjs/helpers/useOutsidePress.d.ts +24 -0
- package/dist/types-cjs/helpers/useOverlayFocus.d.ts +44 -0
- package/dist/types-cjs/index.d.ts +2 -0
- package/dist/types-cjs/layout/AppFrame.d.ts +306 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/components/_affix.scss +74 -0
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/layout/_appframe.scss +306 -0
- package/src/scss/layout/_index.scss +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPicker.js","sources":["../../../src/form/ColorPicker.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { ColorSwatch } from '../elements/ColorSwatch';\nimport {\n ColorFormat,\n Hsva,\n formatColor,\n hsvaToRgba,\n parseColor,\n prefersDarkInk,\n sameColor,\n} from './_colorInternals/colorMath';\nimport {\n ColorPickerContext,\n keepingChannels,\n standalone,\n useColorPicker,\n usePicker,\n} from './_colorInternals/pickerState';\nimport { EyeDropperButton } from './_colorInternals/EyeDropperButton';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n useFieldsetDisabled,\n} from './FormContext';\nimport { useAutoLabelledBy } from './useAutoLabelId';\n\nexport type { ColorFormat } from './_colorInternals/colorMath';\n\n/**\n * A preset color for a picker's swatches: a CSS color, or a CSS color with\n * a name. The name labels the swatch for a screen reader and shows as its\n * tooltip; without one, the color as written does.\n */\nexport type ColorPickerSwatch = string | { color: string; label?: string };\n\n/**\n * The strings a color picker says, each with an English default. A key\n * left out, or set to an empty string, keeps its default.\n */\nexport interface ColorPickerLabels {\n /**\n * Names the saturation and brightness square.\n * @defaultValue 'Saturation and brightness'\n */\n area?: string;\n /**\n * What a screen reader calls the square in place of \"slider\".\n * @defaultValue '2D slider'\n */\n areaRoleDescription?: string;\n /**\n * The square's horizontal channel, in its value text.\n * @defaultValue 'Saturation'\n */\n saturation?: string;\n /**\n * The square's vertical channel, in its value text.\n * @defaultValue 'Brightness'\n */\n brightness?: string;\n /**\n * Names the hue slider.\n * @defaultValue 'Hue'\n */\n hue?: string;\n /**\n * Names the alpha slider.\n * @defaultValue 'Alpha'\n */\n alpha?: string;\n /**\n * The unit after the hue's number in its value text, \"171 degrees\".\n * Inside a `LocaleProvider` with a `locale`, that locale writes the number\n * and its unit, and this isn't used.\n * @defaultValue 'degrees'\n */\n degrees?: string;\n /**\n * Names the field that shows the value as text.\n * @defaultValue 'Color value'\n */\n value?: string;\n /**\n * Names the group of swatches.\n * @defaultValue 'Swatches'\n */\n swatches?: string;\n /**\n * Names the eye dropper button.\n * @defaultValue 'Pick a color from the screen'\n */\n eyeDropper?: string;\n /**\n * Names `ColorInput`'s launcher and the panel it opens.\n * @defaultValue 'Choose color'\n */\n chooseColor?: string;\n}\n\n// The theme colors `swatches=\"bulma\"` shows, read off the page.\nconst BULMA_SWATCHES: ReadonlyArray<{ color: string; label: string }> = [\n { color: 'var(--bulma-primary)', label: 'Primary' },\n { color: 'var(--bulma-link)', label: 'Link' },\n { color: 'var(--bulma-info)', label: 'Info' },\n { color: 'var(--bulma-success)', label: 'Success' },\n { color: 'var(--bulma-warning)', label: 'Warning' },\n { color: 'var(--bulma-danger)', label: 'Danger' },\n];\n\nconst clamp = (value: number, low: number, high: number) =>\n Math.min(Math.max(value, low), high);\n\n/** Whether the element is laid out right to left. */\nconst isRtl = (element: Element | null) =>\n !!element && getComputedStyle(element).direction === 'rtl';\n\n/** Where a pointer is across an element, from 0 to 1 each way. */\nconst pointIn = (element: HTMLElement, event: React.PointerEvent) => {\n const rect = element.getBoundingClientRect();\n const across =\n rect.width > 0 ? clamp((event.clientX - rect.left) / rect.width, 0, 1) : 0;\n const down =\n rect.height > 0 ? clamp((event.clientY - rect.top) / rect.height, 0, 1) : 0;\n return { x: isRtl(element) ? 1 - across : across, y: down };\n};\n\n/** The color's red, green and blue, rounded, as a CSS `rgb()` takes them. */\nconst rgbChannels = (color: Hsva) => {\n const { r, g, b } = hsvaToRgba(color);\n return `${Math.round(r)} ${Math.round(g)} ${Math.round(b)}`;\n};\n\n/** Whether a press should start a drag: any touch or pen, a mouse's main button. */\nconst startsDrag = (event: React.PointerEvent) =>\n event.pointerType !== 'mouse' || event.button === 0;\n\n/** Hands a node to a forwarded ref and to one of the part's own. */\nfunction setRefs<T>(\n node: T | null,\n own: React.MutableRefObject<T | null>,\n forwarded: React.ForwardedRef<T>\n) {\n own.current = node;\n if (typeof forwarded === 'function') forwarded(node);\n else if (forwarded) forwarded.current = node;\n}\n\n// ---------------------------------------------------------------------------\n// ColorPicker.Area\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.Area. The helper props, the other attributes and the\n * `ref` land on the square's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the square's `<div>`.\n */\nexport interface ColorPickerAreaProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n}\n\n/**\n * The saturation and brightness square, operated by pointer or by keyboard as one 2D slider.\n *\n * @function\n * @param {ColorPickerAreaProps} props - Props for ColorPicker.Area.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the square's `<div>`.\n * @returns {JSX.Element | null} The square, or nothing outside a ColorPicker.\n */\nexport const ColorPickerArea = forwardRef<HTMLDivElement, ColorPickerAreaProps>(\n ({ className, style, ...props }, ref) => {\n const picker = usePicker('Area');\n const live = picker ?? standalone;\n const { color, change, end, disabled, labels, touch, percent } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n const rootRef = useRef<HTMLDivElement | null>(null);\n const xRef = useRef<HTMLInputElement>(null);\n const yRef = useRef<HTMLInputElement>(null);\n // The axis whose input holds the tab stop: the one focused or moved last.\n const [axis, setAxis] = useState<'x' | 'y'>('x');\n // Once a key has moved the square, both inputs are exposed until focus\n // leaves it, so the one that moved can be read.\n const [keyed, setKeyed] = useState(false);\n const draggingRef = useRef(false);\n\n const areaClass = usePrefixedClassNames('color-area', {\n 'is-disabled': disabled,\n });\n const thumbClass = usePrefixedClassNames('color-area-thumb');\n const inputClass = usePrefixedClassNames('color-area-input');\n\n const s = Math.round(color.s);\n const v = Math.round(color.v);\n const saturationText = `${labels.saturation} ${percent(s)}`;\n const brightnessText = `${labels.brightness} ${percent(v)}`;\n\n const focusAxis = (which: 'x' | 'y') =>\n (which === 'x' ? xRef : yRef).current?.focus({ preventScroll: true });\n // The axis a key moved to, focused once the render that shows its input\n // is on the page, so it's no longer aria-hidden as it takes focus.\n const focusNextRef = useRef<'x' | 'y' | null>(null);\n useClientLayoutEffect(() => {\n if (!focusNextRef.current) return;\n focusAxis(focusNextRef.current);\n focusNextRef.current = null;\n });\n\n const moveTo = (event: React.PointerEvent<HTMLDivElement>) => {\n const { x, y } = pointIn(event.currentTarget, event);\n change({ ...color, s: x * 100, v: (1 - y) * 100 });\n };\n\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (disabled || !startsDrag(event)) return;\n // No text selection, and focus goes where the square puts it.\n event.preventDefault();\n event.currentTarget.setPointerCapture?.(event.pointerId);\n draggingRef.current = true;\n moveTo(event);\n focusAxis(axis);\n };\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n if (draggingRef.current) moveTo(event);\n };\n const endDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n draggingRef.current = false;\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n end();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n const by = event.shiftKey ? 10 : 1;\n // The horizontal arrows follow the screen: right to left, saturation\n // grows to the left.\n const right = isRtl(rootRef.current) ? -by : by;\n const moves: Record<string, [number, number]> = {\n ArrowRight: [right, 0],\n ArrowLeft: [-right, 0],\n ArrowUp: [0, by],\n ArrowDown: [0, -by],\n PageUp: [0, 10],\n PageDown: [0, -10],\n Home: [-10, 0],\n End: [10, 0],\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n const [dx, dy] = move;\n change(\n {\n ...color,\n s: clamp(s + dx, 0, 100),\n v: clamp(v + dy, 0, 100),\n },\n true\n );\n const moved = dx !== 0 ? 'x' : 'y';\n setAxis(moved);\n setKeyed(true);\n if (moved !== axis) focusNextRef.current = moved;\n };\n\n // A touch screen reader, or a browser's own stepping, sets an input's\n // value without a key the square handled.\n const onInput =\n (which: 'x' | 'y') => (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = Number(event.target.value);\n change(\n which === 'x' ? { ...color, s: value } : { ...color, v: value },\n true\n );\n };\n\n const onBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n const next = event.relatedTarget;\n if (next !== xRef.current && next !== yRef.current) setKeyed(false);\n };\n\n // What both inputs share; each adds its axis, and the handlers.\n const shared = {\n type: 'range',\n className: inputClass,\n min: 0,\n max: 100,\n step: 1,\n disabled,\n 'aria-label': labels.area,\n 'aria-roledescription': labels.areaRoleDescription,\n } as const;\n // The one not holding the tab stop is hidden until a key moves the\n // square, so a screen reader lists one control; both show on touch.\n const tabIndexOf = (which: 'x' | 'y') => (touch || axis === which ? 0 : -1);\n const hiddenOf = (which: 'x' | 'y') =>\n touch || keyed || axis === which ? undefined : true;\n\n if (!picker) return null;\n\n return (\n <div\n ref={node => setRefs(node, rootRef, ref)}\n className={classNames(areaClass, bulmaHelperClasses, className)}\n style={\n {\n ...style,\n '--color-picker-hue': Math.round(color.h),\n '--color-picker-rgb': rgbChannels(color),\n '--color-area-x': `${color.s}%`,\n '--color-area-y': `${100 - color.v}%`,\n } as React.CSSProperties\n }\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n {...rest}\n >\n <div className={thumbClass} role=\"presentation\">\n <input\n ref={xRef}\n {...shared}\n value={s}\n aria-valuetext={`${saturationText}, ${brightnessText}`}\n aria-orientation=\"horizontal\"\n tabIndex={tabIndexOf('x')}\n aria-hidden={hiddenOf('x')}\n onChange={onInput('x')}\n onKeyDown={onKeyDown}\n onFocus={() => setAxis('x')}\n onBlur={onBlur}\n />\n <input\n ref={yRef}\n {...shared}\n value={v}\n aria-valuetext={`${brightnessText}, ${saturationText}`}\n aria-orientation=\"vertical\"\n tabIndex={tabIndexOf('y')}\n aria-hidden={hiddenOf('y')}\n onChange={onInput('y')}\n onKeyDown={onKeyDown}\n onFocus={() => setAxis('y')}\n onBlur={onBlur}\n />\n </div>\n </div>\n );\n }\n);\n\nColorPickerArea.displayName = 'ColorPicker.Area';\n\n// ---------------------------------------------------------------------------\n// ColorPicker.HueSlider and ColorPicker.AlphaSlider\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.HueSlider and ColorPicker.AlphaSlider. The helper\n * props, the other attributes and the `ref` land on the slider's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the slider's `<div>`.\n */\nexport interface ColorPickerSliderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n}\n\ninterface ChannelSliderProps extends ColorPickerSliderProps {\n channel: 'hue' | 'alpha';\n}\n\n/** The hue or the alpha slider: a hidden native range under a drawn track. */\nconst ChannelSlider = forwardRef<HTMLDivElement, ChannelSliderProps>(\n ({ channel, className, style, ...props }, ref) => {\n const picker = usePicker(channel === 'hue' ? 'HueSlider' : 'AlphaSlider');\n const live = picker ?? standalone;\n const { color, change, end, disabled, labels, percent, degrees } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const draggingRef = useRef(false);\n\n const isHue = channel === 'hue';\n const max = isHue ? 360 : 100;\n const value = Math.round(isHue ? color.h : color.a * 100);\n const withValue = (next: number): Hsva =>\n isHue ? { ...color, h: next } : { ...color, a: next / 100 };\n\n const sliderClass = usePrefixedClassNames('color-slider', {\n 'is-hue': isHue,\n 'is-alpha': !isHue,\n 'is-disabled': disabled,\n });\n const trackClass = usePrefixedClassNames('color-slider-track');\n const thumbClass = usePrefixedClassNames('color-slider-thumb');\n const inputClass = usePrefixedClassNames('color-slider-input');\n\n const moveTo = (event: React.PointerEvent<HTMLDivElement>) => {\n const { x } = pointIn(event.currentTarget, event);\n change(withValue(x * max));\n };\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (disabled || !startsDrag(event)) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture?.(event.pointerId);\n draggingRef.current = true;\n moveTo(event);\n rootRef.current?.querySelector('input')?.focus({ preventScroll: true });\n };\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n if (draggingRef.current) moveTo(event);\n };\n const endDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n draggingRef.current = false;\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n end();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n const by = event.shiftKey ? 10 : 1;\n const right = isRtl(rootRef.current) ? -by : by;\n const steps: Record<string, number> = {\n ArrowRight: right,\n ArrowLeft: -right,\n ArrowUp: by,\n ArrowDown: -by,\n PageUp: 10,\n PageDown: -10,\n Home: -max,\n End: max,\n };\n const step = steps[event.key];\n if (step === undefined) return;\n event.preventDefault();\n change(withValue(clamp(value + step, 0, max)), true);\n };\n\n if (!picker) return null;\n\n return (\n <div\n ref={node => setRefs(node, rootRef, ref)}\n className={classNames(sliderClass, bulmaHelperClasses, className)}\n style={\n {\n ...style,\n '--color-picker-hue': Math.round(color.h),\n '--color-picker-rgb': rgbChannels(color),\n '--color-slider-position': `${(value / max) * 100}%`,\n } as React.CSSProperties\n }\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n {...rest}\n >\n <div className={trackClass} />\n <div className={thumbClass} role=\"presentation\">\n <input\n type=\"range\"\n className={inputClass}\n min={0}\n max={max}\n step={1}\n value={value}\n disabled={disabled}\n // Spelled out, as the square's is, so Safari's Tab reaches it\n // with its default settings, which skip a range input without\n // one.\n tabIndex={0}\n aria-label={isHue ? labels.hue : labels.alpha}\n aria-valuetext={isHue ? degrees(value) : percent(value)}\n onChange={event =>\n change(withValue(Number(event.target.value)), true)\n }\n onKeyDown={onKeyDown}\n />\n </div>\n </div>\n );\n }\n);\n\nChannelSlider.displayName = 'ChannelSlider';\n\n/**\n * The hue slider, from red round the spectrum and back to red.\n *\n * @function\n * @param {ColorPickerSliderProps} props - Props for ColorPicker.HueSlider.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the slider's `<div>`.\n * @returns {JSX.Element | null} The slider, or nothing outside a ColorPicker.\n */\nexport const ColorPickerHueSlider = forwardRef<\n HTMLDivElement,\n ColorPickerSliderProps\n>((props, ref) => <ChannelSlider ref={ref} {...props} channel=\"hue\" />);\n\nColorPickerHueSlider.displayName = 'ColorPicker.HueSlider';\n\n/**\n * The alpha slider, from see-through to solid.\n *\n * @function\n * @param {ColorPickerSliderProps} props - Props for ColorPicker.AlphaSlider.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the slider's `<div>`.\n * @returns {JSX.Element | null} The slider, or nothing outside a ColorPicker.\n */\nexport const ColorPickerAlphaSlider = forwardRef<\n HTMLDivElement,\n ColorPickerSliderProps\n>((props, ref) => <ChannelSlider ref={ref} {...props} channel=\"alpha\" />);\n\nColorPickerAlphaSlider.displayName = 'ColorPicker.AlphaSlider';\n\n// ---------------------------------------------------------------------------\n// ColorPicker.Swatches\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.Swatches. The helper props, the other attributes and\n * the `ref` land on the group's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the group's `<div>`.\n */\nexport interface ColorPickerSwatchesProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The colors to offer, in place of the picker's own `swatches`: a list,\n * or `\"bulma\"` for the page's theme colors.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n}\n\n/** Arrow keys and how far they move along the swatches. */\nconst SWATCH_STEPS: Record<string, number> = {\n ArrowRight: 1,\n ArrowDown: 1,\n ArrowLeft: -1,\n ArrowUp: -1,\n};\n\n/**\n * The swatches, a radio group of preset colors that sets the picker's color.\n *\n * @function\n * @param {ColorPickerSwatchesProps} props - Props for ColorPicker.Swatches.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the group's `<div>`.\n * @returns {JSX.Element | null} The swatches, or nothing outside a ColorPicker or with none to show.\n */\nexport const ColorPickerSwatches = forwardRef<\n HTMLDivElement,\n ColorPickerSwatchesProps\n>(({ className, swatches: ownSwatches, ...props }, ref) => {\n const picker = usePicker('Swatches');\n const live = picker ?? standalone;\n const { color, change, disabled, labels, format, alpha } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n const groupClass = usePrefixedClassNames('color-picker-swatches');\n const rootRef = useRef<HTMLDivElement | null>(null);\n\n const given = ownSwatches ?? live.swatches;\n const list = useMemo(\n () =>\n (given === 'bulma' ? BULMA_SWATCHES : (given ?? [])).map(entry =>\n typeof entry === 'string' ? { color: entry } : entry\n ),\n [given]\n );\n\n // A color the picker can't read as written, such as a var(), is read off\n // the page, as the text the swatch's own custom property resolves to.\n const chipsRef = useRef<Array<HTMLSpanElement | null>>([]);\n const textOf = useCallback(\n (i: number): string => {\n const chip = chipsRef.current[i];\n if (parseColor(list[i].color) || !chip) return list[i].color;\n return getComputedStyle(chip)\n .getPropertyValue('--color-swatch-color')\n .trim();\n },\n [list]\n );\n // Those texts, read after every render rather than once: a Theme can\n // change the variables behind them while the picker is open, and the\n // chosen swatch has to follow. A read that changes nothing renders\n // nothing more.\n const [resolved, setResolved] = useState<string[]>([]);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose; the updater keeps the state when nothing changed, so it settles\n useEffect(() => {\n const next = list.map((_, i) => textOf(i));\n // eslint-disable-next-line react-hooks/set-state-in-effect -- a var() color can only be read off the page once its swatch is on it\n setResolved(previous =>\n previous.length === next.length &&\n previous.every((text, i) => text === next[i])\n ? previous\n : next\n );\n });\n\n const colorOf = (i: number) =>\n parseColor(list[i].color) ?? parseColor(resolved[i]);\n // The same color, as far as the picker's value can tell: the same 8-bit\n // color, or the same text, since an HSL value is rounded.\n const shownText = formatColor(color, format, alpha);\n const checked = list.findIndex((_, i) => {\n const swatch = colorOf(i);\n if (!swatch) return false;\n const solid = alpha ? swatch : { ...swatch, a: 1 };\n return (\n sameColor(solid, color) || formatColor(solid, format, alpha) === shownText\n );\n });\n const [focused, setFocused] = useState<number | null>(null);\n const tabStop = focused ?? (checked >= 0 ? checked : 0);\n\n // Read afresh, so a theme that changed since the last render counts.\n const pick = (i: number) => {\n const text = textOf(i);\n const swatch = parseColor(text);\n if (swatch) change(keepingChannels(swatch, color, text), true);\n };\n\n const onKeyDown = (i: number) => (event: React.KeyboardEvent) => {\n const buttons = Array.from(\n (rootRef.current as HTMLDivElement).querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]'\n )\n );\n let next: number | undefined;\n if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = buttons.length - 1;\n else if (SWATCH_STEPS[event.key]) {\n // Left and Right follow the screen, so right to left they swap.\n const sideways = event.key === 'ArrowLeft' || event.key === 'ArrowRight';\n const flip = sideways && isRtl(rootRef.current) ? -1 : 1;\n next =\n (i + SWATCH_STEPS[event.key] * flip + buttons.length) % buttons.length;\n }\n if (next === undefined) return;\n event.preventDefault();\n buttons[next]?.focus();\n pick(next);\n };\n\n if (!picker || list.length === 0) return null;\n\n return (\n <div\n ref={node => setRefs(node, rootRef, ref)}\n className={classNames(groupClass, bulmaHelperClasses, className)}\n role=\"radiogroup\"\n aria-label={labels.swatches}\n aria-disabled={disabled || undefined}\n {...rest}\n >\n {list.map((entry, i) => {\n const swatch = colorOf(i);\n const isChecked = i === checked;\n // The check is drawn in black or white with a ring of the other, so\n // it shows on any color. On a see-through swatch the page shows\n // through, so it takes the scheme's text color and background,\n // which follow dark mode, in place of the swatch's own.\n const seeThrough = !!swatch && swatch.a < 1;\n return (\n <button\n key={`${entry.color}-${i}`}\n type=\"button\"\n role=\"radio\"\n aria-checked={isChecked}\n aria-label={entry.label || entry.color}\n title={entry.label}\n tabIndex={i === tabStop ? 0 : -1}\n disabled={disabled}\n className={prefixedClassNames(classPrefix, 'color-picker-swatch', {\n 'is-checked': isChecked,\n 'is-see-through': seeThrough,\n 'is-dark-ink': !!swatch && !seeThrough && prefersDarkInk(swatch),\n })}\n onClick={() => pick(i)}\n onKeyDown={onKeyDown(i)}\n onFocus={() => setFocused(i)}\n onBlur={() => setFocused(null)}\n >\n <ColorSwatch\n ref={node => {\n chipsRef.current[i] = node;\n }}\n color={entry.color}\n aria-hidden=\"true\"\n >\n {isChecked && (\n <CheckIcon\n haloClass={prefixedClassNames(\n classPrefix,\n 'color-picker-check-halo'\n )}\n />\n )}\n </ColorSwatch>\n </button>\n );\n })}\n </div>\n );\n});\n\nColorPickerSwatches.displayName = 'ColorPicker.Swatches';\n\n/**\n * The check on the chosen swatch: a ring in `haloClass`, and the check over\n * it in the current color.\n */\nconst CheckIcon = ({ haloClass }: { haloClass: string }) => (\n <svg viewBox=\"0 0 16 16\" width=\"1em\" height=\"1em\" aria-hidden=\"true\">\n {['halo', 'ink'].map(part => (\n <path\n key={part}\n className={part === 'halo' ? haloClass : undefined}\n d=\"M3.5 8.5l3 3 6-7\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={part === 'halo' ? 4.5 : 2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n ))}\n </svg>\n);\n\n// ---------------------------------------------------------------------------\n// ColorPicker.Input\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.Input. The helper props, the other attributes and\n * the `ref` land on the row's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the row's `<div>`.\n */\nexport interface ColorPickerInputProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n}\n\n/**\n * The value as text you can type in, beside a preview swatch, with the eye dropper when the picker has `eyeDropper`.\n *\n * @function\n * @param {ColorPickerInputProps} props - Props for ColorPicker.Input.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the row's `<div>`.\n * @returns {JSX.Element | null} The row, or nothing outside a ColorPicker.\n */\nexport const ColorPickerInput = forwardRef<\n HTMLDivElement,\n ColorPickerInputProps\n>(({ className, ...props }, ref) => {\n const picker = usePicker('Input');\n const live = picker ?? standalone;\n const { color, text, change, disabled, labels } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rowClass = usePrefixedClassNames('color-picker-value');\n const previewClass = usePrefixedClassNames('color-picker-preview');\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 const invalid = draft !== null && !parseColor(draft);\n const inputClass = usePrefixedClassNames('input', {\n 'is-small': true,\n 'is-danger': invalid,\n });\n\n const commit = () => {\n if (draft === null) return;\n const parsed = parseColor(draft);\n setDraft(null);\n if (parsed) change(keepingChannels(parsed, color, draft), true);\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (draft === null) return;\n if (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 (event.key === 'Escape') {\n // Puts the value back, and keeps the key from closing a popover too.\n event.preventDefault();\n event.stopPropagation();\n setDraft(null);\n }\n };\n\n if (!picker) return null;\n\n return (\n <div\n ref={ref}\n className={classNames(rowClass, bulmaHelperClasses, className)}\n {...rest}\n >\n <ColorSwatch color={text} className={previewClass} aria-hidden=\"true\" />\n <input\n type=\"text\"\n className={inputClass}\n value={draft ?? text}\n disabled={disabled}\n aria-label={labels.value}\n aria-invalid={invalid || undefined}\n spellCheck={false}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n onChange={event => setDraft(event.target.value)}\n onKeyDown={onKeyDown}\n onBlur={commit}\n />\n <EyeDropperButton />\n </div>\n );\n});\n\nColorPickerInput.displayName = 'ColorPicker.Input';\n\n// ---------------------------------------------------------------------------\n// ColorPicker (root)\n// ---------------------------------------------------------------------------\n\n/**\n * Props for the ColorPicker component. The helper props, the other\n * attributes and the `ref` land on the picker's `<div>`, inside the `Field`\n * and `Control` it renders when it isn't already in them.\n *\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a\n * `Field` for them, nested in the `.control`, and warns in development.\n * Wrap the `Control` in a `Field` instead, and set the `label`, `horizontal`\n * and class name on that `Field`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the picker's `<div>`.\n * @extraProp {string} [aria-label] - Names the picker's group when there's no `label`.\n */\nexport interface ColorPickerProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'color' | 'role'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'>,\n FormFieldProps {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Field label naming the picker's group, through `aria-labelledby`. Dropped inside an outer `Field`, whose own label names it instead. An `aria-label` or `aria-labelledby` you set wins over either. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /**\n * The color, controlled: any CSS color the picker reads (hex, `rgb()`,\n * `hsl()` or a color name), in any format, since `onChange` hands back\n * the `format` asked for. One it can't read leaves the picker showing the\n * last color it could. A value it gave you comes back without moving the\n * thumbs, and a gray or black keeps the hue and saturation the user had.\n */\n value?: string;\n /** The color to start with, uncontrolled. Black without one. */\n defaultValue?: string;\n /**\n * Called with the color, in `format`, as it changes: on every step of a\n * drag, and on a key, a swatch, a typed value or the eye dropper.\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 a key, a swatch, a typed value or the eye\n * dropper. The place to save it.\n */\n onChangeEnd?: (value: string) => void;\n /**\n * How the value is written: `'hsl'` (`hsl(171, 100%, 41%)`), Bulma's own\n * color space and what `Theme`'s `primaryH`, `primaryS` and `primaryL`\n * take, `'hex'` (`#00d1b2`) or `'rgb'` (`rgb(0, 209, 178)`). With `alpha`,\n * `hsla()`, `#rrggbbaa` and `rgba()`.\n * @defaultValue 'hsl'\n */\n format?: ColorFormat;\n /**\n * Adds an alpha slider and writes the alpha into the value. Without it,\n * the value is always solid.\n */\n alpha?: boolean;\n /**\n * Preset colors shown as a radio group under the picker: a list of CSS\n * colors, each a string or `{ color, label }`, or `\"bulma\"` for the page's\n * primary, link, info, success, warning and danger, from Bulma's CSS\n * variables, so a themed app shows its own. A color the picker can't read\n * as written, such as a `var()`, is read off the page each time the picker\n * renders, so after a theme change the swatches show the new colors at\n * once and the chosen one is marked again on the picker's next render,\n * which a `Theme` around it causes. The `\"bulma\"` names are English; for\n * others, pass the list yourself, such as\n * `{ color: 'var(--bulma-primary)', label: 'Primär' }`.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n /**\n * Adds a button that picks a color from anywhere on the screen, where the\n * browser has the EyeDropper API (desktop Chromium today). Elsewhere, and\n * until the page hydrates, it isn't shown.\n */\n eyeDropper?: boolean;\n /** Disables every part. A disabled `Fieldset` around it does too. */\n disabled?: boolean;\n /** Form field name. When set, a hidden input carries the value. */\n name?: string;\n /** The id of the form the hidden input belongs to. */\n form?: string;\n /** The strings it says, each with an English default. */\n labels?: ColorPickerLabels;\n /**\n * Parts for a layout of your own: `ColorPicker.Area`,\n * `ColorPicker.HueSlider`, `ColorPicker.AlphaSlider`,\n * `ColorPicker.Swatches` and `ColorPicker.Input`, with anything else\n * between them. Without children, the picker shows the square, the hue\n * slider, the alpha slider with `alpha`, the value, and the swatches when\n * there are some.\n */\n children?: React.ReactNode;\n}\n\n/**\n * The `ColorPicker` component is a panel for choosing a color: a saturation and brightness square, a hue slider, and the value as text, with alpha and swatches when asked for.\n *\n * Every part is operable by keyboard, and the square is two native range\n * inputs, one per axis, with one tab stop. The value is a CSS color string\n * in `format`, HSL by default.\n *\n * @function\n * @param {ColorPickerProps} props - Props for the ColorPicker component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the picker's `<div>`.\n * @returns {JSX.Element} The rendered picker.\n *\n * @example\n * <ColorPicker label=\"Brand color\" defaultValue=\"#1e6b99\" swatches=\"bulma\" />\n */\nconst ColorPickerRoot = forwardRef<HTMLDivElement, ColorPickerProps>(\n (\n {\n className,\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n format = 'hsl',\n alpha = false,\n swatches,\n eyeDropper = false,\n disabled: disabledProp,\n name,\n form,\n labels,\n children,\n ...props\n },\n ref\n ) => {\n const disabled = useFieldsetDisabled(disabledProp);\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('ColorPicker', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const pickerClass = usePrefixedClassNames('color-picker', {\n 'is-disabled': disabled,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n const context = useColorPicker({\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n });\n\n const picker = (\n <div\n ref={ref}\n className={classNames(pickerClass, bulmaHelperClasses, className)}\n role=\"group\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n <ColorPickerContext.Provider value={context}>\n {children ?? (\n <>\n <ColorPickerArea />\n <ColorPickerHueSlider />\n {alpha && <ColorPickerAlphaSlider />}\n <ColorPickerInput />\n {swatches && <ColorPickerSwatches />}\n </>\n )}\n </ColorPickerContext.Provider>\n {name && (\n <input\n type=\"hidden\"\n name={name}\n form={form}\n value={context.text}\n disabled={disabled}\n />\n )}\n </div>\n );\n\n let content: React.ReactNode = picker;\n if (rendersOwnControl('ColorPicker', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nColorPickerRoot.displayName = 'ColorPicker';\n\nexport const ColorPicker = withSubComponents(ColorPickerRoot, {\n Area: ColorPickerArea,\n HueSlider: ColorPickerHueSlider,\n AlphaSlider: ColorPickerAlphaSlider,\n Swatches: ColorPickerSwatches,\n Input: ColorPickerInput,\n});\n\nexport default ColorPicker;\n"],"names":["clamp","_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ColorPicker.js","sources":["../../../src/form/ColorPicker.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { ColorSwatch } from '../elements/ColorSwatch';\nimport {\n ColorFormat,\n Hsva,\n formatColor,\n hsvaToRgba,\n parseColor,\n prefersDarkInk,\n sameColor,\n} from './_colorInternals/colorMath';\nimport {\n ColorPickerContext,\n keepingChannels,\n standalone,\n useColorPicker,\n usePicker,\n} from './_colorInternals/pickerState';\nimport { EyeDropperButton } from './_colorInternals/EyeDropperButton';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n useFieldsetDisabled,\n} from './FormContext';\nimport { useAutoLabelledBy } from './useAutoLabelId';\n\nexport type { ColorFormat } from './_colorInternals/colorMath';\n\n/**\n * A preset color for a picker's swatches: a CSS color, or a CSS color with\n * a name. The name labels the swatch for a screen reader and shows as its\n * tooltip; without one, the color as written does.\n */\nexport type ColorPickerSwatch = string | { color: string; label?: string };\n\n/**\n * The strings a color picker says, each with an English default. A key\n * left out, or set to an empty string, keeps its default.\n */\nexport interface ColorPickerLabels {\n /**\n * Names the saturation and brightness square.\n * @defaultValue 'Saturation and brightness'\n */\n area?: string;\n /**\n * What a screen reader calls the square in place of \"slider\".\n * @defaultValue '2D slider'\n */\n areaRoleDescription?: string;\n /**\n * The square's horizontal channel, in its value text.\n * @defaultValue 'Saturation'\n */\n saturation?: string;\n /**\n * The square's vertical channel, in its value text.\n * @defaultValue 'Brightness'\n */\n brightness?: string;\n /**\n * Names the hue slider.\n * @defaultValue 'Hue'\n */\n hue?: string;\n /**\n * Names the alpha slider.\n * @defaultValue 'Alpha'\n */\n alpha?: string;\n /**\n * The unit after the hue's number in its value text, \"171 degrees\".\n * Inside a `LocaleProvider` with a `locale`, that locale writes the number\n * and its unit, and this isn't used.\n * @defaultValue 'degrees'\n */\n degrees?: string;\n /**\n * Names the field that shows the value as text.\n * @defaultValue 'Color value'\n */\n value?: string;\n /**\n * Names the group of swatches.\n * @defaultValue 'Swatches'\n */\n swatches?: string;\n /**\n * Names the eye dropper button.\n * @defaultValue 'Pick a color from the screen'\n */\n eyeDropper?: string;\n /**\n * Names `ColorInput`'s launcher and the panel it opens.\n * @defaultValue 'Choose color'\n */\n chooseColor?: string;\n}\n\n// The theme colors `swatches=\"bulma\"` shows, read off the page.\nconst BULMA_SWATCHES: ReadonlyArray<{ color: string; label: string }> = [\n { color: 'var(--bulma-primary)', label: 'Primary' },\n { color: 'var(--bulma-link)', label: 'Link' },\n { color: 'var(--bulma-info)', label: 'Info' },\n { color: 'var(--bulma-success)', label: 'Success' },\n { color: 'var(--bulma-warning)', label: 'Warning' },\n { color: 'var(--bulma-danger)', label: 'Danger' },\n];\n\nconst clamp = (value: number, low: number, high: number) =>\n Math.min(Math.max(value, low), high);\n\n/** Whether the element is laid out right to left. */\nconst isRtl = (element: Element | null) =>\n !!element && getComputedStyle(element).direction === 'rtl';\n\n/** Where a pointer is across an element, from 0 to 1 each way. */\nconst pointIn = (element: HTMLElement, event: React.PointerEvent) => {\n const rect = element.getBoundingClientRect();\n const across =\n rect.width > 0 ? clamp((event.clientX - rect.left) / rect.width, 0, 1) : 0;\n const down =\n rect.height > 0 ? clamp((event.clientY - rect.top) / rect.height, 0, 1) : 0;\n return { x: isRtl(element) ? 1 - across : across, y: down };\n};\n\n/** The color's red, green and blue, rounded, as a CSS `rgb()` takes them. */\nconst rgbChannels = (color: Hsva) => {\n const { r, g, b } = hsvaToRgba(color);\n return `${Math.round(r)} ${Math.round(g)} ${Math.round(b)}`;\n};\n\n/** Whether a press should start a drag: any touch or pen, a mouse's main button. */\nconst startsDrag = (event: React.PointerEvent) =>\n event.pointerType !== 'mouse' || event.button === 0;\n\n/** Hands a node to a forwarded ref and to one of the part's own. */\nfunction setRefs<T>(\n node: T | null,\n own: React.MutableRefObject<T | null>,\n forwarded: React.ForwardedRef<T>\n) {\n own.current = node;\n if (typeof forwarded === 'function') forwarded(node);\n else if (forwarded) forwarded.current = node;\n}\n\n// ---------------------------------------------------------------------------\n// ColorPicker.Area\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.Area. The helper props, the other attributes and the\n * `ref` land on the square's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the square's `<div>`.\n */\nexport interface ColorPickerAreaProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n}\n\n/**\n * The saturation and brightness square, operated by pointer or by keyboard as one 2D slider.\n *\n * @function\n * @param {ColorPickerAreaProps} props - Props for ColorPicker.Area.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the square's `<div>`.\n * @returns {JSX.Element | null} The square, or nothing outside a ColorPicker.\n */\nexport const ColorPickerArea = forwardRef<HTMLDivElement, ColorPickerAreaProps>(\n ({ className, style, ...props }, ref) => {\n const picker = usePicker('Area');\n const live = picker ?? standalone;\n const { color, change, end, disabled, labels, touch, percent } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n const rootRef = useRef<HTMLDivElement | null>(null);\n const xRef = useRef<HTMLInputElement>(null);\n const yRef = useRef<HTMLInputElement>(null);\n // The axis whose input holds the tab stop: the one focused or moved last.\n const [axis, setAxis] = useState<'x' | 'y'>('x');\n // Once a key has moved the square, both inputs are exposed until focus\n // leaves it, so the one that moved can be read.\n const [keyed, setKeyed] = useState(false);\n const draggingRef = useRef(false);\n\n const areaClass = usePrefixedClassNames('color-area', {\n 'is-disabled': disabled,\n });\n const thumbClass = usePrefixedClassNames('color-area-thumb');\n const inputClass = usePrefixedClassNames('color-area-input');\n\n const s = Math.round(color.s);\n const v = Math.round(color.v);\n const saturationText = `${labels.saturation} ${percent(s)}`;\n const brightnessText = `${labels.brightness} ${percent(v)}`;\n\n const focusAxis = (which: 'x' | 'y') =>\n (which === 'x' ? xRef : yRef).current?.focus({ preventScroll: true });\n // The axis a key moved to, focused once the render that shows its input\n // is on the page, so it's no longer aria-hidden as it takes focus.\n const focusNextRef = useRef<'x' | 'y' | null>(null);\n useClientLayoutEffect(() => {\n if (!focusNextRef.current) return;\n focusAxis(focusNextRef.current);\n focusNextRef.current = null;\n });\n\n const moveTo = (event: React.PointerEvent<HTMLDivElement>) => {\n const { x, y } = pointIn(event.currentTarget, event);\n change({ ...color, s: x * 100, v: (1 - y) * 100 });\n };\n\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (disabled || !startsDrag(event)) return;\n // No text selection, and focus goes where the square puts it.\n event.preventDefault();\n event.currentTarget.setPointerCapture?.(event.pointerId);\n draggingRef.current = true;\n moveTo(event);\n focusAxis(axis);\n };\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n if (draggingRef.current) moveTo(event);\n };\n const endDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n draggingRef.current = false;\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n end();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n const by = event.shiftKey ? 10 : 1;\n // The horizontal arrows follow the screen: right to left, saturation\n // grows to the left.\n const right = isRtl(rootRef.current) ? -by : by;\n const moves: Record<string, [number, number]> = {\n ArrowRight: [right, 0],\n ArrowLeft: [-right, 0],\n ArrowUp: [0, by],\n ArrowDown: [0, -by],\n PageUp: [0, 10],\n PageDown: [0, -10],\n Home: [-10, 0],\n End: [10, 0],\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n const [dx, dy] = move;\n change(\n {\n ...color,\n s: clamp(s + dx, 0, 100),\n v: clamp(v + dy, 0, 100),\n },\n true\n );\n const moved = dx !== 0 ? 'x' : 'y';\n setAxis(moved);\n setKeyed(true);\n if (moved !== axis) focusNextRef.current = moved;\n };\n\n // A touch screen reader, or a browser's own stepping, sets an input's\n // value without a key the square handled.\n const onInput =\n (which: 'x' | 'y') => (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = Number(event.target.value);\n change(\n which === 'x' ? { ...color, s: value } : { ...color, v: value },\n true\n );\n };\n\n const onBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n const next = event.relatedTarget;\n if (next !== xRef.current && next !== yRef.current) setKeyed(false);\n };\n\n // What both inputs share; each adds its axis, and the handlers.\n const shared = {\n type: 'range',\n className: inputClass,\n min: 0,\n max: 100,\n step: 1,\n disabled,\n 'aria-label': labels.area,\n 'aria-roledescription': labels.areaRoleDescription,\n } as const;\n // The one not holding the tab stop is hidden until a key moves the\n // square, so a screen reader lists one control; both show on touch.\n const tabIndexOf = (which: 'x' | 'y') => (touch || axis === which ? 0 : -1);\n const hiddenOf = (which: 'x' | 'y') =>\n touch || keyed || axis === which ? undefined : true;\n\n if (!picker) return null;\n\n return (\n <div\n ref={node => setRefs(node, rootRef, ref)}\n className={classNames(areaClass, bulmaHelperClasses, className)}\n style={\n {\n ...style,\n '--color-picker-hue': Math.round(color.h),\n '--color-picker-rgb': rgbChannels(color),\n '--color-area-x': `${color.s}%`,\n '--color-area-y': `${100 - color.v}%`,\n } as React.CSSProperties\n }\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n {...rest}\n >\n <div className={thumbClass} role=\"presentation\">\n <input\n ref={xRef}\n {...shared}\n value={s}\n aria-valuetext={`${saturationText}, ${brightnessText}`}\n aria-orientation=\"horizontal\"\n tabIndex={tabIndexOf('x')}\n aria-hidden={hiddenOf('x')}\n onChange={onInput('x')}\n onKeyDown={onKeyDown}\n onFocus={() => setAxis('x')}\n onBlur={onBlur}\n />\n <input\n ref={yRef}\n {...shared}\n value={v}\n aria-valuetext={`${brightnessText}, ${saturationText}`}\n aria-orientation=\"vertical\"\n tabIndex={tabIndexOf('y')}\n aria-hidden={hiddenOf('y')}\n onChange={onInput('y')}\n onKeyDown={onKeyDown}\n onFocus={() => setAxis('y')}\n onBlur={onBlur}\n />\n </div>\n </div>\n );\n }\n);\n\nColorPickerArea.displayName = 'ColorPicker.Area';\n\n// ---------------------------------------------------------------------------\n// ColorPicker.HueSlider and ColorPicker.AlphaSlider\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.HueSlider and ColorPicker.AlphaSlider. The helper\n * props, the other attributes and the `ref` land on the slider's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the slider's `<div>`.\n */\nexport interface ColorPickerSliderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n}\n\ninterface ChannelSliderProps extends ColorPickerSliderProps {\n channel: 'hue' | 'alpha';\n}\n\n/** The hue or the alpha slider: a hidden native range under a drawn track. */\nconst ChannelSlider = forwardRef<HTMLDivElement, ChannelSliderProps>(\n ({ channel, className, style, ...props }, ref) => {\n const picker = usePicker(channel === 'hue' ? 'HueSlider' : 'AlphaSlider');\n const live = picker ?? standalone;\n const { color, change, end, disabled, labels, percent, degrees } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const draggingRef = useRef(false);\n\n const isHue = channel === 'hue';\n const max = isHue ? 360 : 100;\n const value = Math.round(isHue ? color.h : color.a * 100);\n const withValue = (next: number): Hsva =>\n isHue ? { ...color, h: next } : { ...color, a: next / 100 };\n\n const sliderClass = usePrefixedClassNames('color-slider', {\n 'is-hue': isHue,\n 'is-alpha': !isHue,\n 'is-disabled': disabled,\n });\n const trackClass = usePrefixedClassNames('color-slider-track');\n const thumbClass = usePrefixedClassNames('color-slider-thumb');\n const inputClass = usePrefixedClassNames('color-slider-input');\n\n const moveTo = (event: React.PointerEvent<HTMLDivElement>) => {\n const { x } = pointIn(event.currentTarget, event);\n change(withValue(x * max));\n };\n const onPointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n if (disabled || !startsDrag(event)) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture?.(event.pointerId);\n draggingRef.current = true;\n moveTo(event);\n rootRef.current?.querySelector('input')?.focus({ preventScroll: true });\n };\n const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n if (draggingRef.current) moveTo(event);\n };\n const endDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n draggingRef.current = false;\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n end();\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n const by = event.shiftKey ? 10 : 1;\n const right = isRtl(rootRef.current) ? -by : by;\n const steps: Record<string, number> = {\n ArrowRight: right,\n ArrowLeft: -right,\n ArrowUp: by,\n ArrowDown: -by,\n PageUp: 10,\n PageDown: -10,\n Home: -max,\n End: max,\n };\n const step = steps[event.key];\n if (step === undefined) return;\n event.preventDefault();\n change(withValue(clamp(value + step, 0, max)), true);\n };\n\n if (!picker) return null;\n\n return (\n <div\n ref={node => setRefs(node, rootRef, ref)}\n className={classNames(sliderClass, bulmaHelperClasses, className)}\n style={\n {\n ...style,\n '--color-picker-hue': Math.round(color.h),\n '--color-picker-rgb': rgbChannels(color),\n '--color-slider-position': `${(value / max) * 100}%`,\n } as React.CSSProperties\n }\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n {...rest}\n >\n <div className={trackClass} />\n <div className={thumbClass} role=\"presentation\">\n <input\n type=\"range\"\n className={inputClass}\n min={0}\n max={max}\n step={1}\n value={value}\n disabled={disabled}\n // Spelled out, as the square's is, so Safari's Tab reaches it\n // with its default settings, which skip a range input without\n // one.\n tabIndex={0}\n aria-label={isHue ? labels.hue : labels.alpha}\n aria-valuetext={isHue ? degrees(value) : percent(value)}\n onChange={event =>\n change(withValue(Number(event.target.value)), true)\n }\n onKeyDown={onKeyDown}\n />\n </div>\n </div>\n );\n }\n);\n\nChannelSlider.displayName = 'ChannelSlider';\n\n/**\n * The hue slider, from red round the spectrum and back to red.\n *\n * @function\n * @param {ColorPickerSliderProps} props - Props for ColorPicker.HueSlider.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the slider's `<div>`.\n * @returns {JSX.Element | null} The slider, or nothing outside a ColorPicker.\n */\nexport const ColorPickerHueSlider = forwardRef<\n HTMLDivElement,\n ColorPickerSliderProps\n>((props, ref) => <ChannelSlider ref={ref} {...props} channel=\"hue\" />);\n\nColorPickerHueSlider.displayName = 'ColorPicker.HueSlider';\n\n/**\n * The alpha slider, from see-through to solid.\n *\n * @function\n * @param {ColorPickerSliderProps} props - Props for ColorPicker.AlphaSlider.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the slider's `<div>`.\n * @returns {JSX.Element | null} The slider, or nothing outside a ColorPicker.\n */\nexport const ColorPickerAlphaSlider = forwardRef<\n HTMLDivElement,\n ColorPickerSliderProps\n>((props, ref) => <ChannelSlider ref={ref} {...props} channel=\"alpha\" />);\n\nColorPickerAlphaSlider.displayName = 'ColorPicker.AlphaSlider';\n\n// ---------------------------------------------------------------------------\n// ColorPicker.Swatches\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.Swatches. The helper props, the other attributes and\n * the `ref` land on the group's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the group's `<div>`.\n */\nexport interface ColorPickerSwatchesProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The colors to offer, in place of the picker's own `swatches`: a list,\n * or `\"bulma\"` for the page's theme colors.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n}\n\n/** Arrow keys and how far they move along the swatches. */\nconst SWATCH_STEPS: Record<string, number> = {\n ArrowRight: 1,\n ArrowDown: 1,\n ArrowLeft: -1,\n ArrowUp: -1,\n};\n\n/**\n * The swatches, a radio group of preset colors that sets the picker's color.\n *\n * @function\n * @param {ColorPickerSwatchesProps} props - Props for ColorPicker.Swatches.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the group's `<div>`.\n * @returns {JSX.Element | null} The swatches, or nothing outside a ColorPicker or with none to show.\n */\nexport const ColorPickerSwatches = forwardRef<\n HTMLDivElement,\n ColorPickerSwatchesProps\n>(({ className, swatches: ownSwatches, ...props }, ref) => {\n const picker = usePicker('Swatches');\n const live = picker ?? standalone;\n const { color, change, disabled, labels, format, alpha } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n const groupClass = usePrefixedClassNames('color-picker-swatches');\n const rootRef = useRef<HTMLDivElement | null>(null);\n\n const given = ownSwatches ?? live.swatches;\n const list = useMemo(\n () =>\n (given === 'bulma' ? BULMA_SWATCHES : (given ?? [])).map(entry =>\n typeof entry === 'string' ? { color: entry } : entry\n ),\n [given]\n );\n\n // A color the picker can't read as written, such as a var(), is read off\n // the page, as the text the swatch's own custom property resolves to.\n const chipsRef = useRef<Array<HTMLSpanElement | null>>([]);\n const textOf = useCallback(\n (i: number): string => {\n const chip = chipsRef.current[i];\n if (parseColor(list[i].color) || !chip) return list[i].color;\n return getComputedStyle(chip)\n .getPropertyValue('--color-swatch-color')\n .trim();\n },\n [list]\n );\n // Those texts, read after every render rather than once: a Theme can\n // change the variables behind them while the picker is open, and the\n // chosen swatch has to follow. A read that changes nothing renders\n // nothing more.\n const [resolved, setResolved] = useState<string[]>([]);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose; the updater keeps the state when nothing changed, so it settles\n useEffect(() => {\n const next = list.map((_, i) => textOf(i));\n // eslint-disable-next-line react-hooks/set-state-in-effect -- a var() color can only be read off the page once its swatch is on it\n setResolved(previous =>\n previous.length === next.length &&\n previous.every((text, i) => text === next[i])\n ? previous\n : next\n );\n });\n\n const colorOf = (i: number) =>\n parseColor(list[i].color) ?? parseColor(resolved[i]);\n // The same color, as far as the picker's value can tell: the same 8-bit\n // color, or the same text, since an HSL value is rounded.\n const shownText = formatColor(color, format, alpha);\n const checked = list.findIndex((_, i) => {\n const swatch = colorOf(i);\n if (!swatch) return false;\n const solid = alpha ? swatch : { ...swatch, a: 1 };\n return (\n sameColor(solid, color) || formatColor(solid, format, alpha) === shownText\n );\n });\n const [focused, setFocused] = useState<number | null>(null);\n const tabStop = focused ?? (checked >= 0 ? checked : 0);\n\n // Read afresh, so a theme that changed since the last render counts.\n const pick = (i: number) => {\n const text = textOf(i);\n const swatch = parseColor(text);\n if (swatch) change(keepingChannels(swatch, color, text), true);\n };\n\n const onKeyDown = (i: number) => (event: React.KeyboardEvent) => {\n const buttons = Array.from(\n (rootRef.current as HTMLDivElement).querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]'\n )\n );\n let next: number | undefined;\n if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = buttons.length - 1;\n else if (SWATCH_STEPS[event.key]) {\n // Left and Right follow the screen, so right to left they swap.\n const sideways = event.key === 'ArrowLeft' || event.key === 'ArrowRight';\n const flip = sideways && isRtl(rootRef.current) ? -1 : 1;\n next =\n (i + SWATCH_STEPS[event.key] * flip + buttons.length) % buttons.length;\n }\n if (next === undefined) return;\n event.preventDefault();\n buttons[next]?.focus();\n pick(next);\n };\n\n if (!picker || list.length === 0) return null;\n\n return (\n <div\n ref={node => setRefs(node, rootRef, ref)}\n className={classNames(groupClass, bulmaHelperClasses, className)}\n role=\"radiogroup\"\n aria-label={labels.swatches}\n aria-disabled={disabled || undefined}\n {...rest}\n >\n {list.map((entry, i) => {\n const swatch = colorOf(i);\n const isChecked = i === checked;\n // The check is drawn in black or white with a ring of the other, so\n // it shows on any color. On a see-through swatch the page shows\n // through, so it takes the scheme's text color and background,\n // which follow dark mode, in place of the swatch's own.\n const seeThrough = !!swatch && swatch.a < 1;\n return (\n <button\n key={`${entry.color}-${i}`}\n type=\"button\"\n role=\"radio\"\n aria-checked={isChecked}\n aria-label={entry.label || entry.color}\n title={entry.label}\n tabIndex={i === tabStop ? 0 : -1}\n disabled={disabled}\n className={prefixedClassNames(classPrefix, 'color-picker-swatch', {\n 'is-checked': isChecked,\n 'is-see-through': seeThrough,\n 'is-dark-ink': !!swatch && !seeThrough && prefersDarkInk(swatch),\n })}\n onClick={() => pick(i)}\n onKeyDown={onKeyDown(i)}\n onFocus={() => setFocused(i)}\n onBlur={() => setFocused(null)}\n >\n <ColorSwatch\n ref={node => {\n chipsRef.current[i] = node;\n }}\n color={entry.color}\n aria-hidden=\"true\"\n >\n {isChecked && (\n <CheckIcon\n haloClass={prefixedClassNames(\n classPrefix,\n 'color-picker-check-halo'\n )}\n />\n )}\n </ColorSwatch>\n </button>\n );\n })}\n </div>\n );\n});\n\nColorPickerSwatches.displayName = 'ColorPicker.Swatches';\n\n/**\n * The check on the chosen swatch: a ring in `haloClass`, and the check over\n * it in the current color.\n */\nconst CheckIcon = ({ haloClass }: { haloClass: string }) => (\n <svg viewBox=\"0 0 16 16\" width=\"1em\" height=\"1em\" aria-hidden=\"true\">\n {['halo', 'ink'].map(part => (\n <path\n key={part}\n className={part === 'halo' ? haloClass : undefined}\n d=\"M3.5 8.5l3 3 6-7\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={part === 'halo' ? 4.5 : 2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n ))}\n </svg>\n);\n\n// ---------------------------------------------------------------------------\n// ColorPicker.Input\n// ---------------------------------------------------------------------------\n\n/**\n * Props for ColorPicker.Input. The helper props, the other attributes and\n * the `ref` land on the row's `<div>`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the row's `<div>`.\n */\nexport interface ColorPickerInputProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n}\n\n/**\n * The value as text you can type in, beside a preview swatch, with the eye dropper when the picker has `eyeDropper`.\n *\n * @function\n * @param {ColorPickerInputProps} props - Props for ColorPicker.Input.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the row's `<div>`.\n * @returns {JSX.Element | null} The row, or nothing outside a ColorPicker.\n */\nexport const ColorPickerInput = forwardRef<\n HTMLDivElement,\n ColorPickerInputProps\n>(({ className, ...props }, ref) => {\n const picker = usePicker('Input');\n const live = picker ?? standalone;\n const { color, text, change, disabled, labels } = live;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rowClass = usePrefixedClassNames('color-picker-value');\n const previewClass = usePrefixedClassNames('color-picker-preview');\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 const invalid = draft !== null && !parseColor(draft);\n const inputClass = usePrefixedClassNames('input', {\n 'is-small': true,\n 'is-danger': invalid,\n });\n\n const commit = () => {\n if (draft === null) return;\n const parsed = parseColor(draft);\n setDraft(null);\n if (parsed) change(keepingChannels(parsed, color, draft), true);\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (draft === null) return;\n if (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 (event.key === 'Escape') {\n // Puts the value back, and keeps the key from closing a popover too.\n event.preventDefault();\n event.stopPropagation();\n setDraft(null);\n }\n };\n\n if (!picker) return null;\n\n return (\n <div\n ref={ref}\n className={classNames(rowClass, bulmaHelperClasses, className)}\n {...rest}\n >\n <ColorSwatch color={text} className={previewClass} aria-hidden=\"true\" />\n <input\n type=\"text\"\n className={inputClass}\n value={draft ?? text}\n disabled={disabled}\n aria-label={labels.value}\n aria-invalid={invalid || undefined}\n spellCheck={false}\n autoComplete=\"off\"\n autoCapitalize=\"off\"\n onChange={event => setDraft(event.target.value)}\n onKeyDown={onKeyDown}\n onBlur={commit}\n />\n <EyeDropperButton />\n </div>\n );\n});\n\nColorPickerInput.displayName = 'ColorPicker.Input';\n\n// ---------------------------------------------------------------------------\n// ColorPicker (root)\n// ---------------------------------------------------------------------------\n\n/**\n * Props for the ColorPicker component. The helper props, the other\n * attributes and the `ref` land on the picker's `<div>`, inside the `Field`\n * and `Control` it renders when it isn't already in them.\n *\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a\n * `Field` for them, nested in the `.control`, and warns in development.\n * Wrap the `Control` in a `Field` instead, and set the `label`, `horizontal`\n * and class name on that `Field`.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the picker's `<div>`.\n * @extraProp {string} [aria-label] - Names the picker's group when there's no `label`.\n */\nexport interface ColorPickerProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'color' | 'role'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'>,\n FormFieldProps {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Field label naming the picker's group, through `aria-labelledby`. Dropped inside an outer `Field`, whose own label names it instead. An `aria-label` or `aria-labelledby` you set wins over either. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /**\n * The color, controlled: any CSS color the picker reads (hex, `rgb()`,\n * `hsl()` or a color name), in any format, since `onChange` hands back\n * the `format` asked for. One it can't read leaves the picker showing the\n * last color it could. A value it gave you comes back without moving the\n * thumbs, and a gray or black keeps the hue and saturation the user had.\n */\n value?: string;\n /** The color to start with, uncontrolled. Black without one. */\n defaultValue?: string;\n /**\n * Called with the color, in `format`, as it changes: on every step of a\n * drag, and on a key, a swatch, a typed value or the eye dropper.\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 a key, a swatch, a typed value or the eye\n * dropper. The place to save it.\n */\n onChangeEnd?: (value: string) => void;\n /**\n * How the value is written: `'hsl'` (`hsl(171, 100%, 41%)`), Bulma's own\n * color space and what `Theme`'s `primaryH`, `primaryS` and `primaryL`\n * take, `'hex'` (`#00d1b2`) or `'rgb'` (`rgb(0, 209, 178)`). With `alpha`,\n * `hsla()`, `#rrggbbaa` and `rgba()`.\n * @defaultValue 'hsl'\n */\n format?: ColorFormat;\n /**\n * Adds an alpha slider and writes the alpha into the value. Without it,\n * the value is always solid.\n */\n alpha?: boolean;\n /**\n * Preset colors shown as a radio group under the picker: a list of CSS\n * colors, each a string or `{ color, label }`, or `\"bulma\"` for the page's\n * primary, link, info, success, warning and danger, from Bulma's CSS\n * variables, so a themed app shows its own. A color the picker can't read\n * as written, such as a `var()`, is read off the page each time the picker\n * renders, so after a theme change the swatches show the new colors at\n * once and the chosen one is marked again on the picker's next render,\n * which a `Theme` around it causes. The `\"bulma\"` names are English; for\n * others, pass the list yourself, such as\n * `{ color: 'var(--bulma-primary)', label: 'Primär' }`.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n /**\n * Adds a button that picks a color from anywhere on the screen, where the\n * browser has the EyeDropper API (desktop Chromium today). Elsewhere, and\n * until the page hydrates, it isn't shown.\n */\n eyeDropper?: boolean;\n /** Disables every part. A disabled `Fieldset` around it does too. */\n disabled?: boolean;\n /** Form field name. When set, a hidden input carries the value. */\n name?: string;\n /** The id of the form the hidden input belongs to. */\n form?: string;\n /** The strings it says, each with an English default. */\n labels?: ColorPickerLabels;\n /**\n * Parts for a layout of your own: `ColorPicker.Area`,\n * `ColorPicker.HueSlider`, `ColorPicker.AlphaSlider`,\n * `ColorPicker.Swatches` and `ColorPicker.Input`, with anything else\n * between them. Without children, the picker shows the square, the hue\n * slider, the alpha slider with `alpha`, the value, and the swatches when\n * there are some.\n */\n children?: React.ReactNode;\n}\n\n/**\n * The `ColorPicker` component is a panel for choosing a color: a saturation and brightness square, a hue slider, and the value as text, with alpha and swatches when asked for.\n *\n * Every part is operable by keyboard, and the square is two native range\n * inputs, one per axis, with one tab stop. The value is a CSS color string\n * in `format`, HSL by default.\n *\n * @function\n * @param {ColorPickerProps} props - Props for the ColorPicker component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the picker's `<div>`.\n * @returns {JSX.Element} The rendered picker.\n *\n * @example\n * <ColorPicker label=\"Brand color\" defaultValue=\"#1e6b99\" swatches=\"bulma\" />\n */\nconst ColorPickerRoot = forwardRef<HTMLDivElement, ColorPickerProps>(\n (\n {\n className,\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n format = 'hsl',\n alpha = false,\n swatches,\n eyeDropper = false,\n disabled: disabledProp,\n name,\n form,\n labels,\n children,\n ...props\n },\n ref\n ) => {\n const disabled = useFieldsetDisabled(disabledProp);\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('ColorPicker', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const pickerClass = usePrefixedClassNames('color-picker', {\n 'is-disabled': disabled,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n const context = useColorPicker({\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n });\n\n const picker = (\n <div\n ref={ref}\n className={classNames(pickerClass, bulmaHelperClasses, className)}\n role=\"group\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n <ColorPickerContext.Provider value={context}>\n {children ?? (\n <>\n <ColorPickerArea />\n <ColorPickerHueSlider />\n {alpha && <ColorPickerAlphaSlider />}\n <ColorPickerInput />\n {swatches && <ColorPickerSwatches />}\n </>\n )}\n </ColorPickerContext.Provider>\n {name && (\n <input\n type=\"hidden\"\n name={name}\n form={form}\n value={context.text}\n disabled={disabled}\n />\n )}\n </div>\n );\n\n let content: React.ReactNode = picker;\n if (rendersOwnControl('ColorPicker', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nColorPickerRoot.displayName = 'ColorPicker';\n\nexport const ColorPicker = withSubComponents(ColorPickerRoot, {\n Area: ColorPickerArea,\n HueSlider: ColorPickerHueSlider,\n AlphaSlider: ColorPickerAlphaSlider,\n Swatches: ColorPickerSwatches,\n Input: ColorPickerInput,\n});\n\nexport default ColorPicker;\n"],"names":["clamp","setRefs","_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
@@ -71,7 +71,7 @@ const standalone$1 = {
|
|
|
71
71
|
const ComboboxContext = createContext(null);
|
|
72
72
|
const useCombobox = () => useContext(ComboboxContext) ?? standalone$1;
|
|
73
73
|
/** Hands a node to a forwarded ref and to one of the component's own. */
|
|
74
|
-
function setRefs$
|
|
74
|
+
function setRefs$2(node, own, forwarded) {
|
|
75
75
|
own.current = node;
|
|
76
76
|
if (typeof forwarded === 'function')
|
|
77
77
|
forwarded(node);
|
|
@@ -203,7 +203,7 @@ const ComboboxParts = forwardRef(({ children, below, onSettle, open, defaultOpen
|
|
|
203
203
|
appendToBody,
|
|
204
204
|
};
|
|
205
205
|
const { rootRef } = engine;
|
|
206
|
-
const rootRefs = useCallback((node) => setRefs$
|
|
206
|
+
const rootRefs = useCallback((node) => setRefs$2(node, rootRef, ref), [rootRef, ref]);
|
|
207
207
|
const comboboxElement = (jsxs("div", { className: classNames(rootClass, bulmaHelperClasses, className), ...rest, ref: rootRefs, children: [jsx(ComboboxContext.Provider, { value: context, children: children }), jsx(StatusRegion, { items: announced, describe: describeEmpty })] }));
|
|
208
208
|
const fieldElement = below === undefined ? (comboboxElement) : (jsxs("div", { children: [comboboxElement, jsx("div", { onPointerDownCapture: engine.markInside, onMouseDown: engine.keepFocus, children: below })] }));
|
|
209
209
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
@@ -236,7 +236,7 @@ const ComboboxInput = forwardRef(({ id, isLoading, controlSize, onKeyDown, onCha
|
|
|
236
236
|
return () => reportLoading(false);
|
|
237
237
|
}, [reportLoading, isLoading]);
|
|
238
238
|
const { inputRef } = engine;
|
|
239
|
-
const inputRefs = useCallback((node) => setRefs$
|
|
239
|
+
const inputRefs = useCallback((node) => setRefs$2(node, inputRef, ref), [inputRef, ref]);
|
|
240
240
|
const { expanded, highlighted } = engine;
|
|
241
241
|
// An `id` of the field's own reaches the label from a layout effect, so
|
|
242
242
|
// in server markup, and the first render, the label's `for` still names
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
2
|
'use client';
|
|
3
3
|
import { useRef, useEffect, useCallback } from 'react';
|
|
4
|
+
import { useLatestRef } from './useLatestRef.js';
|
|
4
5
|
|
|
5
6
|
// INTERNAL: deliberately not exported from src/index.ts.
|
|
6
7
|
/**
|
|
@@ -64,6 +65,37 @@ function useOverlayStack(inStack, modal = true) {
|
|
|
64
65
|
return !above.some(overlay => among !== 'modal' || overlay.modal);
|
|
65
66
|
}, []);
|
|
66
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Calls `onEscape` for an Escape while `active` and the overlay is the
|
|
70
|
+
* topmost one, as `isTopmost` (from `useOverlayStack`) says, and marks the key
|
|
71
|
+
* used with `preventDefault()`, so nothing under it acts on it too.
|
|
72
|
+
*
|
|
73
|
+
* It listens on `window`, so everything inside the overlay has had the key
|
|
74
|
+
* first, and an Escape something there used, such as a popup closing, is
|
|
75
|
+
* left to it. The listener stays put while `onEscape` changes identity, as an
|
|
76
|
+
* inline one does on every render of the parent: it reads the latest one as
|
|
77
|
+
* the key arrives.
|
|
78
|
+
*
|
|
79
|
+
* @function useOverlayEscape
|
|
80
|
+
* @param active - Whether the overlay is open and closes on Escape.
|
|
81
|
+
* @param isTopmost - The overlay's check from `useOverlayStack`.
|
|
82
|
+
* @param onEscape - What closing it does.
|
|
83
|
+
*/
|
|
84
|
+
function useOverlayEscape(active, isTopmost, onEscape) {
|
|
85
|
+
const onEscapeRef = useLatestRef(onEscape);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (!active)
|
|
88
|
+
return undefined;
|
|
89
|
+
const handleKeyDown = (e) => {
|
|
90
|
+
if (e.key !== 'Escape' || e.defaultPrevented || !isTopmost())
|
|
91
|
+
return;
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
onEscapeRef.current();
|
|
94
|
+
};
|
|
95
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
96
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
97
|
+
}, [active, isTopmost, onEscapeRef]);
|
|
98
|
+
}
|
|
67
99
|
|
|
68
|
-
export { isModalOverlayOpen, useOverlayStack };
|
|
100
|
+
export { isModalOverlayOpen, useOverlayEscape, useOverlayStack };
|
|
69
101
|
//# sourceMappingURL=overlayStack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlayStack.js","sources":["../../../src/helpers/overlayStack.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport { useCallback, useEffect, useRef } from 'react';\n\n/** An open overlay's place in the stack. */\ninterface OpenOverlay {\n /**\n * Whether it shuts off the page under it, as a Modal does, so it holds Tab\n * rather than leaving it to an overlay under it. A Sidebar without an\n * overlay doesn't.\n */\n modal: boolean;\n}\n\n/**\n * The open overlays that take part, in the order they opened. Only the last\n * one answers Escape, so one keypress closes one layer, and only the last\n * modal one holds Tab. It's touched in effects and key handlers, never while\n * rendering, so a server render leaves it alone.\n */\nconst openOverlays: OpenOverlay[] = [];\n\n/**\n * Whether a modal overlay is open anywhere in the stack. One that isn't modal\n * and opens while one is leaves focus where it is, since the modal one keeps\n * Tab and a Tab from the new one's controls would only go back to it.\n *\n * @function isModalOverlayOpen\n * @returns Whether any open overlay in the stack is modal.\n */\nexport const isModalOverlayOpen = (): boolean =>\n openOverlays.some(overlay => overlay.modal);\n\n/**\n * Holds this overlay's place in the stack of open overlays while `inStack`\n * is true, from the effect after it opens until the one after it closes.\n * Opening again puts it back on top.\n *\n * Returns a check for whether nothing in the stack sits above this overlay,\n * to call when a key arrives. For an overlay in the stack, that's whether it\n * is the topmost one. For one that isn't, such as a Toast, it's whether no\n * overlay is open at all. Asked about `'modal'` overlays, it counts only the\n * modal ones, which is the check for Tab: a modal overlay keeps holding Tab\n * with one that isn't modal open over it, while that one takes Escape.\n *\n * @function useOverlayStack\n * @param inStack - Whether this overlay is open and takes part.\n * @param modal - Whether this overlay is modal, which it is unless it says\n * otherwise: a Sidebar passes whether it has an overlay. It can change while\n * the overlay is open, and its place stays where it is.\n * @returns A check for whether nothing in the stack, or no modal overlay, is\n * above this overlay.\n */\nexport function useOverlayStack(\n inStack: boolean,\n modal = true\n): (among?: 'modal') => boolean {\n const tokenRef = useRef<OpenOverlay>({ modal });\n\n useEffect(() => {\n tokenRef.current.modal = modal;\n }, [modal]);\n\n useEffect(() => {\n if (!inStack) return undefined;\n const token = tokenRef.current;\n openOverlays.push(token);\n // Takes out this effect's own push. Should it ever be gone already, the\n // stack is left as it is: splicing at -1 would take the topmost overlay\n // instead.\n return () => {\n const index = openOverlays.indexOf(token);\n if (index !== -1) openOverlays.splice(index, 1);\n };\n }, [inStack]);\n\n return useCallback((among?: 'modal') => {\n // Everything above this overlay, or the whole stack for one not in it.\n const above = openOverlays.slice(\n openOverlays.indexOf(tokenRef.current) + 1\n );\n return !above.some(overlay => among !== 'modal' || overlay.modal);\n }, []);\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"overlayStack.js","sources":["../../../src/helpers/overlayStack.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport { useCallback, useEffect, useRef } from 'react';\nimport { useLatestRef } from './useLatestRef';\n\n/** An open overlay's place in the stack. */\ninterface OpenOverlay {\n /**\n * Whether it shuts off the page under it, as a Modal does, so it holds Tab\n * rather than leaving it to an overlay under it. A Sidebar without an\n * overlay doesn't.\n */\n modal: boolean;\n}\n\n/**\n * The open overlays that take part, in the order they opened. Only the last\n * one answers Escape, so one keypress closes one layer, and only the last\n * modal one holds Tab. It's touched in effects and key handlers, never while\n * rendering, so a server render leaves it alone.\n */\nconst openOverlays: OpenOverlay[] = [];\n\n/**\n * Whether a modal overlay is open anywhere in the stack. One that isn't modal\n * and opens while one is leaves focus where it is, since the modal one keeps\n * Tab and a Tab from the new one's controls would only go back to it.\n *\n * @function isModalOverlayOpen\n * @returns Whether any open overlay in the stack is modal.\n */\nexport const isModalOverlayOpen = (): boolean =>\n openOverlays.some(overlay => overlay.modal);\n\n/**\n * Holds this overlay's place in the stack of open overlays while `inStack`\n * is true, from the effect after it opens until the one after it closes.\n * Opening again puts it back on top.\n *\n * Returns a check for whether nothing in the stack sits above this overlay,\n * to call when a key arrives. For an overlay in the stack, that's whether it\n * is the topmost one. For one that isn't, such as a Toast, it's whether no\n * overlay is open at all. Asked about `'modal'` overlays, it counts only the\n * modal ones, which is the check for Tab: a modal overlay keeps holding Tab\n * with one that isn't modal open over it, while that one takes Escape.\n *\n * @function useOverlayStack\n * @param inStack - Whether this overlay is open and takes part.\n * @param modal - Whether this overlay is modal, which it is unless it says\n * otherwise: a Sidebar passes whether it has an overlay. It can change while\n * the overlay is open, and its place stays where it is.\n * @returns A check for whether nothing in the stack, or no modal overlay, is\n * above this overlay.\n */\nexport function useOverlayStack(\n inStack: boolean,\n modal = true\n): (among?: 'modal') => boolean {\n const tokenRef = useRef<OpenOverlay>({ modal });\n\n useEffect(() => {\n tokenRef.current.modal = modal;\n }, [modal]);\n\n useEffect(() => {\n if (!inStack) return undefined;\n const token = tokenRef.current;\n openOverlays.push(token);\n // Takes out this effect's own push. Should it ever be gone already, the\n // stack is left as it is: splicing at -1 would take the topmost overlay\n // instead.\n return () => {\n const index = openOverlays.indexOf(token);\n if (index !== -1) openOverlays.splice(index, 1);\n };\n }, [inStack]);\n\n return useCallback((among?: 'modal') => {\n // Everything above this overlay, or the whole stack for one not in it.\n const above = openOverlays.slice(\n openOverlays.indexOf(tokenRef.current) + 1\n );\n return !above.some(overlay => among !== 'modal' || overlay.modal);\n }, []);\n}\n\n/**\n * Calls `onEscape` for an Escape while `active` and the overlay is the\n * topmost one, as `isTopmost` (from `useOverlayStack`) says, and marks the key\n * used with `preventDefault()`, so nothing under it acts on it too.\n *\n * It listens on `window`, so everything inside the overlay has had the key\n * first, and an Escape something there used, such as a popup closing, is\n * left to it. The listener stays put while `onEscape` changes identity, as an\n * inline one does on every render of the parent: it reads the latest one as\n * the key arrives.\n *\n * @function useOverlayEscape\n * @param active - Whether the overlay is open and closes on Escape.\n * @param isTopmost - The overlay's check from `useOverlayStack`.\n * @param onEscape - What closing it does.\n */\nexport function useOverlayEscape(\n active: boolean,\n isTopmost: () => boolean,\n onEscape: () => void\n): void {\n const onEscapeRef = useLatestRef(onEscape);\n\n useEffect(() => {\n if (!active) return undefined;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape' || e.defaultPrevented || !isTopmost()) return;\n e.preventDefault();\n onEscapeRef.current();\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [active, isTopmost, onEscapeRef]);\n}\n"],"names":[],"mappings":";;;;;AAAA;AAcA;;;;;AAKG;AACH,MAAM,YAAY,GAAkB,EAAE;AAEtC;;;;;;;AAOG;AACI,MAAM,kBAAkB,GAAG,MAChC,YAAY,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK;AAE5C;;;;;;;;;;;;;;;;;;;AAmBG;SACa,eAAe,CAC7B,OAAgB,EAChB,KAAK,GAAG,IAAI,EAAA;IAEZ,MAAM,QAAQ,GAAG,MAAM,CAAc,EAAE,KAAK,EAAE,CAAC;IAE/C,SAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK;AAChC,IAAA,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAEX,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,SAAS;AAC9B,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO;AAC9B,QAAA,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;;;;AAIxB,QAAA,OAAO,MAAK;YACV,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;YACzC,IAAI,KAAK,KAAK,EAAE;AAAE,gBAAA,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AACjD,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAEb,IAAA,OAAO,WAAW,CAAC,CAAC,KAAe,KAAI;;AAErC,QAAA,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAC9B,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAC3C;AACD,QAAA,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;IACnE,CAAC,EAAE,EAAE,CAAC;AACR;AAEA;;;;;;;;;;;;;;;AAeG;SACa,gBAAgB,CAC9B,MAAe,EACf,SAAwB,EACxB,QAAoB,EAAA;AAEpB,IAAA,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC;IAE1C,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,SAAS;AAC7B,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI;AACzC,YAAA,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,SAAS,EAAE;gBAAE;YAC9D,CAAC,CAAC,cAAc,EAAE;YAClB,WAAW,CAAC,OAAO,EAAE;AACvB,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC;QACjD,OAAO,MAAM,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC;IACnE,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACtC;;"}
|
|
@@ -48,6 +48,33 @@ function usePortalContainer() {
|
|
|
48
48
|
const { portalContainer } = useConfig();
|
|
49
49
|
return container => resolvePortalContainer(container || portalContainer);
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Reads Modal's `portal` prop (`boolean | string | HTMLElement`) for a
|
|
53
|
+
* component that takes it: whether the content is in its portal yet, and
|
|
54
|
+
* where it goes.
|
|
55
|
+
*
|
|
56
|
+
* A portal has no server-rendered counterpart, so such a component renders in
|
|
57
|
+
* place on the server and while hydrating, and moves into its portal once the
|
|
58
|
+
* client takes over. Render the content in `Portal` with
|
|
59
|
+
* `disabled={!isPortaled}` and this `container`. Moving remounts the content,
|
|
60
|
+
* so an effect that holds one of its nodes depends on `isPortaled`, `portal`
|
|
61
|
+
* and `defaultTarget`.
|
|
62
|
+
*
|
|
63
|
+
* @function usePortalProp
|
|
64
|
+
* @param portal - The component's `portal` prop.
|
|
65
|
+
* @returns Whether it's portaled now, its `container`, and the provider's
|
|
66
|
+
* target while that places it.
|
|
67
|
+
*/
|
|
68
|
+
function usePortalProp(portal) {
|
|
69
|
+
const hydrated = useIsHydrated();
|
|
70
|
+
const { portalContainer } = useConfig();
|
|
71
|
+
const isPortaled = Boolean(portal) && hydrated;
|
|
72
|
+
return {
|
|
73
|
+
isPortaled,
|
|
74
|
+
container: typeof portal === 'boolean' ? undefined : portal,
|
|
75
|
+
defaultTarget: isPortaled && portal === true ? portalContainer : undefined,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
51
78
|
/**
|
|
52
79
|
* Renders its children into another part of the page, `document.body` unless `container` or a `ConfigProvider` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.
|
|
53
80
|
*
|
|
@@ -111,5 +138,5 @@ function Portal({ children, container, disabled = false }) {
|
|
|
111
138
|
return createPortal(jsx(LocalePortalScope, { target: target, children: children }), target);
|
|
112
139
|
}
|
|
113
140
|
|
|
114
|
-
export { Portal, resolvePortalContainer, usePortalContainer };
|
|
141
|
+
export { Portal, resolvePortalContainer, usePortalContainer, usePortalProp };
|
|
115
142
|
//# sourceMappingURL=portal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sources":["../../../src/helpers/portal.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIsHydrated } from './useIsHydrated';\nimport { useConfig } from './Config';\nimport { LocalePortalScope } from './LocaleProvider';\n\n/**\n * Resolves a portal target: an `HTMLElement` is used directly, a non-empty\n * `string` is treated as a `document.querySelector` selector (falling back to\n * `document.body` when it matches nothing), and any falsy value — `undefined`\n * or the empty string — resolves to `document.body`.\n *\n * The empty string is deliberately treated as \"no target\" rather than passed\n * through: `document.querySelector('')` throws a `SyntaxError`, and callers\n * building a selector from state can easily hand us `''`.\n *\n * @function resolvePortalContainer\n * @param container - The requested portal target, if any.\n * @returns The resolved DOM node to portal into.\n */\nexport function resolvePortalContainer(\n container?: string | HTMLElement\n): HTMLElement {\n if (!container) {\n return document.body;\n }\n if (typeof container === 'string') {\n return (\n (document.querySelector(container) as HTMLElement | null) ?? document.body\n );\n }\n return container;\n}\n\n/**\n * Where a component's portal goes, as a function to call when the portal is\n * created: the target the component was given, else the `portalContainer` a\n * `ConfigProvider` sets, else `document.body`, each read as\n * `resolvePortalContainer` reads it. A component that portals resolves its\n * target through this, so the provider's default reaches it.\n *\n * The hook only reads context, so it is safe to call on the server, ahead of\n * any early return. The function it returns reads the DOM, so call it only\n * where the portal is created, which the server never reaches.\n *\n * @function usePortalContainer\n * @returns A function that takes the component's own target, if any, and\n * returns the DOM node to portal into.\n */\nexport function usePortalContainer(): (\n container?: string | HTMLElement\n) => HTMLElement {\n const { portalContainer } = useConfig();\n return container => resolvePortalContainer(container || portalContainer);\n}\n\n/**\n * Props for the Portal component.\n */\nexport interface PortalProps {\n /** Content to render into the container. */\n children?: React.ReactNode;\n /**\n * Where the content goes: an element, or a `document.querySelector`\n * selector. Omitted or empty, it goes to the `portalContainer` a\n * `ConfigProvider` sets, and to `document.body` when none is set. A\n * selector that matches nothing means `document.body` too. A selector is\n * looked up again on each render, so the\n * content follows the target when it changes. Moving to another target\n * remounts the children and resets their state, which includes a selector\n * that only starts matching after the content has shown in `document.body`.\n * Render the target first, or pass the element once you have it.\n */\n container?: string | HTMLElement;\n /**\n * Render the children in place instead, on the server as well as the\n * client. Lets a component that portals only sometimes keep a single code\n * path.\n * @defaultValue false\n */\n disabled?: boolean;\n}\n\n/**\n * Renders its children into another part of the page, `document.body` unless `container` or a `ConfigProvider` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.\n *\n * React's server renderer can't render a portal, so `Portal` renders nothing\n * on the server and during hydration, and mounts its children in the commit\n * that follows. The first client render then matches the server markup. In an app\n * without server rendering it portals on the first render.\n *\n * React context, such as `ConfigProvider`'s class prefix, reaches the\n * portaled children, and their React events bubble through the React tree.\n * CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`\n * sets its variables on a wrapper element the portaled content has left, so\n * that content sees the page-level theme, and styles scoped to a shadow root\n * don't reach `document.body` at all. To keep them, portal into an element\n * inside the themed area or the shadow root: pass it as `container`, or as\n * the `portalContainer` of a `ConfigProvider` around that area. The second\n * also reaches what the library's components portal, such as Popover's\n * `appendToBody` panel or a `Modal` with `portal`.\n *\n * Inside a `LocaleProvider`, the children keep its `dir` and `lang`. A\n * container inside the provider's own wrapper takes the children as they\n * are, and they follow the provider through the page. Any other,\n * `document.body` included, gets them inside one `<div>` carrying the\n * provider's values, with `display: contents` so it adds no box. It is\n * still an element, so content that must be the container's direct child,\n * a `<tr>` in a `<tbody>`, or that a direct-child selector styles, belongs\n * in a container inside the provider. Which of the two is settled when the\n * children mount, so a change of locale updates them in place rather than\n * remounting them.\n *\n * Tab order and focus follow the DOM too. Content portaled from inside a\n * focus trap is no longer inside the trapped element, so the trap neither\n * reaches it nor holds focus there: render nested overlays inside the\n * trapped element, or give them a trap of their own. To trap portaled\n * content, put `useFocusTrap`'s ref on the element inside the `Portal`.\n *\n * @function\n * @param {PortalProps} props - Props for the Portal component.\n * @returns The portal, the children in place when `disabled`, or nothing\n * before hydration.\n *\n * @example\n * <Portal>\n * <div className=\"box\">Rendered at the end of document.body</div>\n * </Portal>\n *\n * @example\n * // Into a dedicated overlay root\n * <Portal container=\"#overlays\">\n * <CommandPalette />\n * </Portal>\n */\nexport function Portal({ children, container, disabled = false }: PortalProps) {\n const hydrated = useIsHydrated();\n const resolveContainer = usePortalContainer();\n if (disabled) return <>{children}</>;\n if (!hydrated) return null;\n const target = resolveContainer(container);\n return createPortal(\n <LocalePortalScope target={target}>{children}</LocalePortalScope>,\n target\n );\n}\n"],"names":["_jsx","_Fragment"],"mappings":";;;;;;;;AAMA;;;;;;;;;;;;;AAaG;AACG,SAAU,sBAAsB,CACpC,SAAgC,EAAA;IAEhC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,QAAQ,CAAC,IAAI;IACtB;AACA,IAAA,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;AACjC,QAAA,QACG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAwB,IAAI,QAAQ,CAAC,IAAI;IAE9E;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;;;;;;;;;;;;;;AAcG;SACa,kBAAkB,GAAA;AAGhC,IAAA,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE;IACvC,OAAO,SAAS,IAAI,sBAAsB,CAAC,SAAS,IAAI,eAAe,CAAC;AAC1E;AA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDG;AACG,SAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,EAAe,EAAA;AAC3E,IAAA,MAAM,QAAQ,GAAG,aAAa,EAAE;AAChC,IAAA,MAAM,gBAAgB,GAAG,kBAAkB,EAAE;AAC7C,IAAA,IAAI,QAAQ;QAAE,OAAOA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAI;AACpC,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,IAAI;AAC1B,IAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC;AAC1C,IAAA,OAAO,YAAY,CACjBD,GAAA,CAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAqB,EACjE,MAAM,CACP;AACH;;"}
|
|
1
|
+
{"version":3,"file":"portal.js","sources":["../../../src/helpers/portal.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIsHydrated } from './useIsHydrated';\nimport { useConfig } from './Config';\nimport { LocalePortalScope } from './LocaleProvider';\n\n/**\n * Resolves a portal target: an `HTMLElement` is used directly, a non-empty\n * `string` is treated as a `document.querySelector` selector (falling back to\n * `document.body` when it matches nothing), and any falsy value — `undefined`\n * or the empty string — resolves to `document.body`.\n *\n * The empty string is deliberately treated as \"no target\" rather than passed\n * through: `document.querySelector('')` throws a `SyntaxError`, and callers\n * building a selector from state can easily hand us `''`.\n *\n * @function resolvePortalContainer\n * @param container - The requested portal target, if any.\n * @returns The resolved DOM node to portal into.\n */\nexport function resolvePortalContainer(\n container?: string | HTMLElement\n): HTMLElement {\n if (!container) {\n return document.body;\n }\n if (typeof container === 'string') {\n return (\n (document.querySelector(container) as HTMLElement | null) ?? document.body\n );\n }\n return container;\n}\n\n/**\n * Where a component's portal goes, as a function to call when the portal is\n * created: the target the component was given, else the `portalContainer` a\n * `ConfigProvider` sets, else `document.body`, each read as\n * `resolvePortalContainer` reads it. A component that portals resolves its\n * target through this, so the provider's default reaches it.\n *\n * The hook only reads context, so it is safe to call on the server, ahead of\n * any early return. The function it returns reads the DOM, so call it only\n * where the portal is created, which the server never reaches.\n *\n * @function usePortalContainer\n * @returns A function that takes the component's own target, if any, and\n * returns the DOM node to portal into.\n */\nexport function usePortalContainer(): (\n container?: string | HTMLElement\n) => HTMLElement {\n const { portalContainer } = useConfig();\n return container => resolvePortalContainer(container || portalContainer);\n}\n\n/**\n * What a component that takes Modal's `portal` prop does with it now. See\n * `usePortalProp`.\n */\nexport interface PortalPropState {\n /**\n * Whether the content renders in its portal: `portal` is set and\n * hydration is over. Before that it renders in place.\n */\n isPortaled: boolean;\n /**\n * The target to pass `Portal` as its `container`: the selector or element\n * `portal` names, or `undefined` for `true`, which leaves the choice to the\n * `portalContainer` a `ConfigProvider` sets and then `document.body`.\n */\n container?: string | HTMLElement;\n /**\n * The `portalContainer` a `ConfigProvider` sets, while it's what places the\n * content (portaled, with `portal` set to `true`), else `undefined`. A\n * change to it moves the content, so effects that hold its nodes depend\n * on it.\n */\n defaultTarget?: string | HTMLElement;\n}\n\n/**\n * Reads Modal's `portal` prop (`boolean | string | HTMLElement`) for a\n * component that takes it: whether the content is in its portal yet, and\n * where it goes.\n *\n * A portal has no server-rendered counterpart, so such a component renders in\n * place on the server and while hydrating, and moves into its portal once the\n * client takes over. Render the content in `Portal` with\n * `disabled={!isPortaled}` and this `container`. Moving remounts the content,\n * so an effect that holds one of its nodes depends on `isPortaled`, `portal`\n * and `defaultTarget`.\n *\n * @function usePortalProp\n * @param portal - The component's `portal` prop.\n * @returns Whether it's portaled now, its `container`, and the provider's\n * target while that places it.\n */\nexport function usePortalProp(\n portal?: boolean | string | HTMLElement\n): PortalPropState {\n const hydrated = useIsHydrated();\n const { portalContainer } = useConfig();\n const isPortaled = Boolean(portal) && hydrated;\n return {\n isPortaled,\n container: typeof portal === 'boolean' ? undefined : portal,\n defaultTarget: isPortaled && portal === true ? portalContainer : undefined,\n };\n}\n\n/**\n * Props for the Portal component.\n */\nexport interface PortalProps {\n /** Content to render into the container. */\n children?: React.ReactNode;\n /**\n * Where the content goes: an element, or a `document.querySelector`\n * selector. Omitted or empty, it goes to the `portalContainer` a\n * `ConfigProvider` sets, and to `document.body` when none is set. A\n * selector that matches nothing means `document.body` too. A selector is\n * looked up again on each render, so the\n * content follows the target when it changes. Moving to another target\n * remounts the children and resets their state, which includes a selector\n * that only starts matching after the content has shown in `document.body`.\n * Render the target first, or pass the element once you have it.\n */\n container?: string | HTMLElement;\n /**\n * Render the children in place instead, on the server as well as the\n * client. Lets a component that portals only sometimes keep a single code\n * path.\n * @defaultValue false\n */\n disabled?: boolean;\n}\n\n/**\n * Renders its children into another part of the page, `document.body` unless `container` or a `ConfigProvider` says otherwise, so floating content escapes an ancestor's `overflow`, `transform` or stacking context.\n *\n * React's server renderer can't render a portal, so `Portal` renders nothing\n * on the server and during hydration, and mounts its children in the commit\n * that follows. The first client render then matches the server markup. In an app\n * without server rendering it portals on the first render.\n *\n * React context, such as `ConfigProvider`'s class prefix, reaches the\n * portaled children, and their React events bubble through the React tree.\n * CSS inheritance follows the DOM instead: a scoped (non-`isRoot`) `Theme`\n * sets its variables on a wrapper element the portaled content has left, so\n * that content sees the page-level theme, and styles scoped to a shadow root\n * don't reach `document.body` at all. To keep them, portal into an element\n * inside the themed area or the shadow root: pass it as `container`, or as\n * the `portalContainer` of a `ConfigProvider` around that area. The second\n * also reaches what the library's components portal, such as Popover's\n * `appendToBody` panel or a `Modal` with `portal`.\n *\n * Inside a `LocaleProvider`, the children keep its `dir` and `lang`. A\n * container inside the provider's own wrapper takes the children as they\n * are, and they follow the provider through the page. Any other,\n * `document.body` included, gets them inside one `<div>` carrying the\n * provider's values, with `display: contents` so it adds no box. It is\n * still an element, so content that must be the container's direct child,\n * a `<tr>` in a `<tbody>`, or that a direct-child selector styles, belongs\n * in a container inside the provider. Which of the two is settled when the\n * children mount, so a change of locale updates them in place rather than\n * remounting them.\n *\n * Tab order and focus follow the DOM too. Content portaled from inside a\n * focus trap is no longer inside the trapped element, so the trap neither\n * reaches it nor holds focus there: render nested overlays inside the\n * trapped element, or give them a trap of their own. To trap portaled\n * content, put `useFocusTrap`'s ref on the element inside the `Portal`.\n *\n * @function\n * @param {PortalProps} props - Props for the Portal component.\n * @returns The portal, the children in place when `disabled`, or nothing\n * before hydration.\n *\n * @example\n * <Portal>\n * <div className=\"box\">Rendered at the end of document.body</div>\n * </Portal>\n *\n * @example\n * // Into a dedicated overlay root\n * <Portal container=\"#overlays\">\n * <CommandPalette />\n * </Portal>\n */\nexport function Portal({ children, container, disabled = false }: PortalProps) {\n const hydrated = useIsHydrated();\n const resolveContainer = usePortalContainer();\n if (disabled) return <>{children}</>;\n if (!hydrated) return null;\n const target = resolveContainer(container);\n return createPortal(\n <LocalePortalScope target={target}>{children}</LocalePortalScope>,\n target\n );\n}\n"],"names":["_jsx","_Fragment"],"mappings":";;;;;;;;AAMA;;;;;;;;;;;;;AAaG;AACG,SAAU,sBAAsB,CACpC,SAAgC,EAAA;IAEhC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,QAAQ,CAAC,IAAI;IACtB;AACA,IAAA,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;AACjC,QAAA,QACG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAwB,IAAI,QAAQ,CAAC,IAAI;IAE9E;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;;;;;;;;;;;;;;AAcG;SACa,kBAAkB,GAAA;AAGhC,IAAA,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE;IACvC,OAAO,SAAS,IAAI,sBAAsB,CAAC,SAAS,IAAI,eAAe,CAAC;AAC1E;AA2BA;;;;;;;;;;;;;;;;AAgBG;AACG,SAAU,aAAa,CAC3B,MAAuC,EAAA;AAEvC,IAAA,MAAM,QAAQ,GAAG,aAAa,EAAE;AAChC,IAAA,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE;IACvC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ;IAC9C,OAAO;QACL,UAAU;AACV,QAAA,SAAS,EAAE,OAAO,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,MAAM;AAC3D,QAAA,aAAa,EAAE,UAAU,IAAI,MAAM,KAAK,IAAI,GAAG,eAAe,GAAG,SAAS;KAC3E;AACH;AA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDG;AACG,SAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,EAAe,EAAA;AAC3E,IAAA,MAAM,QAAQ,GAAG,aAAa,EAAE;AAChC,IAAA,MAAM,gBAAgB,GAAG,kBAAkB,EAAE;AAC7C,IAAA,IAAI,QAAQ;QAAE,OAAOA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAI;AACpC,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,IAAI;AAC1B,IAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC;AAC1C,IAAA,OAAO,YAAY,CACjBD,GAAA,CAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAqB,EACjE,MAAM,CACP;AACH;;"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { useClientLayoutEffect } from './useClientLayoutEffect.js';
|
|
5
|
+
|
|
6
|
+
// INTERNAL: deliberately not exported from src/index.ts.
|
|
7
|
+
/**
|
|
8
|
+
* The media queries Bulma's `fullhd`, `widescreen`, `desktop` and `tablet`
|
|
9
|
+
* mixins open with, widest first, at Bulma's default breakpoints. A
|
|
10
|
+
* stylesheet lays a component out with those mixins; these tell its script
|
|
11
|
+
* which layout that is. A theme that moves Bulma's breakpoints moves the
|
|
12
|
+
* stylesheet's switch but not these. Narrower than the last one is `mobile`.
|
|
13
|
+
*/
|
|
14
|
+
const VIEWPORT_QUERIES = [
|
|
15
|
+
'screen and (min-width: 1408px)',
|
|
16
|
+
'screen and (min-width: 1216px)',
|
|
17
|
+
'screen and (min-width: 1024px)',
|
|
18
|
+
'screen and (min-width: 769px), print',
|
|
19
|
+
];
|
|
20
|
+
/** `useBulmaViewport`'s answer below the tablet breakpoint. */
|
|
21
|
+
const MOBILE = VIEWPORT_QUERIES.length;
|
|
22
|
+
/** Where Bulma's `widescreen`, `desktop` and `tablet` sit in `VIEWPORT_QUERIES`. */
|
|
23
|
+
const VIEWPORT_INDEX = {
|
|
24
|
+
widescreen: 1,
|
|
25
|
+
desktop: 2,
|
|
26
|
+
tablet: 3,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Which of Bulma's viewports the window is in: the index of the widest
|
|
30
|
+
* `VIEWPORT_QUERIES` entry that matches, `MOBILE` below them all, or `-1`
|
|
31
|
+
* when that isn't known (on the server, before the first layout effect, and
|
|
32
|
+
* whenever `enabled` is off, so a caller that needs no answer subscribes to
|
|
33
|
+
* nothing). It's read in a layout effect, so the first paint after hydration
|
|
34
|
+
* already has it.
|
|
35
|
+
*
|
|
36
|
+
* @function useBulmaViewport
|
|
37
|
+
* @param enabled - Whether the caller needs the viewport at all.
|
|
38
|
+
* @returns The viewport, as described above.
|
|
39
|
+
*/
|
|
40
|
+
function useBulmaViewport(enabled) {
|
|
41
|
+
const [viewport, setViewport] = useState(-1);
|
|
42
|
+
useClientLayoutEffect(() => {
|
|
43
|
+
if (!enabled || typeof window.matchMedia !== 'function')
|
|
44
|
+
return undefined;
|
|
45
|
+
const lists = VIEWPORT_QUERIES.map(query => window.matchMedia(query));
|
|
46
|
+
const update = () => {
|
|
47
|
+
const index = lists.findIndex(list => list.matches);
|
|
48
|
+
setViewport(index < 0 ? MOBILE : index);
|
|
49
|
+
};
|
|
50
|
+
update();
|
|
51
|
+
lists.forEach(list => list.addEventListener('change', update));
|
|
52
|
+
return () => lists.forEach(list => list.removeEventListener('change', update));
|
|
53
|
+
}, [enabled]);
|
|
54
|
+
return enabled ? viewport : -1;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether the window is at or past one of Bulma's breakpoints, at its default
|
|
58
|
+
* width, through the one media query Bulma's mixin for it opens with, so a
|
|
59
|
+
* caller re-renders only when the window crosses that breakpoint. `null`
|
|
60
|
+
* until it's known: on the server, and before the first layout effect. Where
|
|
61
|
+
* `matchMedia` isn't there, it's `true`, the wide layout a server renders.
|
|
62
|
+
*
|
|
63
|
+
* @function useBulmaBreakpoint
|
|
64
|
+
* @param breakpoint - The breakpoint: `tablet`, `desktop` or `widescreen`.
|
|
65
|
+
* @returns Whether the window is at or past it, or `null`.
|
|
66
|
+
*/
|
|
67
|
+
function useBulmaBreakpoint(breakpoint) {
|
|
68
|
+
const [atOrPast, setAtOrPast] = useState(null);
|
|
69
|
+
useClientLayoutEffect(() => {
|
|
70
|
+
const list = typeof window.matchMedia === 'function'
|
|
71
|
+
? window.matchMedia(VIEWPORT_QUERIES[VIEWPORT_INDEX[breakpoint]])
|
|
72
|
+
: null;
|
|
73
|
+
const update = () => setAtOrPast(list ? list.matches : true);
|
|
74
|
+
update();
|
|
75
|
+
list?.addEventListener('change', update);
|
|
76
|
+
return () => list?.removeEventListener('change', update);
|
|
77
|
+
}, [breakpoint]);
|
|
78
|
+
return atOrPast;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { MOBILE, useBulmaBreakpoint, useBulmaViewport };
|
|
82
|
+
//# sourceMappingURL=useBulmaViewport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBulmaViewport.js","sources":["../../../src/helpers/useBulmaViewport.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport { useState } from 'react';\nimport { useClientLayoutEffect } from './useClientLayoutEffect';\n\n/**\n * The media queries Bulma's `fullhd`, `widescreen`, `desktop` and `tablet`\n * mixins open with, widest first, at Bulma's default breakpoints. A\n * stylesheet lays a component out with those mixins; these tell its script\n * which layout that is. A theme that moves Bulma's breakpoints moves the\n * stylesheet's switch but not these. Narrower than the last one is `mobile`.\n */\nconst VIEWPORT_QUERIES = [\n 'screen and (min-width: 1408px)',\n 'screen and (min-width: 1216px)',\n 'screen and (min-width: 1024px)',\n 'screen and (min-width: 769px), print',\n];\n\n/** `useBulmaViewport`'s answer below the tablet breakpoint. */\nexport const MOBILE = VIEWPORT_QUERIES.length;\n\n/** Where Bulma's `widescreen`, `desktop` and `tablet` sit in `VIEWPORT_QUERIES`. */\nconst VIEWPORT_INDEX = {\n widescreen: 1,\n desktop: 2,\n tablet: 3,\n} as const;\n\n/**\n * Which of Bulma's viewports the window is in: the index of the widest\n * `VIEWPORT_QUERIES` entry that matches, `MOBILE` below them all, or `-1`\n * when that isn't known (on the server, before the first layout effect, and\n * whenever `enabled` is off, so a caller that needs no answer subscribes to\n * nothing). It's read in a layout effect, so the first paint after hydration\n * already has it.\n *\n * @function useBulmaViewport\n * @param enabled - Whether the caller needs the viewport at all.\n * @returns The viewport, as described above.\n */\nexport function useBulmaViewport(enabled: boolean): number {\n const [viewport, setViewport] = useState(-1);\n\n useClientLayoutEffect(() => {\n if (!enabled || typeof window.matchMedia !== 'function') return undefined;\n const lists = VIEWPORT_QUERIES.map(query => window.matchMedia(query));\n const update = () => {\n const index = lists.findIndex(list => list.matches);\n setViewport(index < 0 ? MOBILE : index);\n };\n update();\n lists.forEach(list => list.addEventListener('change', update));\n return () =>\n lists.forEach(list => list.removeEventListener('change', update));\n }, [enabled]);\n\n return enabled ? viewport : -1;\n}\n\n/**\n * Whether the window is at or past one of Bulma's breakpoints, at its default\n * width, through the one media query Bulma's mixin for it opens with, so a\n * caller re-renders only when the window crosses that breakpoint. `null`\n * until it's known: on the server, and before the first layout effect. Where\n * `matchMedia` isn't there, it's `true`, the wide layout a server renders.\n *\n * @function useBulmaBreakpoint\n * @param breakpoint - The breakpoint: `tablet`, `desktop` or `widescreen`.\n * @returns Whether the window is at or past it, or `null`.\n */\nexport function useBulmaBreakpoint(\n breakpoint: keyof typeof VIEWPORT_INDEX\n): boolean | null {\n const [atOrPast, setAtOrPast] = useState<boolean | null>(null);\n\n useClientLayoutEffect(() => {\n const list =\n typeof window.matchMedia === 'function'\n ? window.matchMedia(VIEWPORT_QUERIES[VIEWPORT_INDEX[breakpoint]])\n : null;\n const update = () => setAtOrPast(list ? list.matches : true);\n update();\n list?.addEventListener('change', update);\n return () => list?.removeEventListener('change', update);\n }, [breakpoint]);\n\n return atOrPast;\n}\n"],"names":[],"mappings":";;;;;AAAA;AAIA;;;;;;AAMG;AACH,MAAM,gBAAgB,GAAG;IACvB,gCAAgC;IAChC,gCAAgC;IAChC,gCAAgC;IAChC,sCAAsC;CACvC;AAED;AACO,MAAM,MAAM,GAAG,gBAAgB,CAAC;AAEvC;AACA,MAAM,cAAc,GAAG;AACrB,IAAA,UAAU,EAAE,CAAC;AACb,IAAA,OAAO,EAAE,CAAC;AACV,IAAA,MAAM,EAAE,CAAC;CACD;AAEV;;;;;;;;;;;AAWG;AACG,SAAU,gBAAgB,CAAC,OAAgB,EAAA;IAC/C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;IAE5C,qBAAqB,CAAC,MAAK;QACzB,IAAI,CAAC,OAAO,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;AAAE,YAAA,OAAO,SAAS;AACzE,QAAA,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,MAAK;AAClB,YAAA,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC;AACnD,YAAA,WAAW,CAAC,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC;AACzC,QAAA,CAAC;AACD,QAAA,MAAM,EAAE;AACR,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9D,OAAO,MACL,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACrE,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;IAEb,OAAO,OAAO,GAAG,QAAQ,GAAG,EAAE;AAChC;AAEA;;;;;;;;;;AAUG;AACG,SAAU,kBAAkB,CAChC,UAAuC,EAAA;IAEvC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC;IAE9D,qBAAqB,CAAC,MAAK;AACzB,QAAA,MAAM,IAAI,GACR,OAAO,MAAM,CAAC,UAAU,KAAK;AAC3B,cAAE,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;cAC9D,IAAI;AACV,QAAA,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;AAC5D,QAAA,MAAM,EAAE;AACR,QAAA,IAAI,EAAE,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;QACxC,OAAO,MAAM,IAAI,EAAE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC;AAC1D,IAAA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;AAEhB,IAAA,OAAO,QAAQ;AACjB;;"}
|