@allxsmith/bestax-bulma 5.57.4 → 5.58.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/Avatars.js +2 -2
- package/dist/esm/components/Avatars.js.map +1 -1
- package/dist/esm/components/Badge.js +2 -2
- package/dist/esm/components/Badge.js.map +1 -1
- package/dist/esm/components/Pagination.js +2 -2
- package/dist/esm/components/Pagination.js.map +1 -1
- package/dist/esm/components/Steps.js +2 -2
- package/dist/esm/components/Steps.js.map +1 -1
- package/dist/esm/components/TreeView.js +7 -5
- package/dist/esm/components/TreeView.js.map +1 -1
- package/dist/esm/components/useDataTable.js +2 -2
- package/dist/esm/components/useDataTable.js.map +1 -1
- package/dist/esm/elements/NumberFormatter.js +42 -0
- package/dist/esm/elements/NumberFormatter.js.map +1 -0
- package/dist/esm/elements/RingProgress.js +2 -2
- package/dist/esm/elements/RingProgress.js.map +1 -1
- package/dist/esm/form/Dropzone.js +2 -2
- package/dist/esm/form/Dropzone.js.map +1 -1
- package/dist/esm/form/File.js +2 -2
- package/dist/esm/form/File.js.map +1 -1
- package/dist/esm/form/Rate.js +2 -2
- package/dist/esm/form/Rate.js.map +1 -1
- package/dist/esm/form/Slider.js +2 -2
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/Taginput.js +2 -2
- package/dist/esm/form/Taginput.js.map +1 -1
- package/dist/esm/form/_colorInternals/pickerState.js +2 -2
- package/dist/esm/form/_colorInternals/pickerState.js.map +1 -1
- package/dist/esm/helpers/LocaleProvider.js +13 -6
- package/dist/esm/helpers/LocaleProvider.js.map +1 -1
- package/dist/esm/helpers/localeFormat.js +196 -36
- package/dist/esm/helpers/localeFormat.js.map +1 -1
- package/dist/esm/helpers/useTreeView.js +54 -20
- package/dist/esm/helpers/useTreeView.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +312 -76
- 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/TreeView.d.ts +20 -11
- package/dist/types/elements/NumberFormatter.d.ts +62 -0
- package/dist/types/helpers/LocaleProvider.d.ts +7 -0
- package/dist/types/helpers/localeFormat.d.ts +30 -8
- package/dist/types/helpers/useTreeView.d.ts +12 -6
- package/dist/types/index.d.ts +3 -0
- package/dist/types-cjs/components/TreeView.d.ts +20 -11
- package/dist/types-cjs/elements/NumberFormatter.d.ts +62 -0
- package/dist/types-cjs/helpers/LocaleProvider.d.ts +7 -0
- package/dist/types-cjs/helpers/localeFormat.d.ts +30 -8
- package/dist/types-cjs/helpers/useTreeView.d.ts +12 -6
- package/dist/types-cjs/index.d.ts +3 -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/form/_field.scss +40 -0
- package/src/scss/form/_index.scss +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Taginput.js","sources":["../../../src/form/Taginput.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n} from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useConfig, useIconLibrary } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { isEventInside } from '../helpers/shadowDom';\nimport { useLocaleMatcher, useNumberFormat } from '../helpers/localeFormat';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n useFieldsetDisabled,\n} from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { Icon } from '../elements/Icon';\n\n/**\n * Represents a tag item object with a value and optional label.\n */\nexport interface TaginputItem {\n /** The tag value. */\n value: string;\n /** Display label (optional). */\n label?: string;\n [key: string]: unknown;\n}\n\n/** A tag can be either a TaginputItem object or a plain string. */\nexport type TaginputTag = TaginputItem | string;\n\ntype IconLibrary = 'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols';\n\n// An IME that's composing owns every key: Enter confirms what it composed,\n// the arrows move through its candidates, and Escape cancels it. Safari can\n// say so with `keyCode` 229 rather than `isComposing` (#1102).\nconst isComposing = (e: React.KeyboardEvent): boolean =>\n e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229;\n\n/**\n * Props for the Taginput component.\n * Inside an outer `Field`, or a `Control` with no `Field` around it, it\n * renders no `Field` of its own. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface TaginputProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label. Automatically associated with the text input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here; it then replaces the `aria-label=\"Add tag\"` fallback too. With `data`, the label naming the input also names the open suggestion list, through `aria-labelledby`, when it has an id: this label always does, and an outer `Field`'s does unless you wired it by hand without an `id` in its `labelProps`. Otherwise the list is named \"Suggestions\". */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). With `data`, while the label names the input, the suggestion list's `aria-labelledby` points at it, through an `id` here when you give one and a generated one otherwise. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Applied to the inner text input (the labellable control), not the wrapper div. */\n id?: string;\n /** The current tags (controlled). */\n value?: TaginputTag[];\n /** Default tags (uncontrolled). */\n defaultValue?: TaginputTag[];\n /**\n * Autocomplete suggestions. With `data` set, even to an empty array, the\n * text input is a `role=\"combobox\"` that controls the suggestion list and\n * points `aria-activedescendant` at the highlighted suggestion. Without it\n * there's no list, so the input stays a plain text field. The list shows\n * the suggestions that contain what's typed, ignoring case, and inside a\n * `LocaleProvider` with a `locale`, ignoring accents too where that\n * language does, so \"cafe\" finds \"Café\".\n */\n data?: string[];\n /** Placeholder text when no tags. */\n placeholder?: string;\n /** Object property to use as display field. */\n field?: string;\n /** Allow creating new tags not in suggestions. */\n allowNew?: boolean;\n /** Allow duplicate tags. */\n allowDuplicates?: boolean;\n /** Open autocomplete dropdown on focus. */\n openOnFocus?: boolean;\n /** Remove tag on backspace. Default: true. */\n removeOnKeys?: boolean;\n /** Keys to confirm tag creation. Default: ['Enter', ',']. */\n confirmKeys?: string[];\n /** Show close button on tags. Default: true. */\n closable?: boolean;\n /** Attach tags visually. */\n attached?: boolean;\n /**\n * Maximum number of tags allowed. At the limit the text input stays but\n * turns read-only, so focus stays put and the label still names it. It\n * takes no more tags and the suggestion list stays closed. Backspace (with\n * `removeOnKeys`) or a tag's remove button makes room again. While the\n * counter shows, it describes the input.\n */\n maxTags?: number;\n /** Maximum length of input. */\n maxlength?: number;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input is read-only. */\n readonly?: boolean;\n /** Applies rounded corners to the tags. */\n rounded?: boolean;\n /** Truncates long tag text with ellipsis. */\n ellipsis?: boolean;\n /**\n * Shows a counter of the number of tags, written the way the `locale` of\n * a `LocaleProvider` around it writes numbers.\n */\n hasCounter?: boolean;\n /**\n * Characters that split pasted text into tags. Each part goes through the\n * same checks as a typed tag, against the tags before it, the paste's own\n * included, and adding stops at `maxTags`. `onChange` fires once for the\n * whole paste, and `onAdd` once for each tag it adds.\n */\n onPasteSeparators?: string[];\n /** Validation function called before adding a tag. */\n beforeAdding?: (tag: string) => boolean;\n /** Custom function for creating tag objects from input. */\n createTag?: (input: string) => TaginputTag;\n /** Keeps the first autocomplete suggestion highlighted. */\n keepFirst?: boolean;\n /** Keeps the autocomplete dropdown open after selection. */\n keepOpen?: boolean;\n /**\n * Shows a loading spinner in the input.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n */\n loading?: boolean;\n /** ARIA label for tag close buttons. */\n ariaCloseLabel?: string;\n /** Icon name for the input field. */\n icon?: string;\n /** Icon library to use. */\n iconLibrary?: IconLibrary;\n /** Icon style variant (e.g., 'solid', 'outlined'). */\n iconVariant?: string;\n /** Additional icon modifiers. */\n iconFeatures?: string | string[];\n /** Input color variant. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Tag color variant. */\n tagColor?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'dark'\n | 'light';\n /** Size variant. */\n size?: 'small' | 'medium' | 'large';\n /** Form field name. When set, one hidden input per tag is rendered. */\n name?: string;\n /** Optional id of the form the hidden inputs belong to. */\n form?: string;\n /** Callback when tags change. */\n onChange?: (tags: TaginputTag[]) => void;\n /** Callback when tag is added. */\n onAdd?: (tag: TaginputTag) => void;\n /** Callback when tag is removed. */\n onRemove?: (tag: TaginputTag, index: number) => void;\n /** Callback when typing in input. */\n onTyping?: (value: string) => void;\n /** Custom render for tags. */\n tagTemplate?: (tag: TaginputTag) => React.ReactNode;\n}\n\n/**\n * The `Taginput` component provides a tag/chip input field for managing multiple tags.\n *\n * @function\n * @param {TaginputProps} props - Props for the Taginput component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the input element.\n * @returns {JSX.Element} The rendered taginput component.\n *\n * @example\n * // Basic usage\n * <Taginput\n * placeholder=\"Add a tag...\"\n * onChange={(tags) => console.log(tags)}\n * />\n *\n * @example\n * // With autocomplete\n * <Taginput\n * data={['React', 'Vue', 'Angular', 'Svelte']}\n * allowNew={false}\n * placeholder=\"Select frameworks...\"\n * />\n */\nexport const Taginput = forwardRef<HTMLInputElement, TaginputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue = [],\n data: dataProp,\n placeholder,\n field = 'label',\n allowNew = true,\n allowDuplicates = false,\n openOnFocus = false,\n removeOnKeys = true,\n confirmKeys = ['Enter', ','],\n closable = true,\n attached = false,\n maxTags,\n maxlength,\n disabled: disabledProp,\n readonly = false,\n rounded = false,\n ellipsis = false,\n hasCounter = true,\n onPasteSeparators = [','],\n beforeAdding,\n createTag,\n keepFirst = false,\n keepOpen = true,\n loading = false,\n ariaCloseLabel,\n icon,\n iconLibrary: iconLibraryProp,\n iconVariant,\n iconFeatures,\n color,\n tagColor,\n size,\n onChange,\n onAdd,\n onRemove,\n onTyping,\n tagTemplate,\n name,\n form,\n id,\n className,\n ...props\n },\n ref\n ) => {\n const disabled = useFieldsetDisabled(disabledProp);\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Taginput', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const { classPrefix } = useConfig();\n const defaultIconLibrary = useIconLibrary();\n const formatNumber = useNumberFormat();\n const matchText = useLocaleMatcher();\n const resolvedLibrary = iconLibraryProp || defaultIconLibrary || 'fa';\n const pcn = (\n ...args: (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[]\n ) => prefixedClassNames(classPrefix, ...args);\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const [internalTags, setInternalTags] =\n useState<TaginputTag[]>(defaultValue);\n const [inputValue, setInputValue] = useState('');\n const [isActive, setIsActive] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const counterId = `${baseId}-counter`;\n\n // With `data` the input offers suggestions, so it's a combobox, even\n // while none match. Without it there's never a list, so it stays a plain\n // text field.\n const hasSuggestions = dataProp !== undefined;\n const data = dataProp ?? [];\n\n // Use controlled or internal tags\n const tags = controlledValue !== undefined ? controlledValue : internalTags;\n\n const isMaxReached = maxTags !== undefined && tags.length >= maxTags;\n // The suggestion list points `aria-labelledby` at the label that names\n // the input, so with suggestions it needs that label's id.\n const {\n controlId,\n fieldLabelProps,\n labelled,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: hasSuggestions,\n });\n\n // Get display value from tag\n const getDisplayValue = (tag: TaginputTag): string => {\n if (typeof tag === 'string') return tag;\n const fieldValue = tag[field];\n if (typeof fieldValue === 'string') return fieldValue;\n return tag.value || '';\n };\n\n // Filter autocomplete data\n const filteredData = data.filter(item => {\n const displayValue = item.toLowerCase();\n const matchesInput = matchText\n ? matchText(item, inputValue)\n : displayValue.includes(inputValue.toLowerCase());\n const notAlreadyAdded =\n allowDuplicates ||\n !tags.some(tag => getDisplayValue(tag).toLowerCase() === displayValue);\n const hasInput = inputValue || (openOnFocus && isActive);\n return matchesInput && notAlreadyAdded && hasInput;\n });\n // At the tag limit the list stays closed, since it could only offer tags\n // past the limit (#1087).\n const listOpen = isActive && !isMaxReached && filteredData.length > 0;\n\n // keepFirst: auto-highlight first item when dropdown opens\n useEffect(() => {\n if (keepFirst && isActive && filteredData.length > 0) {\n setHighlightedIndex(0);\n }\n }, [keepFirst, isActive, filteredData.length]);\n\n // Update tags\n const updateTags = useCallback(\n (newTags: TaginputTag[]) => {\n if (controlledValue === undefined) {\n setInternalTags(newTags);\n }\n onChange?.(newTags);\n },\n [controlledValue, onChange]\n );\n\n // Add tags from text typed, pasted or picked from the list. Each one is\n // checked against the tags before it, this batch's included, so a paste\n // of several adds them all in one change (#1101). Only `createTag` turns\n // text into an object.\n const addTags = useCallback(\n (values: string[]) => {\n if (disabled || readonly) return;\n\n let next = tags;\n const added: TaginputTag[] = [];\n for (const value of values) {\n // A paste can bring more tags than there's room for, and at the\n // limit the read-only input still takes Enter.\n if (maxTags !== undefined && next.length >= maxTags) break;\n\n const displayValue = value.trim();\n if (!displayValue) continue;\n const lower = displayValue.toLowerCase();\n\n // Duplicates, data and the dropdown filter all compare\n // case-insensitively.\n if (\n !allowDuplicates &&\n next.some(tag => getDisplayValue(tag).toLowerCase() === lower)\n )\n continue;\n\n // Without allowNew, only a suggestion can become a tag.\n if (!allowNew && !data.some(d => d.toLowerCase() === lower)) continue;\n\n if (beforeAdding && !beforeAdding(displayValue)) continue;\n\n const tag = createTag ? createTag(displayValue) : displayValue;\n next = [...next, tag];\n added.push(tag);\n }\n if (added.length === 0) return;\n\n updateTags(next);\n added.forEach(tag => onAdd?.(tag));\n setInputValue('');\n if (!keepOpen) {\n setIsActive(false);\n }\n setHighlightedIndex(-1);\n },\n [\n disabled,\n readonly,\n tags,\n maxTags,\n allowDuplicates,\n allowNew,\n data,\n field,\n updateTags,\n onAdd,\n beforeAdding,\n createTag,\n keepOpen,\n ]\n );\n\n // Remove tag\n const removeTag = useCallback(\n (index: number) => {\n /* istanbul ignore next: both triggers (delete button click, Backspace handler) are already gated on disabled/readonly */\n if (disabled || readonly) return;\n\n const removedTag = tags[index];\n const newTags = tags.filter((_, i) => i !== index);\n updateTags(newTags);\n onRemove?.(removedTag, index);\n },\n [disabled, readonly, tags, updateTags, onRemove]\n );\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n\n // Check if a confirm key was typed\n const lastChar = newValue.slice(-1);\n if (confirmKeys.includes(lastChar) && lastChar !== 'Enter') {\n const valueWithoutKey = newValue.slice(0, -1).trim();\n if (valueWithoutKey) {\n addTags([valueWithoutKey]);\n }\n return;\n }\n\n setInputValue(newValue);\n onTyping?.(newValue);\n\n if (newValue && data.length > 0) {\n setIsActive(true);\n }\n },\n [confirmKeys, addTags, onTyping, data.length]\n );\n\n // Handle paste\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n if (onPasteSeparators.length === 0) return;\n\n const pastedText = e.clipboardData.getData('text');\n // Check if any separator exists in the pasted text\n const hasSeparator = onPasteSeparators.some(sep =>\n pastedText.includes(sep)\n );\n\n if (!hasSeparator) return;\n\n e.preventDefault();\n\n // Build a character class from all separators. A `-` is escaped\n // too, since between two others it would make a range.\n const escapedSeparators = onPasteSeparators.map(s =>\n s.replace(/[-.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n );\n const regex = new RegExp(`[${escapedSeparators.join('')}]`);\n\n addTags(pastedText.split(regex));\n },\n [onPasteSeparators, addTags]\n );\n\n // Handle focus\n const handleFocus = useCallback(() => {\n if (openOnFocus && data.length > 0 && !disabled) {\n setIsActive(true);\n }\n }, [openOnFocus, data.length, disabled]);\n\n // Reaching the limit dismisses the list the way a click outside does, so\n // making room later doesn't bring it back unasked. It's an effect, not a\n // step in addTag, because a click on a suggestion also bubbles to the\n // container, whose focus on the input reopens the list in that same\n // event, and because a controlled value can reach the limit too.\n useEffect(() => {\n if (isMaxReached) {\n setIsActive(false);\n setHighlightedIndex(-1);\n }\n }, [isMaxReached]);\n\n // Handle click outside\n useEffect(() => {\n if (!isActive) return undefined;\n\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !isEventInside(e, containerRef.current)) {\n setIsActive(false);\n setHighlightedIndex(-1);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }, [isActive]);\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled || readonly || isComposing(e)) return;\n\n // Handle confirm keys\n if (confirmKeys.includes(e.key)) {\n e.preventDefault();\n if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {\n addTags([filteredData[highlightedIndex]]);\n } else if (inputValue.trim()) {\n addTags([inputValue]);\n }\n return;\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!isActive && data.length > 0) {\n setIsActive(true);\n } else {\n setHighlightedIndex(prev =>\n prev < filteredData.length - 1 ? prev + 1 : prev\n );\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));\n break;\n case 'Backspace':\n if (removeOnKeys && !inputValue && tags.length > 0) {\n e.preventDefault();\n removeTag(tags.length - 1);\n }\n break;\n case 'Escape':\n // Closing the suggestions claims the key, so a Modal around the\n // field stays open. With none showing, the key goes on to it.\n if (listOpen) e.preventDefault();\n setIsActive(false);\n setHighlightedIndex(-1);\n break;\n }\n },\n [\n disabled,\n readonly,\n confirmKeys,\n highlightedIndex,\n filteredData,\n addTags,\n inputValue,\n isActive,\n listOpen,\n data.length,\n removeOnKeys,\n tags.length,\n removeTag,\n ]\n );\n\n // Combined ref\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n }\n },\n [ref]\n );\n\n // Focus input when container is clicked\n const handleContainerClick = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Generate classes\n const taginputClasses = pcn('taginput', {\n 'is-active': isActive,\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-disabled': disabled,\n 'is-rounded': rounded,\n 'is-ellipsis': ellipsis,\n });\n\n const containerClasses = pcn('taginput-container', {\n 'is-attached': attached,\n 'has-icons-left': !!icon,\n });\n\n const inputClasses = pcn('input', {\n [`is-${size}`]: !!size,\n });\n\n const tagClasses = pcn('tag', {\n [`is-${tagColor}`]: !!tagColor,\n [`is-${size}`]: !!size,\n });\n\n const combinedClasses = classNames(\n taginputClasses,\n bulmaHelperClasses,\n className\n );\n\n // Counter text\n const showCounter =\n hasCounter && (maxTags !== undefined || maxlength !== undefined);\n const write = formatNumber ?? String;\n const counterText =\n maxTags !== undefined\n ? `${write(tags.length)} / ${write(maxTags)}`\n : maxlength !== undefined\n ? `${write(inputValue.length)} / ${write(maxlength)}`\n : '';\n\n const counterClasses = pcn('help', 'counter');\n const tagsClasses = pcn('tags');\n const dropdownMenuClasses = pcn('dropdown-menu', 'is-active');\n const dropdownContentClasses = pcn('dropdown-content');\n const iconRightClass = pcn('icon', 'is-right');\n const loaderClass = pcn('loader', 'is-loading');\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The combobox controls its listbox and points at the highlighted option,\n // the way Autocomplete's does. The listbox takes its name from the label\n // that names the combobox, the one this renders or a surrounding Field's,\n // and keeps a fallback name when no label names it or the one that does\n // has no id to point at. While no suggestion matches there's no listbox,\n // so the combobox is collapsed and points at nothing. It skips a\n // highlighted suggestion that's blank once trimmed, since that one can't\n // become a tag, and the option it points at is the one marked selected.\n const optionId = (index: number) => `${listboxId}-${index}`;\n const activeOptionId =\n listOpen && filteredData[highlightedIndex]?.trim()\n ? optionId(highlightedIndex)\n : undefined;\n const comboboxProps: React.InputHTMLAttributes<HTMLInputElement> = {\n role: 'combobox',\n 'aria-expanded': listOpen,\n 'aria-controls': listOpen ? listboxId : undefined,\n 'aria-activedescendant': activeOptionId,\n 'aria-haspopup': 'listbox',\n 'aria-autocomplete': 'list',\n };\n\n const taginputElement = (\n <div\n ref={containerRef}\n className={combinedClasses}\n onClick={handleContainerClick}\n {...rest}\n >\n <div className={containerClasses}>\n {icon && (\n <Icon\n name={icon}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n containerClassName={pcn('icon', 'is-left')}\n />\n )}\n <div className={tagsClasses}>\n {tags.map((tag, index) => {\n const displayVal = getDisplayValue(tag);\n return (\n <span key={index} className={tagClasses}>\n {tagTemplate ? (\n tagTemplate(tag)\n ) : ellipsis ? (\n <span title={displayVal}>{displayVal}</span>\n ) : (\n displayVal\n )}\n {closable && !disabled && !readonly && (\n <button\n type=\"button\"\n className={pcn('delete', 'is-small')}\n onClick={e => {\n e.stopPropagation();\n removeTag(index);\n }}\n aria-label={ariaCloseLabel || `Remove ${displayVal}`}\n />\n )}\n </span>\n );\n })}\n <input\n ref={combinedRef}\n type=\"text\"\n className={inputClasses}\n id={controlId}\n value={inputValue}\n placeholder={tags.length === 0 ? placeholder : undefined}\n disabled={disabled}\n // Read-only at the tag limit rather than gone, so focus stays\n // put and a label keeps naming it, and Backspace still makes\n // room (#1103).\n readOnly={readonly || isMaxReached}\n maxLength={maxlength}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n {...(hasSuggestions && comboboxProps)}\n // Fallback name, dropped only when a rendered label actually\n // targets this input, its own or a surrounding Field's\n // (aria-label would win otherwise). A label pointing elsewhere\n // keeps the fallback so the input is never nameless.\n aria-label={labelled ? undefined : 'Add tag'}\n // The counter, while it shows, describes the input, so at the\n // limit it says why the field takes no more.\n aria-describedby={showCounter ? counterId : undefined}\n />\n </div>\n {loading && (\n <span className={iconRightClass}>\n <span className={loaderClass} />\n </span>\n )}\n </div>\n\n {listOpen && (\n <div className={dropdownMenuClasses}>\n <div\n ref={dropdownRef}\n id={listboxId}\n className={dropdownContentClasses}\n role=\"listbox\"\n aria-labelledby={listLabelId}\n aria-label={listLabelId ? undefined : 'Suggestions'}\n >\n {filteredData.map((item, index) => (\n <a\n key={index}\n id={optionId(index)}\n className={pcn('dropdown-item', {\n 'is-active': index === highlightedIndex,\n })}\n onClick={() => addTags([item])}\n onMouseEnter={() => setHighlightedIndex(index)}\n role=\"option\"\n aria-selected={optionId(index) === activeOptionId}\n >\n {item}\n </a>\n ))}\n </div>\n </div>\n )}\n\n {showCounter && (\n <small id={counterId} className={counterClasses}>\n {counterText}\n </small>\n )}\n\n {name &&\n tags.map((tag, i) => (\n <input\n key={`tag-input-${i}`}\n type=\"hidden\"\n name={name}\n value={getDisplayValue(tag)}\n form={form}\n />\n ))}\n </div>\n );\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 {taginputElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {taginputElement}\n {messageEl}\n </>\n );\n }\n);\n\nTaginput.displayName = 'Taginput';\n\n/** @deprecated Use `Taginput` — same component. */\nexport const TagInput = Taginput;\n\n/** @deprecated Use `TaginputProps`. */\nexport type TagInputProps = TaginputProps;\n\nexport default Taginput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Taginput.js","sources":["../../../src/form/Taginput.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n} from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useConfig, useIconLibrary } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { isEventInside } from '../helpers/shadowDom';\nimport {\n useLocaleMatcher,\n useScopedNumberFormat,\n} from '../helpers/localeFormat';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n useFieldsetDisabled,\n} from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { Icon } from '../elements/Icon';\n\n/**\n * Represents a tag item object with a value and optional label.\n */\nexport interface TaginputItem {\n /** The tag value. */\n value: string;\n /** Display label (optional). */\n label?: string;\n [key: string]: unknown;\n}\n\n/** A tag can be either a TaginputItem object or a plain string. */\nexport type TaginputTag = TaginputItem | string;\n\ntype IconLibrary = 'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols';\n\n// An IME that's composing owns every key: Enter confirms what it composed,\n// the arrows move through its candidates, and Escape cancels it. Safari can\n// say so with `keyCode` 229 rather than `isComposing` (#1102).\nconst isComposing = (e: React.KeyboardEvent): boolean =>\n e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229;\n\n/**\n * Props for the Taginput component.\n * Inside an outer `Field`, or a `Control` with no `Field` around it, it\n * renders no `Field` of its own. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface TaginputProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label. Automatically associated with the text input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here; it then replaces the `aria-label=\"Add tag\"` fallback too. With `data`, the label naming the input also names the open suggestion list, through `aria-labelledby`, when it has an id: this label always does, and an outer `Field`'s does unless you wired it by hand without an `id` in its `labelProps`. Otherwise the list is named \"Suggestions\". */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). With `data`, while the label names the input, the suggestion list's `aria-labelledby` points at it, through an `id` here when you give one and a generated one otherwise. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Applied to the inner text input (the labellable control), not the wrapper div. */\n id?: string;\n /** The current tags (controlled). */\n value?: TaginputTag[];\n /** Default tags (uncontrolled). */\n defaultValue?: TaginputTag[];\n /**\n * Autocomplete suggestions. With `data` set, even to an empty array, the\n * text input is a `role=\"combobox\"` that controls the suggestion list and\n * points `aria-activedescendant` at the highlighted suggestion. Without it\n * there's no list, so the input stays a plain text field. The list shows\n * the suggestions that contain what's typed, ignoring case, and inside a\n * `LocaleProvider` with a `locale`, ignoring accents too where that\n * language does, so \"cafe\" finds \"Café\".\n */\n data?: string[];\n /** Placeholder text when no tags. */\n placeholder?: string;\n /** Object property to use as display field. */\n field?: string;\n /** Allow creating new tags not in suggestions. */\n allowNew?: boolean;\n /** Allow duplicate tags. */\n allowDuplicates?: boolean;\n /** Open autocomplete dropdown on focus. */\n openOnFocus?: boolean;\n /** Remove tag on backspace. Default: true. */\n removeOnKeys?: boolean;\n /** Keys to confirm tag creation. Default: ['Enter', ',']. */\n confirmKeys?: string[];\n /** Show close button on tags. Default: true. */\n closable?: boolean;\n /** Attach tags visually. */\n attached?: boolean;\n /**\n * Maximum number of tags allowed. At the limit the text input stays but\n * turns read-only, so focus stays put and the label still names it. It\n * takes no more tags and the suggestion list stays closed. Backspace (with\n * `removeOnKeys`) or a tag's remove button makes room again. While the\n * counter shows, it describes the input.\n */\n maxTags?: number;\n /** Maximum length of input. */\n maxlength?: number;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input is read-only. */\n readonly?: boolean;\n /** Applies rounded corners to the tags. */\n rounded?: boolean;\n /** Truncates long tag text with ellipsis. */\n ellipsis?: boolean;\n /**\n * Shows a counter of the number of tags, written the way the `locale` of\n * a `LocaleProvider` around it writes numbers.\n */\n hasCounter?: boolean;\n /**\n * Characters that split pasted text into tags. Each part goes through the\n * same checks as a typed tag, against the tags before it, the paste's own\n * included, and adding stops at `maxTags`. `onChange` fires once for the\n * whole paste, and `onAdd` once for each tag it adds.\n */\n onPasteSeparators?: string[];\n /** Validation function called before adding a tag. */\n beforeAdding?: (tag: string) => boolean;\n /** Custom function for creating tag objects from input. */\n createTag?: (input: string) => TaginputTag;\n /** Keeps the first autocomplete suggestion highlighted. */\n keepFirst?: boolean;\n /** Keeps the autocomplete dropdown open after selection. */\n keepOpen?: boolean;\n /**\n * Shows a loading spinner in the input.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n */\n loading?: boolean;\n /** ARIA label for tag close buttons. */\n ariaCloseLabel?: string;\n /** Icon name for the input field. */\n icon?: string;\n /** Icon library to use. */\n iconLibrary?: IconLibrary;\n /** Icon style variant (e.g., 'solid', 'outlined'). */\n iconVariant?: string;\n /** Additional icon modifiers. */\n iconFeatures?: string | string[];\n /** Input color variant. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Tag color variant. */\n tagColor?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'dark'\n | 'light';\n /** Size variant. */\n size?: 'small' | 'medium' | 'large';\n /** Form field name. When set, one hidden input per tag is rendered. */\n name?: string;\n /** Optional id of the form the hidden inputs belong to. */\n form?: string;\n /** Callback when tags change. */\n onChange?: (tags: TaginputTag[]) => void;\n /** Callback when tag is added. */\n onAdd?: (tag: TaginputTag) => void;\n /** Callback when tag is removed. */\n onRemove?: (tag: TaginputTag, index: number) => void;\n /** Callback when typing in input. */\n onTyping?: (value: string) => void;\n /** Custom render for tags. */\n tagTemplate?: (tag: TaginputTag) => React.ReactNode;\n}\n\n/**\n * The `Taginput` component provides a tag/chip input field for managing multiple tags.\n *\n * @function\n * @param {TaginputProps} props - Props for the Taginput component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the input element.\n * @returns {JSX.Element} The rendered taginput component.\n *\n * @example\n * // Basic usage\n * <Taginput\n * placeholder=\"Add a tag...\"\n * onChange={(tags) => console.log(tags)}\n * />\n *\n * @example\n * // With autocomplete\n * <Taginput\n * data={['React', 'Vue', 'Angular', 'Svelte']}\n * allowNew={false}\n * placeholder=\"Select frameworks...\"\n * />\n */\nexport const Taginput = forwardRef<HTMLInputElement, TaginputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue = [],\n data: dataProp,\n placeholder,\n field = 'label',\n allowNew = true,\n allowDuplicates = false,\n openOnFocus = false,\n removeOnKeys = true,\n confirmKeys = ['Enter', ','],\n closable = true,\n attached = false,\n maxTags,\n maxlength,\n disabled: disabledProp,\n readonly = false,\n rounded = false,\n ellipsis = false,\n hasCounter = true,\n onPasteSeparators = [','],\n beforeAdding,\n createTag,\n keepFirst = false,\n keepOpen = true,\n loading = false,\n ariaCloseLabel,\n icon,\n iconLibrary: iconLibraryProp,\n iconVariant,\n iconFeatures,\n color,\n tagColor,\n size,\n onChange,\n onAdd,\n onRemove,\n onTyping,\n tagTemplate,\n name,\n form,\n id,\n className,\n ...props\n },\n ref\n ) => {\n const disabled = useFieldsetDisabled(disabledProp);\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Taginput', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const { classPrefix } = useConfig();\n const defaultIconLibrary = useIconLibrary();\n const formatNumber = useScopedNumberFormat();\n const matchText = useLocaleMatcher();\n const resolvedLibrary = iconLibraryProp || defaultIconLibrary || 'fa';\n const pcn = (\n ...args: (\n | string\n | number\n | undefined\n | null\n | false\n | Record<string, unknown>\n | unknown[]\n )[]\n ) => prefixedClassNames(classPrefix, ...args);\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const [internalTags, setInternalTags] =\n useState<TaginputTag[]>(defaultValue);\n const [inputValue, setInputValue] = useState('');\n const [isActive, setIsActive] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const baseId = useId();\n const listboxId = `${baseId}-listbox`;\n const counterId = `${baseId}-counter`;\n\n // With `data` the input offers suggestions, so it's a combobox, even\n // while none match. Without it there's never a list, so it stays a plain\n // text field.\n const hasSuggestions = dataProp !== undefined;\n const data = dataProp ?? [];\n\n // Use controlled or internal tags\n const tags = controlledValue !== undefined ? controlledValue : internalTags;\n\n const isMaxReached = maxTags !== undefined && tags.length >= maxTags;\n // The suggestion list points `aria-labelledby` at the label that names\n // the input, so with suggestions it needs that label's id.\n const {\n controlId,\n fieldLabelProps,\n labelled,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: hasSuggestions,\n });\n\n // Get display value from tag\n const getDisplayValue = (tag: TaginputTag): string => {\n if (typeof tag === 'string') return tag;\n const fieldValue = tag[field];\n if (typeof fieldValue === 'string') return fieldValue;\n return tag.value || '';\n };\n\n // Filter autocomplete data\n const filteredData = data.filter(item => {\n const displayValue = item.toLowerCase();\n const matchesInput = matchText\n ? matchText(item, inputValue)\n : displayValue.includes(inputValue.toLowerCase());\n const notAlreadyAdded =\n allowDuplicates ||\n !tags.some(tag => getDisplayValue(tag).toLowerCase() === displayValue);\n const hasInput = inputValue || (openOnFocus && isActive);\n return matchesInput && notAlreadyAdded && hasInput;\n });\n // At the tag limit the list stays closed, since it could only offer tags\n // past the limit (#1087).\n const listOpen = isActive && !isMaxReached && filteredData.length > 0;\n\n // keepFirst: auto-highlight first item when dropdown opens\n useEffect(() => {\n if (keepFirst && isActive && filteredData.length > 0) {\n setHighlightedIndex(0);\n }\n }, [keepFirst, isActive, filteredData.length]);\n\n // Update tags\n const updateTags = useCallback(\n (newTags: TaginputTag[]) => {\n if (controlledValue === undefined) {\n setInternalTags(newTags);\n }\n onChange?.(newTags);\n },\n [controlledValue, onChange]\n );\n\n // Add tags from text typed, pasted or picked from the list. Each one is\n // checked against the tags before it, this batch's included, so a paste\n // of several adds them all in one change (#1101). Only `createTag` turns\n // text into an object.\n const addTags = useCallback(\n (values: string[]) => {\n if (disabled || readonly) return;\n\n let next = tags;\n const added: TaginputTag[] = [];\n for (const value of values) {\n // A paste can bring more tags than there's room for, and at the\n // limit the read-only input still takes Enter.\n if (maxTags !== undefined && next.length >= maxTags) break;\n\n const displayValue = value.trim();\n if (!displayValue) continue;\n const lower = displayValue.toLowerCase();\n\n // Duplicates, data and the dropdown filter all compare\n // case-insensitively.\n if (\n !allowDuplicates &&\n next.some(tag => getDisplayValue(tag).toLowerCase() === lower)\n )\n continue;\n\n // Without allowNew, only a suggestion can become a tag.\n if (!allowNew && !data.some(d => d.toLowerCase() === lower)) continue;\n\n if (beforeAdding && !beforeAdding(displayValue)) continue;\n\n const tag = createTag ? createTag(displayValue) : displayValue;\n next = [...next, tag];\n added.push(tag);\n }\n if (added.length === 0) return;\n\n updateTags(next);\n added.forEach(tag => onAdd?.(tag));\n setInputValue('');\n if (!keepOpen) {\n setIsActive(false);\n }\n setHighlightedIndex(-1);\n },\n [\n disabled,\n readonly,\n tags,\n maxTags,\n allowDuplicates,\n allowNew,\n data,\n field,\n updateTags,\n onAdd,\n beforeAdding,\n createTag,\n keepOpen,\n ]\n );\n\n // Remove tag\n const removeTag = useCallback(\n (index: number) => {\n /* istanbul ignore next: both triggers (delete button click, Backspace handler) are already gated on disabled/readonly */\n if (disabled || readonly) return;\n\n const removedTag = tags[index];\n const newTags = tags.filter((_, i) => i !== index);\n updateTags(newTags);\n onRemove?.(removedTag, index);\n },\n [disabled, readonly, tags, updateTags, onRemove]\n );\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n\n // Check if a confirm key was typed\n const lastChar = newValue.slice(-1);\n if (confirmKeys.includes(lastChar) && lastChar !== 'Enter') {\n const valueWithoutKey = newValue.slice(0, -1).trim();\n if (valueWithoutKey) {\n addTags([valueWithoutKey]);\n }\n return;\n }\n\n setInputValue(newValue);\n onTyping?.(newValue);\n\n if (newValue && data.length > 0) {\n setIsActive(true);\n }\n },\n [confirmKeys, addTags, onTyping, data.length]\n );\n\n // Handle paste\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n if (onPasteSeparators.length === 0) return;\n\n const pastedText = e.clipboardData.getData('text');\n // Check if any separator exists in the pasted text\n const hasSeparator = onPasteSeparators.some(sep =>\n pastedText.includes(sep)\n );\n\n if (!hasSeparator) return;\n\n e.preventDefault();\n\n // Build a character class from all separators. A `-` is escaped\n // too, since between two others it would make a range.\n const escapedSeparators = onPasteSeparators.map(s =>\n s.replace(/[-.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n );\n const regex = new RegExp(`[${escapedSeparators.join('')}]`);\n\n addTags(pastedText.split(regex));\n },\n [onPasteSeparators, addTags]\n );\n\n // Handle focus\n const handleFocus = useCallback(() => {\n if (openOnFocus && data.length > 0 && !disabled) {\n setIsActive(true);\n }\n }, [openOnFocus, data.length, disabled]);\n\n // Reaching the limit dismisses the list the way a click outside does, so\n // making room later doesn't bring it back unasked. It's an effect, not a\n // step in addTag, because a click on a suggestion also bubbles to the\n // container, whose focus on the input reopens the list in that same\n // event, and because a controlled value can reach the limit too.\n useEffect(() => {\n if (isMaxReached) {\n setIsActive(false);\n setHighlightedIndex(-1);\n }\n }, [isMaxReached]);\n\n // Handle click outside\n useEffect(() => {\n if (!isActive) return undefined;\n\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !isEventInside(e, containerRef.current)) {\n setIsActive(false);\n setHighlightedIndex(-1);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }, [isActive]);\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled || readonly || isComposing(e)) return;\n\n // Handle confirm keys\n if (confirmKeys.includes(e.key)) {\n e.preventDefault();\n if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {\n addTags([filteredData[highlightedIndex]]);\n } else if (inputValue.trim()) {\n addTags([inputValue]);\n }\n return;\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!isActive && data.length > 0) {\n setIsActive(true);\n } else {\n setHighlightedIndex(prev =>\n prev < filteredData.length - 1 ? prev + 1 : prev\n );\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));\n break;\n case 'Backspace':\n if (removeOnKeys && !inputValue && tags.length > 0) {\n e.preventDefault();\n removeTag(tags.length - 1);\n }\n break;\n case 'Escape':\n // Closing the suggestions claims the key, so a Modal around the\n // field stays open. With none showing, the key goes on to it.\n if (listOpen) e.preventDefault();\n setIsActive(false);\n setHighlightedIndex(-1);\n break;\n }\n },\n [\n disabled,\n readonly,\n confirmKeys,\n highlightedIndex,\n filteredData,\n addTags,\n inputValue,\n isActive,\n listOpen,\n data.length,\n removeOnKeys,\n tags.length,\n removeTag,\n ]\n );\n\n // Combined ref\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n }\n },\n [ref]\n );\n\n // Focus input when container is clicked\n const handleContainerClick = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Generate classes\n const taginputClasses = pcn('taginput', {\n 'is-active': isActive,\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-disabled': disabled,\n 'is-rounded': rounded,\n 'is-ellipsis': ellipsis,\n });\n\n const containerClasses = pcn('taginput-container', {\n 'is-attached': attached,\n 'has-icons-left': !!icon,\n });\n\n const inputClasses = pcn('input', {\n [`is-${size}`]: !!size,\n });\n\n const tagClasses = pcn('tag', {\n [`is-${tagColor}`]: !!tagColor,\n [`is-${size}`]: !!size,\n });\n\n const combinedClasses = classNames(\n taginputClasses,\n bulmaHelperClasses,\n className\n );\n\n // Counter text\n const showCounter =\n hasCounter && (maxTags !== undefined || maxlength !== undefined);\n const write = formatNumber ?? String;\n const counterText =\n maxTags !== undefined\n ? `${write(tags.length)} / ${write(maxTags)}`\n : maxlength !== undefined\n ? `${write(inputValue.length)} / ${write(maxlength)}`\n : '';\n\n const counterClasses = pcn('help', 'counter');\n const tagsClasses = pcn('tags');\n const dropdownMenuClasses = pcn('dropdown-menu', 'is-active');\n const dropdownContentClasses = pcn('dropdown-content');\n const iconRightClass = pcn('icon', 'is-right');\n const loaderClass = pcn('loader', 'is-loading');\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The combobox controls its listbox and points at the highlighted option,\n // the way Autocomplete's does. The listbox takes its name from the label\n // that names the combobox, the one this renders or a surrounding Field's,\n // and keeps a fallback name when no label names it or the one that does\n // has no id to point at. While no suggestion matches there's no listbox,\n // so the combobox is collapsed and points at nothing. It skips a\n // highlighted suggestion that's blank once trimmed, since that one can't\n // become a tag, and the option it points at is the one marked selected.\n const optionId = (index: number) => `${listboxId}-${index}`;\n const activeOptionId =\n listOpen && filteredData[highlightedIndex]?.trim()\n ? optionId(highlightedIndex)\n : undefined;\n const comboboxProps: React.InputHTMLAttributes<HTMLInputElement> = {\n role: 'combobox',\n 'aria-expanded': listOpen,\n 'aria-controls': listOpen ? listboxId : undefined,\n 'aria-activedescendant': activeOptionId,\n 'aria-haspopup': 'listbox',\n 'aria-autocomplete': 'list',\n };\n\n const taginputElement = (\n <div\n ref={containerRef}\n className={combinedClasses}\n onClick={handleContainerClick}\n {...rest}\n >\n <div className={containerClasses}>\n {icon && (\n <Icon\n name={icon}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n containerClassName={pcn('icon', 'is-left')}\n />\n )}\n <div className={tagsClasses}>\n {tags.map((tag, index) => {\n const displayVal = getDisplayValue(tag);\n return (\n <span key={index} className={tagClasses}>\n {tagTemplate ? (\n tagTemplate(tag)\n ) : ellipsis ? (\n <span title={displayVal}>{displayVal}</span>\n ) : (\n displayVal\n )}\n {closable && !disabled && !readonly && (\n <button\n type=\"button\"\n className={pcn('delete', 'is-small')}\n onClick={e => {\n e.stopPropagation();\n removeTag(index);\n }}\n aria-label={ariaCloseLabel || `Remove ${displayVal}`}\n />\n )}\n </span>\n );\n })}\n <input\n ref={combinedRef}\n type=\"text\"\n className={inputClasses}\n id={controlId}\n value={inputValue}\n placeholder={tags.length === 0 ? placeholder : undefined}\n disabled={disabled}\n // Read-only at the tag limit rather than gone, so focus stays\n // put and a label keeps naming it, and Backspace still makes\n // room (#1103).\n readOnly={readonly || isMaxReached}\n maxLength={maxlength}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n {...(hasSuggestions && comboboxProps)}\n // Fallback name, dropped only when a rendered label actually\n // targets this input, its own or a surrounding Field's\n // (aria-label would win otherwise). A label pointing elsewhere\n // keeps the fallback so the input is never nameless.\n aria-label={labelled ? undefined : 'Add tag'}\n // The counter, while it shows, describes the input, so at the\n // limit it says why the field takes no more.\n aria-describedby={showCounter ? counterId : undefined}\n />\n </div>\n {loading && (\n <span className={iconRightClass}>\n <span className={loaderClass} />\n </span>\n )}\n </div>\n\n {listOpen && (\n <div className={dropdownMenuClasses}>\n <div\n ref={dropdownRef}\n id={listboxId}\n className={dropdownContentClasses}\n role=\"listbox\"\n aria-labelledby={listLabelId}\n aria-label={listLabelId ? undefined : 'Suggestions'}\n >\n {filteredData.map((item, index) => (\n <a\n key={index}\n id={optionId(index)}\n className={pcn('dropdown-item', {\n 'is-active': index === highlightedIndex,\n })}\n onClick={() => addTags([item])}\n onMouseEnter={() => setHighlightedIndex(index)}\n role=\"option\"\n aria-selected={optionId(index) === activeOptionId}\n >\n {item}\n </a>\n ))}\n </div>\n </div>\n )}\n\n {showCounter && (\n <small id={counterId} className={counterClasses}>\n {counterText}\n </small>\n )}\n\n {name &&\n tags.map((tag, i) => (\n <input\n key={`tag-input-${i}`}\n type=\"hidden\"\n name={name}\n value={getDisplayValue(tag)}\n form={form}\n />\n ))}\n </div>\n );\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 {taginputElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {taginputElement}\n {messageEl}\n </>\n );\n }\n);\n\nTaginput.displayName = 'Taginput';\n\n/** @deprecated Use `Taginput` — same component. */\nexport const TagInput = Taginput;\n\n/** @deprecated Use `TaginputProps`. */\nexport type TagInputProps = TaginputProps;\n\nexport default Taginput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
@@ -1,7 +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 { createContext, useContext, useEffect, useState, useRef, useCallback } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { useScopedNumberFormat } from '../../helpers/localeFormat.js';
|
|
5
5
|
import { useClientLayoutEffect } from '../../helpers/useClientLayoutEffect.js';
|
|
6
6
|
import { warnOnce } from '../../helpers/devWarnings.js';
|
|
7
7
|
import { useNativeMobilePicker } from '../_pickerInternals/useNativeMobilePicker.js';
|
|
@@ -137,7 +137,7 @@ function useColorPicker({ value, defaultValue, onChange, onChangeEnd, format, al
|
|
|
137
137
|
onChangeEnd?.(nextText);
|
|
138
138
|
}, [disabled, alpha, format, onChange, onChangeEnd, empty]);
|
|
139
139
|
const end = useCallback(() => onChangeEnd?.(lastTextRef.current), [onChangeEnd]);
|
|
140
|
-
const formatNumber =
|
|
140
|
+
const formatNumber = useScopedNumberFormat();
|
|
141
141
|
const { isCoarsePointer } = useNativeMobilePicker();
|
|
142
142
|
const merged = mergeColorLabels(labels);
|
|
143
143
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pickerState.js","sources":["../../../../src/form/_colorInternals/pickerState.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts. The color a picker\n// holds and the context its parts read, shared by ColorPicker and the panel\n// ColorInput opens, so the panel needs no Field or Control of its own.\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useNumberFormat, NumberFormatter } from '../../helpers/localeFormat';\nimport { useClientLayoutEffect } from '../../helpers/useClientLayoutEffect';\nimport { warnOnce } from '../../helpers/devWarnings';\nimport { useNativeMobilePicker } from '../_pickerInternals/useNativeMobilePicker';\nimport {\n ColorFormat,\n Hsva,\n formatColor,\n namesHue,\n parseColor,\n} from './colorMath';\nimport type { ColorPickerLabels, ColorPickerSwatch } from '../ColorPicker';\n\nconst DEFAULT_LABELS: Required<ColorPickerLabels> = {\n area: 'Saturation and brightness',\n areaRoleDescription: '2D slider',\n saturation: 'Saturation',\n brightness: 'Brightness',\n hue: 'Hue',\n alpha: 'Alpha',\n degrees: 'degrees',\n value: 'Color value',\n swatches: 'Swatches',\n eyeDropper: 'Pick a color from the screen',\n chooseColor: 'Choose color',\n};\n\n/** The labels with each one left out, or empty, at its default. */\nexport const mergeColorLabels = (\n labels: ColorPickerLabels | undefined\n): Required<ColorPickerLabels> => {\n const merged = { ...DEFAULT_LABELS };\n for (const [key, value] of Object.entries(labels ?? {})) {\n if (value) merged[key as keyof ColorPickerLabels] = value;\n }\n return merged;\n};\n\nexport const BLACK: Hsva = { h: 0, s: 0, v: 0, a: 1 };\n\n/**\n * A color read from outside the picker, written as `source`, with the hue\n * and saturation the picker had where the new color has none, so the thumbs\n * don't jump to 0. A gray written as hex, `rgb()` or a name has no hue, so\n * it keeps the picker's; one written as `hsl()` names its hue, which wins.\n * Black has no saturation in the square either way, and keeps the picker's,\n * which writes no differently.\n */\nexport const keepingChannels = (\n next: Hsva,\n previous: Hsva,\n source: string\n): Hsva => ({\n ...next,\n h: (next.s === 0 || next.v === 0) && !namesHue(source) ? previous.h : next.h,\n s: next.v === 0 ? previous.s : next.s,\n});\n\n/** What a picker's parts read from the picker around them. */\nexport interface ColorPickerContextValue {\n /** The color shown, alpha at 1 unless the picker takes alpha. */\n color: Hsva;\n /** The color written in the picker's format. */\n text: string;\n format: ColorFormat;\n alpha: boolean;\n disabled: boolean;\n labels: Required<ColorPickerLabels>;\n swatches: ColorPickerSwatch[] | 'bulma' | undefined;\n eyeDropper: boolean;\n /** Whether a touch screen reader is likely, so both square inputs show. */\n touch: boolean;\n /** Writes a percentage, in the locale of a LocaleProvider when there is one. */\n percent: (value: number) => string;\n /** Writes a hue in degrees, in the locale of a LocaleProvider when there is one. */\n degrees: (value: number) => string;\n /** Sets the color: `onChange`, and `onChangeEnd` too when `end` is set. */\n change: (next: Hsva, end?: boolean) => void;\n /** Ends a drag: `onChangeEnd` with the latest value. */\n end: () => void;\n}\n\nexport const ColorPickerContext = createContext<ColorPickerContextValue | null>(\n null\n);\n\n/** Does nothing, for a part outside a picker and a cancelled eye dropper. */\nexport const noop = () => {};\n\n// What a part outside a ColorPicker reads, so its hooks run the same; it\n// then renders nothing.\nexport const standalone: ColorPickerContextValue = {\n color: BLACK,\n text: '',\n format: 'hsl',\n alpha: false,\n disabled: true,\n labels: DEFAULT_LABELS,\n swatches: undefined,\n eyeDropper: false,\n touch: false,\n percent: String,\n degrees: String,\n change: noop,\n end: noop,\n};\n\n/** The picker around a part, or null with a development warning. */\nexport function usePicker(part: string): ColorPickerContextValue | null {\n const picker = useContext(ColorPickerContext);\n const outside = !picker;\n useEffect(() => {\n if (outside) {\n warnOnce(\n `ColorPicker:${part}:outside`,\n `[bestax-bulma] <ColorPicker.${part}> needs a <ColorPicker> around ` +\n 'it, which holds the color, and renders nothing without one.'\n );\n }\n }, [outside, part]);\n return picker;\n}\n\n/** A percentage, in the provider's locale when there is one. */\nconst writePercent =\n (formatNumber: NumberFormatter | null) => (value: number) =>\n formatNumber\n ? formatNumber(value / 100, { style: 'percent' })\n : `${value}%`;\n\n/** Degrees, in the provider's locale when there is one, else with `unit`. */\nconst writeDegrees =\n (formatNumber: NumberFormatter | null, unit: string) => (value: number) =>\n formatNumber\n ? formatNumber(value, {\n style: 'unit',\n unit: 'degree',\n unitDisplay: 'long',\n })\n : `${value} ${unit}`;\n\n/** What a picker is given: ColorPicker's props, or the ones ColorInput passes on. */\nexport interface PickerOptions {\n value: string | undefined;\n defaultValue: string | undefined;\n onChange: ((value: string) => void) | undefined;\n onChangeEnd: ((value: string) => void) | undefined;\n format: ColorFormat;\n alpha: boolean;\n disabled: boolean;\n swatches: ColorPickerSwatch[] | 'bulma' | undefined;\n eyeDropper: boolean;\n labels: ColorPickerLabels | undefined;\n /**\n * Whether the field the picker serves is empty, as ColorInput's can be.\n * The picker still shows a color then, and any change, even to that same\n * color, is reported, so it fills the field.\n */\n empty?: boolean;\n}\n\n/**\n * Holds a picker's color and builds what its parts read. Controlled, the\n * color shown follows `value`; a value the picker handed out comes back as\n * the exact color it was, thumbs and all.\n */\nexport function useColorPicker({\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n empty = false,\n}: PickerOptions): ColorPickerContextValue {\n const isControlled = value !== undefined;\n // The color the picker last set or started with, and its text. While\n // `value` is that text, this is the color shown.\n const [own, setOwn] = useState(() => {\n const start = isControlled ? value : defaultValue;\n return { text: start ?? '', color: parseColor(start) ?? BLACK };\n });\n // A controlled value from outside becomes the color held, during this\n // render, keeping the hue and saturation a gray or black has none of.\n // One the picker can't read changes nothing, so the last good color\n // stays on screen.\n if (isControlled && value !== own.text) {\n const parsed = parseColor(value);\n if (parsed) {\n setOwn({\n text: value,\n color: keepingChannels(parsed, own.color, value),\n });\n }\n }\n const color = alpha ? own.color : { ...own.color, a: 1 };\n const text = formatColor(color, format, alpha);\n\n // The latest text handed out, so a step that writes the same text\n // doesn't call onChange again, and a drag's end reports the last one.\n const lastTextRef = useRef(text);\n useClientLayoutEffect(() => {\n lastTextRef.current = text;\n });\n\n const change = useCallback(\n (next: Hsva, finished = false) => {\n if (disabled) return;\n const solid = alpha ? next : { ...next, a: 1 };\n const nextText = formatColor(solid, format, alpha);\n setOwn({ text: nextText, color: solid });\n if (empty || nextText !== lastTextRef.current) {\n lastTextRef.current = nextText;\n onChange?.(nextText);\n }\n if (finished) onChangeEnd?.(nextText);\n },\n [disabled, alpha, format, onChange, onChangeEnd, empty]\n );\n const end = useCallback(\n () => onChangeEnd?.(lastTextRef.current),\n [onChangeEnd]\n );\n\n const formatNumber = useNumberFormat();\n const { isCoarsePointer } = useNativeMobilePicker();\n const merged = mergeColorLabels(labels);\n return {\n color,\n text,\n format,\n alpha,\n disabled,\n labels: merged,\n swatches,\n eyeDropper,\n touch: isCoarsePointer,\n percent: writePercent(formatNumber),\n degrees: writeDegrees(formatNumber, merged.degrees),\n change,\n end,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pickerState.js","sources":["../../../../src/form/_colorInternals/pickerState.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts. The color a picker\n// holds and the context its parts read, shared by ColorPicker and the panel\n// ColorInput opens, so the panel needs no Field or Control of its own.\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport {\n useScopedNumberFormat,\n NumberFormatFunction,\n} from '../../helpers/localeFormat';\nimport { useClientLayoutEffect } from '../../helpers/useClientLayoutEffect';\nimport { warnOnce } from '../../helpers/devWarnings';\nimport { useNativeMobilePicker } from '../_pickerInternals/useNativeMobilePicker';\nimport {\n ColorFormat,\n Hsva,\n formatColor,\n namesHue,\n parseColor,\n} from './colorMath';\nimport type { ColorPickerLabels, ColorPickerSwatch } from '../ColorPicker';\n\nconst DEFAULT_LABELS: Required<ColorPickerLabels> = {\n area: 'Saturation and brightness',\n areaRoleDescription: '2D slider',\n saturation: 'Saturation',\n brightness: 'Brightness',\n hue: 'Hue',\n alpha: 'Alpha',\n degrees: 'degrees',\n value: 'Color value',\n swatches: 'Swatches',\n eyeDropper: 'Pick a color from the screen',\n chooseColor: 'Choose color',\n};\n\n/** The labels with each one left out, or empty, at its default. */\nexport const mergeColorLabels = (\n labels: ColorPickerLabels | undefined\n): Required<ColorPickerLabels> => {\n const merged = { ...DEFAULT_LABELS };\n for (const [key, value] of Object.entries(labels ?? {})) {\n if (value) merged[key as keyof ColorPickerLabels] = value;\n }\n return merged;\n};\n\nexport const BLACK: Hsva = { h: 0, s: 0, v: 0, a: 1 };\n\n/**\n * A color read from outside the picker, written as `source`, with the hue\n * and saturation the picker had where the new color has none, so the thumbs\n * don't jump to 0. A gray written as hex, `rgb()` or a name has no hue, so\n * it keeps the picker's; one written as `hsl()` names its hue, which wins.\n * Black has no saturation in the square either way, and keeps the picker's,\n * which writes no differently.\n */\nexport const keepingChannels = (\n next: Hsva,\n previous: Hsva,\n source: string\n): Hsva => ({\n ...next,\n h: (next.s === 0 || next.v === 0) && !namesHue(source) ? previous.h : next.h,\n s: next.v === 0 ? previous.s : next.s,\n});\n\n/** What a picker's parts read from the picker around them. */\nexport interface ColorPickerContextValue {\n /** The color shown, alpha at 1 unless the picker takes alpha. */\n color: Hsva;\n /** The color written in the picker's format. */\n text: string;\n format: ColorFormat;\n alpha: boolean;\n disabled: boolean;\n labels: Required<ColorPickerLabels>;\n swatches: ColorPickerSwatch[] | 'bulma' | undefined;\n eyeDropper: boolean;\n /** Whether a touch screen reader is likely, so both square inputs show. */\n touch: boolean;\n /** Writes a percentage, in the locale of a LocaleProvider when there is one. */\n percent: (value: number) => string;\n /** Writes a hue in degrees, in the locale of a LocaleProvider when there is one. */\n degrees: (value: number) => string;\n /** Sets the color: `onChange`, and `onChangeEnd` too when `end` is set. */\n change: (next: Hsva, end?: boolean) => void;\n /** Ends a drag: `onChangeEnd` with the latest value. */\n end: () => void;\n}\n\nexport const ColorPickerContext = createContext<ColorPickerContextValue | null>(\n null\n);\n\n/** Does nothing, for a part outside a picker and a cancelled eye dropper. */\nexport const noop = () => {};\n\n// What a part outside a ColorPicker reads, so its hooks run the same; it\n// then renders nothing.\nexport const standalone: ColorPickerContextValue = {\n color: BLACK,\n text: '',\n format: 'hsl',\n alpha: false,\n disabled: true,\n labels: DEFAULT_LABELS,\n swatches: undefined,\n eyeDropper: false,\n touch: false,\n percent: String,\n degrees: String,\n change: noop,\n end: noop,\n};\n\n/** The picker around a part, or null with a development warning. */\nexport function usePicker(part: string): ColorPickerContextValue | null {\n const picker = useContext(ColorPickerContext);\n const outside = !picker;\n useEffect(() => {\n if (outside) {\n warnOnce(\n `ColorPicker:${part}:outside`,\n `[bestax-bulma] <ColorPicker.${part}> needs a <ColorPicker> around ` +\n 'it, which holds the color, and renders nothing without one.'\n );\n }\n }, [outside, part]);\n return picker;\n}\n\n/** A percentage, in the provider's locale when there is one. */\nconst writePercent =\n (formatNumber: NumberFormatFunction | null) => (value: number) =>\n formatNumber\n ? formatNumber(value / 100, { style: 'percent' })\n : `${value}%`;\n\n/** Degrees, in the provider's locale when there is one, else with `unit`. */\nconst writeDegrees =\n (formatNumber: NumberFormatFunction | null, unit: string) =>\n (value: number) =>\n formatNumber\n ? formatNumber(value, {\n style: 'unit',\n unit: 'degree',\n unitDisplay: 'long',\n })\n : `${value} ${unit}`;\n\n/** What a picker is given: ColorPicker's props, or the ones ColorInput passes on. */\nexport interface PickerOptions {\n value: string | undefined;\n defaultValue: string | undefined;\n onChange: ((value: string) => void) | undefined;\n onChangeEnd: ((value: string) => void) | undefined;\n format: ColorFormat;\n alpha: boolean;\n disabled: boolean;\n swatches: ColorPickerSwatch[] | 'bulma' | undefined;\n eyeDropper: boolean;\n labels: ColorPickerLabels | undefined;\n /**\n * Whether the field the picker serves is empty, as ColorInput's can be.\n * The picker still shows a color then, and any change, even to that same\n * color, is reported, so it fills the field.\n */\n empty?: boolean;\n}\n\n/**\n * Holds a picker's color and builds what its parts read. Controlled, the\n * color shown follows `value`; a value the picker handed out comes back as\n * the exact color it was, thumbs and all.\n */\nexport function useColorPicker({\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n empty = false,\n}: PickerOptions): ColorPickerContextValue {\n const isControlled = value !== undefined;\n // The color the picker last set or started with, and its text. While\n // `value` is that text, this is the color shown.\n const [own, setOwn] = useState(() => {\n const start = isControlled ? value : defaultValue;\n return { text: start ?? '', color: parseColor(start) ?? BLACK };\n });\n // A controlled value from outside becomes the color held, during this\n // render, keeping the hue and saturation a gray or black has none of.\n // One the picker can't read changes nothing, so the last good color\n // stays on screen.\n if (isControlled && value !== own.text) {\n const parsed = parseColor(value);\n if (parsed) {\n setOwn({\n text: value,\n color: keepingChannels(parsed, own.color, value),\n });\n }\n }\n const color = alpha ? own.color : { ...own.color, a: 1 };\n const text = formatColor(color, format, alpha);\n\n // The latest text handed out, so a step that writes the same text\n // doesn't call onChange again, and a drag's end reports the last one.\n const lastTextRef = useRef(text);\n useClientLayoutEffect(() => {\n lastTextRef.current = text;\n });\n\n const change = useCallback(\n (next: Hsva, finished = false) => {\n if (disabled) return;\n const solid = alpha ? next : { ...next, a: 1 };\n const nextText = formatColor(solid, format, alpha);\n setOwn({ text: nextText, color: solid });\n if (empty || nextText !== lastTextRef.current) {\n lastTextRef.current = nextText;\n onChange?.(nextText);\n }\n if (finished) onChangeEnd?.(nextText);\n },\n [disabled, alpha, format, onChange, onChangeEnd, empty]\n );\n const end = useCallback(\n () => onChangeEnd?.(lastTextRef.current),\n [onChangeEnd]\n );\n\n const formatNumber = useScopedNumberFormat();\n const { isCoarsePointer } = useNativeMobilePicker();\n const merged = mergeColorLabels(labels);\n return {\n color,\n text,\n format,\n alpha,\n disabled,\n labels: merged,\n swatches,\n eyeDropper,\n touch: isCoarsePointer,\n percent: writePercent(formatNumber),\n degrees: writeDegrees(formatNumber, merged.degrees),\n change,\n end,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -10,15 +10,22 @@ import { localeDirection, canonicalLocale } from './localeInfo.js';
|
|
|
10
10
|
const LocaleContext = createContext(null);
|
|
11
11
|
/** The nearest provider's wrapper element, for `LocalePortalScope` to test targets against. */
|
|
12
12
|
const LocaleElementContext = createContext(null);
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/** The provider's warning about a tag `Intl` refuses. */
|
|
14
|
+
const warnProviderLocale = (tag) => warnOnce(`locale-provider-invalid:${tag}`, `[bestax-bulma] <LocaleProvider locale="${tag}">: not a language ` +
|
|
15
|
+
'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +
|
|
16
|
+
'"en-US", with a hyphen rather than an underscore.');
|
|
17
|
+
/**
|
|
18
|
+
* INTERNAL, deliberately not exported from `src/index.ts`. A tag in
|
|
19
|
+
* canonical form, or `undefined` for an empty or missing one and for one
|
|
20
|
+
* `Intl` refuses, which `refused` reports: by default the provider's own
|
|
21
|
+
* development warning, once per tag.
|
|
22
|
+
*/
|
|
23
|
+
function validLocale(tag, refused = warnProviderLocale) {
|
|
15
24
|
try {
|
|
16
25
|
return canonicalLocale(tag);
|
|
17
26
|
}
|
|
18
27
|
catch {
|
|
19
|
-
|
|
20
|
-
'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +
|
|
21
|
-
'"en-US", with a hyphen rather than an underscore.');
|
|
28
|
+
refused(tag);
|
|
22
29
|
return undefined;
|
|
23
30
|
}
|
|
24
31
|
}
|
|
@@ -153,5 +160,5 @@ function LocalePortalScope({ children, target, scope, }) {
|
|
|
153
160
|
return (jsx("div", { dir: values.dir, lang: values.locale, style: displayContents, children: children }));
|
|
154
161
|
}
|
|
155
162
|
|
|
156
|
-
export { LocalePortalScope, LocaleProvider, useLocale, useLocaleScope };
|
|
163
|
+
export { LocalePortalScope, LocaleProvider, useLocale, useLocaleScope, validLocale };
|
|
157
164
|
//# sourceMappingURL=LocaleProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocaleProvider.js","sources":["../../../src/helpers/LocaleProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames } from './classNames';\nimport { useBulmaClasses, BulmaClassesProps } from './useBulmaClasses';\nimport { warnOnce } from './devWarnings';\nimport { canonicalLocale, localeDirection } from './localeInfo';\n\n/** A writing direction. */\nexport type TextDirection = 'ltr' | 'rtl';\n\n/** What the nearest `LocaleProvider` sets, both `undefined` outside one. */\nexport interface LocaleContextValue {\n /**\n * The locale, as a canonical BCP 47 tag such as `\"ar-EG\"`: the provider's\n * own, else the one an outer provider sets.\n */\n locale?: string;\n /**\n * The direction: the provider's own `dir`, else its own locale's, else the\n * one an outer provider sets.\n */\n dir?: TextDirection;\n}\n\nconst LocaleContext = createContext<LocaleContextValue | null>(null);\n\n/** The nearest provider's wrapper element, for `LocalePortalScope` to test targets against. */\nconst LocaleElementContext =\n createContext<React.RefObject<HTMLDivElement | null> | null>(null);\n\n/**\n * Props for the LocaleProvider component. The helper props, the other\n * attributes and the `ref` land on its `<div>`.\n */\nexport interface LocaleProviderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'dir' | 'lang' | 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * A BCP 47 language tag, such as `\"de\"` or `\"ar-EG\"`. It becomes the\n * wrapper's `lang`, the default `locale` of the date and time pickers\n * inside, and, with no `dir`, the direction, from the way its script is\n * written. Unset, a nested provider keeps the outer one's. A tag `Intl`\n * refuses is ignored, with a warning in development.\n */\n locale?: string;\n /**\n * The direction, whatever the locale. Unset, it follows this provider's\n * `locale`, else an outer provider's direction, else the page's.\n */\n dir?: TextDirection;\n /** The part of the app it covers. */\n children?: React.ReactNode;\n}\n\n/** A tag in canonical form, or `undefined`, warning about one `Intl` refuses. */\nfunction validLocale(tag: string | undefined): string | undefined {\n try {\n return canonicalLocale(tag);\n } catch {\n warnOnce(\n `locale-provider-invalid:${tag}`,\n `[bestax-bulma] <LocaleProvider locale=\"${tag}\">: not a language ` +\n 'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +\n '\"en-US\", with a hyphen rather than an underscore.'\n );\n return undefined;\n }\n}\n\n/**\n * Sets the language and writing direction for the part of the app inside it, on a wrapper `<div>` and on what the library portals out of it.\n *\n * The wrapper carries `dir` and `lang`, so CSS and the components that read\n * the computed direction follow it, as they follow `<html dir>`. A `locale`\n * alone sets the direction of its script, and a `dir` sets the direction\n * whatever the locale. A nested provider keeps whatever it leaves unset.\n *\n * Inside it, the date and time pickers take its `locale` unless given their\n * own, and their week starts on the first day of the locale they use unless\n * `firstDayOfWeek` is set, and a picker with a `locale` of its own is read\n * like a nested provider. With a `locale`, the numbers the library writes,\n * such as page numbers and badge counts, follow it, and so does the\n * filtering in `Combobox`, `Autocomplete`, `Taginput` and `Command`, which then ignores\n * accents where the language treats letters as the same. The library's\n * portaled content, such as a `Popover` panel, a `Modal` with `portal`, a\n * `Toast` or a `Portal`'s children, keeps the same `dir` and `lang` though\n * it renders outside the wrapper: in a container outside the wrapper, it\n * sits in a `display: contents` element that carries them. Without a\n * provider none of this changes.\n *\n * @function\n * @param {LocaleProviderProps} props - Props for the LocaleProvider.\n * @returns {JSX.Element} The wrapper, inside the context.\n *\n * @example\n * <LocaleProvider locale=\"ar-EG\">\n * <App />\n * </LocaleProvider>\n */\nexport const LocaleProvider = forwardRef<HTMLDivElement, LocaleProviderProps>(\n (\n { locale: localeProp, dir: dirProp, className, children, ...props },\n ref\n ) => {\n const outer = useContext(LocaleContext);\n const ownLocale = useMemo(() => validLocale(localeProp), [localeProp]);\n const ownLocaleDir = useMemo(\n () => (ownLocale ? localeDirection(ownLocale) : undefined),\n [ownLocale]\n );\n const locale = ownLocale || outer?.locale;\n const dir = dirProp || ownLocaleDir || outer?.dir;\n const value = useMemo(() => ({ locale, dir }), [locale, dir]);\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n // The wrapper, for portaled content to tell whether its target is inside\n // it, and the caller's ref. A callback ref's cleanup is held and run on\n // detach, as Toast and Modal do, since React 18 discards the return value.\n const elementRef = useRef<HTMLDivElement | null>(null);\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const setElement = useCallback(\n (node: HTMLDivElement | null) => {\n elementRef.current = node;\n if (typeof ref === 'function') {\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) consumerCleanup();\n else ref(null);\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n\n return (\n <LocaleContext.Provider value={value}>\n <LocaleElementContext.Provider value={elementRef}>\n <div\n ref={setElement}\n className={classNames(bulmaHelperClasses, className) || undefined}\n {...rest}\n dir={dir}\n lang={locale}\n >\n {children}\n </div>\n </LocaleElementContext.Provider>\n </LocaleContext.Provider>\n );\n }\n);\n\nLocaleProvider.displayName = 'LocaleProvider';\n\n/** What `useLocale` returns outside a provider, the same object each time. */\nconst noLocale: LocaleContextValue = {};\n\n/**\n * The locale and direction the nearest `LocaleProvider` sets, for an app's own `Intl` calls or its own portaled content; both are `undefined` outside one.\n *\n * It isn't the page's direction: with no provider, or one that sets no\n * direction, the page's `<html dir>` still decides. To act on the direction\n * an element is laid out in, read `getComputedStyle(element).direction`, as\n * the library's components do.\n *\n * @function\n * @returns {LocaleContextValue} The nearest provider's `locale` and `dir`.\n *\n * @example\n * const { locale } = useLocale();\n * const price = new Intl.NumberFormat(locale, {\n * style: 'currency',\n * currency: 'EUR',\n * }).format(12.5);\n */\nexport function useLocale(): LocaleContextValue {\n return useContext(LocaleContext) ?? noLocale;\n}\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. The nearest\n * provider's settings, or `null` outside any provider, so a caller can tell\n * \"no provider\" from \"a provider that sets nothing\".\n */\nexport function useLocaleScope(): LocaleContextValue | null {\n return useContext(LocaleContext);\n}\n\nconst displayContents: React.CSSProperties = { display: 'contents' };\n\n/** The `dir` and `lang` portaled content carries: a provider's, or a picker's own. */\nexport interface PortalLocale {\n /** The `lang` to carry, unset for none. */\n locale?: string;\n /** The `dir` to carry, unset for none. */\n dir?: string;\n}\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. Keeps the `dir`\n * and `lang` of the nearest provider, or the `scope` given in their place,\n * on content the library portals into `target`, which has left the\n * provider's wrapper behind.\n *\n * A target inside the provider's own wrapper gets the content as it is: it\n * inherits from the wrapper, and follows it when the provider changes.\n * Content that must be its container's direct child, a `<tr>` portaled into\n * a `<tbody>` there, stays one. Any other target, `document.body` included,\n * gets the content inside a `display: contents` element carrying the\n * values, which adds no box. So does content with a `scope` of its own, a\n * picker's panel, since the provider's values aren't its own.\n *\n * Which of the two is decided once, when the content mounts, and kept while\n * it stays: switching between them would put a different element in its\n * place and remount everything inside, losing typed text, focus and timers.\n * A change of locale or direction updates the wrapper's attributes instead.\n * A target is never left bare because something else, such as `<html>`,\n * happens to carry the same values, since that can stop being true without\n * the content remounting. Outside a provider it renders the children alone,\n * so nothing changes there.\n */\nexport function LocalePortalScope({\n children,\n target,\n scope,\n}: {\n children: React.ReactNode;\n /** The element the content is portaled into. */\n target: Element;\n /** Values to carry in place of the provider's, such as a picker's own. */\n scope?: PortalLocale;\n}) {\n const provider = useContext(LocaleContext);\n const element = useContext(LocaleElementContext);\n const [wrap] = useState(\n () => scope !== undefined || !element?.current?.contains(target)\n );\n if (!provider || !wrap) return <>{children}</>;\n const values = scope ?? provider;\n return (\n <div dir={values.dir} lang={values.locale} style={displayContents}>\n {children}\n </div>\n );\n}\n"],"names":["_jsx","_Fragment"],"mappings":";;;;;;;;;AA+BA,MAAM,aAAa,GAAG,aAAa,CAA4B,IAAI,CAAC;AAEpE;AACA,MAAM,oBAAoB,GACxB,aAAa,CAAgD,IAAI,CAAC;AA2BpE;AACA,SAAS,WAAW,CAAC,GAAuB,EAAA;AAC1C,IAAA,IAAI;AACF,QAAA,OAAO,eAAe,CAAC,GAAG,CAAC;IAC7B;AAAE,IAAA,MAAM;AACN,QAAA,QAAQ,CACN,CAAA,wBAAA,EAA2B,GAAG,EAAE,EAChC,CAAA,uCAAA,EAA0C,GAAG,CAAA,mBAAA,CAAqB;YAChE,+DAA+D;AAC/D,YAAA,mDAAmD,CACtD;AACD,QAAA,OAAO,SAAS;IAClB;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BG;AACI,MAAM,cAAc,GAAG,UAAU,CACtC,CACE,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EACnE,GAAG,KACD;AACF,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,aAAa,CAAC;AACvC,IAAA,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,OAAO,CAC1B,OAAO,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,EAC1D,CAAC,SAAS,CAAC,CACZ;AACD,IAAA,MAAM,MAAM,GAAG,SAAS,IAAI,KAAK,EAAE,MAAM;IACzC,MAAM,GAAG,GAAG,OAAO,IAAI,YAAY,IAAI,KAAK,EAAE,GAAG;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE7D,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC;;;;AAK3D,IAAA,MAAM,UAAU,GAAG,MAAM,CAAwB,IAAI,CAAC;AACtD,IAAA,MAAM,kBAAkB,GAAG,MAAM,CAAsB,IAAI,CAAC;AAC5D,IAAA,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,IAA2B,KAAI;AAC9B,QAAA,UAAU,CAAC,OAAO,GAAG,IAAI;AACzB,QAAA,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;AAC7B,YAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACjB,gBAAA,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO;AAClD,gBAAA,kBAAkB,CAAC,OAAO,GAAG,IAAI;AACjC,gBAAA,IAAI,eAAe;AAAE,oBAAA,eAAe,EAAE;;oBACjC,GAAG,CAAC,IAAI,CAAC;gBACd;YACF;AACA,YAAA,MAAM,OAAO,GAAY,GAAG,CAAC,IAAI,CAAC;AAClC,YAAA,kBAAkB,CAAC,OAAO;gBACxB,OAAO,OAAO,KAAK,UAAU,GAAI,OAAsB,GAAG,IAAI;QAClE;aAAO,IAAI,GAAG,EAAE;AACd,YAAA,GAAG,CAAC,OAAO,GAAG,IAAI;QACpB;AACF,IAAA,CAAC,EACD,CAAC,GAAG,CAAC,CACN;IAED,QACEA,IAAC,aAAa,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,QAAA,EAClCA,GAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,YAC9CA,GAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,CAAC,kBAAkB,EAAE,SAAS,CAAC,IAAI,SAAS,EAAA,GAC7D,IAAI,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,MAAM,EAAA,QAAA,EAEX,QAAQ,EAAA,CACL,EAAA,CACwB,EAAA,CACT;AAE7B,CAAC;AAGH,cAAc,CAAC,WAAW,GAAG,gBAAgB;AAE7C;AACA,MAAM,QAAQ,GAAuB,EAAE;AAEvC;;;;;;;;;;;;;;;;;AAiBG;SACa,SAAS,GAAA;AACvB,IAAA,OAAO,UAAU,CAAC,aAAa,CAAC,IAAI,QAAQ;AAC9C;AAEA;;;;AAIG;SACa,cAAc,GAAA;AAC5B,IAAA,OAAO,UAAU,CAAC,aAAa,CAAC;AAClC;AAEA,MAAM,eAAe,GAAwB,EAAE,OAAO,EAAE,UAAU,EAAE;AAUpE;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACG,SAAU,iBAAiB,CAAC,EAChC,QAAQ,EACR,MAAM,EACN,KAAK,GAON,EAAA;AACC,IAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,aAAa,CAAC;AAC1C,IAAA,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC;IAChD,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CACrB,MAAM,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CACjE;AACD,IAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;QAAE,OAAOA,GAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAI;AAC9C,IAAA,MAAM,MAAM,GAAG,KAAK,IAAI,QAAQ;IAChC,QACED,aAAK,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,eAAe,EAAA,QAAA,EAC9D,QAAQ,EAAA,CACL;AAEV;;"}
|
|
1
|
+
{"version":3,"file":"LocaleProvider.js","sources":["../../../src/helpers/LocaleProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames } from './classNames';\nimport { useBulmaClasses, BulmaClassesProps } from './useBulmaClasses';\nimport { warnOnce } from './devWarnings';\nimport { canonicalLocale, localeDirection } from './localeInfo';\n\n/** A writing direction. */\nexport type TextDirection = 'ltr' | 'rtl';\n\n/** What the nearest `LocaleProvider` sets, both `undefined` outside one. */\nexport interface LocaleContextValue {\n /**\n * The locale, as a canonical BCP 47 tag such as `\"ar-EG\"`: the provider's\n * own, else the one an outer provider sets.\n */\n locale?: string;\n /**\n * The direction: the provider's own `dir`, else its own locale's, else the\n * one an outer provider sets.\n */\n dir?: TextDirection;\n}\n\nconst LocaleContext = createContext<LocaleContextValue | null>(null);\n\n/** The nearest provider's wrapper element, for `LocalePortalScope` to test targets against. */\nconst LocaleElementContext =\n createContext<React.RefObject<HTMLDivElement | null> | null>(null);\n\n/**\n * Props for the LocaleProvider component. The helper props, the other\n * attributes and the `ref` land on its `<div>`.\n */\nexport interface LocaleProviderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'dir' | 'lang' | 'color'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * A BCP 47 language tag, such as `\"de\"` or `\"ar-EG\"`. It becomes the\n * wrapper's `lang`, the default `locale` of the date and time pickers\n * inside, and, with no `dir`, the direction, from the way its script is\n * written. Unset, a nested provider keeps the outer one's. A tag `Intl`\n * refuses is ignored, with a warning in development.\n */\n locale?: string;\n /**\n * The direction, whatever the locale. Unset, it follows this provider's\n * `locale`, else an outer provider's direction, else the page's.\n */\n dir?: TextDirection;\n /** The part of the app it covers. */\n children?: React.ReactNode;\n}\n\n/** The provider's warning about a tag `Intl` refuses. */\nconst warnProviderLocale = (tag: string) =>\n warnOnce(\n `locale-provider-invalid:${tag}`,\n `[bestax-bulma] <LocaleProvider locale=\"${tag}\">: not a language ` +\n 'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +\n '\"en-US\", with a hyphen rather than an underscore.'\n );\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. A tag in\n * canonical form, or `undefined` for an empty or missing one and for one\n * `Intl` refuses, which `refused` reports: by default the provider's own\n * development warning, once per tag.\n */\nexport function validLocale(\n tag: string | undefined,\n refused: (tag: string) => void = warnProviderLocale\n): string | undefined {\n try {\n return canonicalLocale(tag);\n } catch {\n refused(tag as string);\n return undefined;\n }\n}\n\n/**\n * Sets the language and writing direction for the part of the app inside it, on a wrapper `<div>` and on what the library portals out of it.\n *\n * The wrapper carries `dir` and `lang`, so CSS and the components that read\n * the computed direction follow it, as they follow `<html dir>`. A `locale`\n * alone sets the direction of its script, and a `dir` sets the direction\n * whatever the locale. A nested provider keeps whatever it leaves unset.\n *\n * Inside it, the date and time pickers take its `locale` unless given their\n * own, and their week starts on the first day of the locale they use unless\n * `firstDayOfWeek` is set, and a picker with a `locale` of its own is read\n * like a nested provider. With a `locale`, the numbers the library writes,\n * such as page numbers and badge counts, follow it, and so does the\n * filtering in `Combobox`, `Autocomplete`, `Taginput` and `Command`, which then ignores\n * accents where the language treats letters as the same. The library's\n * portaled content, such as a `Popover` panel, a `Modal` with `portal`, a\n * `Toast` or a `Portal`'s children, keeps the same `dir` and `lang` though\n * it renders outside the wrapper: in a container outside the wrapper, it\n * sits in a `display: contents` element that carries them. Without a\n * provider none of this changes.\n *\n * @function\n * @param {LocaleProviderProps} props - Props for the LocaleProvider.\n * @returns {JSX.Element} The wrapper, inside the context.\n *\n * @example\n * <LocaleProvider locale=\"ar-EG\">\n * <App />\n * </LocaleProvider>\n */\nexport const LocaleProvider = forwardRef<HTMLDivElement, LocaleProviderProps>(\n (\n { locale: localeProp, dir: dirProp, className, children, ...props },\n ref\n ) => {\n const outer = useContext(LocaleContext);\n const ownLocale = useMemo(() => validLocale(localeProp), [localeProp]);\n const ownLocaleDir = useMemo(\n () => (ownLocale ? localeDirection(ownLocale) : undefined),\n [ownLocale]\n );\n const locale = ownLocale || outer?.locale;\n const dir = dirProp || ownLocaleDir || outer?.dir;\n const value = useMemo(() => ({ locale, dir }), [locale, dir]);\n\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n\n // The wrapper, for portaled content to tell whether its target is inside\n // it, and the caller's ref. A callback ref's cleanup is held and run on\n // detach, as Toast and Modal do, since React 18 discards the return value.\n const elementRef = useRef<HTMLDivElement | null>(null);\n const consumerCleanupRef = useRef<(() => void) | null>(null);\n const setElement = useCallback(\n (node: HTMLDivElement | null) => {\n elementRef.current = node;\n if (typeof ref === 'function') {\n if (node === null) {\n const consumerCleanup = consumerCleanupRef.current;\n consumerCleanupRef.current = null;\n if (consumerCleanup) consumerCleanup();\n else ref(null);\n return;\n }\n const cleanup: unknown = ref(node);\n consumerCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n\n return (\n <LocaleContext.Provider value={value}>\n <LocaleElementContext.Provider value={elementRef}>\n <div\n ref={setElement}\n className={classNames(bulmaHelperClasses, className) || undefined}\n {...rest}\n dir={dir}\n lang={locale}\n >\n {children}\n </div>\n </LocaleElementContext.Provider>\n </LocaleContext.Provider>\n );\n }\n);\n\nLocaleProvider.displayName = 'LocaleProvider';\n\n/** What `useLocale` returns outside a provider, the same object each time. */\nconst noLocale: LocaleContextValue = {};\n\n/**\n * The locale and direction the nearest `LocaleProvider` sets, for an app's own `Intl` calls or its own portaled content; both are `undefined` outside one.\n *\n * It isn't the page's direction: with no provider, or one that sets no\n * direction, the page's `<html dir>` still decides. To act on the direction\n * an element is laid out in, read `getComputedStyle(element).direction`, as\n * the library's components do.\n *\n * @function\n * @returns {LocaleContextValue} The nearest provider's `locale` and `dir`.\n *\n * @example\n * const { locale } = useLocale();\n * const price = new Intl.NumberFormat(locale, {\n * style: 'currency',\n * currency: 'EUR',\n * }).format(12.5);\n */\nexport function useLocale(): LocaleContextValue {\n return useContext(LocaleContext) ?? noLocale;\n}\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. The nearest\n * provider's settings, or `null` outside any provider, so a caller can tell\n * \"no provider\" from \"a provider that sets nothing\".\n */\nexport function useLocaleScope(): LocaleContextValue | null {\n return useContext(LocaleContext);\n}\n\nconst displayContents: React.CSSProperties = { display: 'contents' };\n\n/** The `dir` and `lang` portaled content carries: a provider's, or a picker's own. */\nexport interface PortalLocale {\n /** The `lang` to carry, unset for none. */\n locale?: string;\n /** The `dir` to carry, unset for none. */\n dir?: string;\n}\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. Keeps the `dir`\n * and `lang` of the nearest provider, or the `scope` given in their place,\n * on content the library portals into `target`, which has left the\n * provider's wrapper behind.\n *\n * A target inside the provider's own wrapper gets the content as it is: it\n * inherits from the wrapper, and follows it when the provider changes.\n * Content that must be its container's direct child, a `<tr>` portaled into\n * a `<tbody>` there, stays one. Any other target, `document.body` included,\n * gets the content inside a `display: contents` element carrying the\n * values, which adds no box. So does content with a `scope` of its own, a\n * picker's panel, since the provider's values aren't its own.\n *\n * Which of the two is decided once, when the content mounts, and kept while\n * it stays: switching between them would put a different element in its\n * place and remount everything inside, losing typed text, focus and timers.\n * A change of locale or direction updates the wrapper's attributes instead.\n * A target is never left bare because something else, such as `<html>`,\n * happens to carry the same values, since that can stop being true without\n * the content remounting. Outside a provider it renders the children alone,\n * so nothing changes there.\n */\nexport function LocalePortalScope({\n children,\n target,\n scope,\n}: {\n children: React.ReactNode;\n /** The element the content is portaled into. */\n target: Element;\n /** Values to carry in place of the provider's, such as a picker's own. */\n scope?: PortalLocale;\n}) {\n const provider = useContext(LocaleContext);\n const element = useContext(LocaleElementContext);\n const [wrap] = useState(\n () => scope !== undefined || !element?.current?.contains(target)\n );\n if (!provider || !wrap) return <>{children}</>;\n const values = scope ?? provider;\n return (\n <div dir={values.dir} lang={values.locale} style={displayContents}>\n {children}\n </div>\n );\n}\n"],"names":["_jsx","_Fragment"],"mappings":"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"}
|