@allxsmith/bestax-bulma 5.67.4 → 5.67.6
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/Dropdown.js +24 -5
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/HoverCard.js +4 -1
- package/dist/esm/components/HoverCard.js.map +1 -1
- package/dist/esm/components/Message.js +8 -1
- package/dist/esm/components/Message.js.map +1 -1
- package/dist/esm/components/Tabs.js.map +1 -1
- package/dist/esm/elements/Notification.js.map +1 -1
- package/dist/esm/form/Combobox.js +7 -2
- package/dist/esm/form/Combobox.js.map +1 -1
- package/dist/esm/form/Control.js.map +1 -1
- package/dist/esm/form/DateTimeInputBase.js +23 -3
- package/dist/esm/form/DateTimeInputBase.js.map +1 -1
- package/dist/esm/form/TimeInputBase.js +6 -2
- package/dist/esm/form/TimeInputBase.js.map +1 -1
- package/dist/esm/form/_pickerInternals/TimeWheels.js +19 -16
- package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -1
- package/dist/esm/helpers/useFocusTrap.js +84 -10
- package/dist/esm/helpers/useFocusTrap.js.map +1 -1
- package/dist/esm/helpers/useOtherClasses.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +2773 -2641
- package/dist/index.cjs.map +1 -1
- package/dist/types/components/HoverCard.d.ts +5 -1
- package/dist/types/components/Message.d.ts +5 -1
- package/dist/types/components/Tabs.d.ts +5 -1
- package/dist/types/elements/Notification.d.ts +18 -2
- package/dist/types/form/Combobox.d.ts +4 -1
- package/dist/types/form/Control.d.ts +18 -4
- package/dist/types/form/DateTimeInputBase.d.ts +3 -0
- package/dist/types/form/TimeInputBase.d.ts +5 -1
- package/dist/types/form/_pickerInternals/TimeWheels.d.ts +6 -0
- package/dist/types/helpers/useFocusTrap.d.ts +14 -4
- package/dist/types/helpers/useOtherClasses.d.ts +6 -1
- package/dist/types-cjs/components/HoverCard.d.ts +5 -1
- package/dist/types-cjs/components/Message.d.ts +5 -1
- package/dist/types-cjs/components/Tabs.d.ts +5 -1
- package/dist/types-cjs/elements/Notification.d.ts +18 -2
- package/dist/types-cjs/form/Combobox.d.ts +4 -1
- package/dist/types-cjs/form/Control.d.ts +18 -4
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +3 -0
- package/dist/types-cjs/form/TimeInputBase.d.ts +5 -1
- package/dist/types-cjs/form/_pickerInternals/TimeWheels.d.ts +6 -0
- package/dist/types-cjs/helpers/useFocusTrap.d.ts +14 -4
- package/dist/types-cjs/helpers/useOtherClasses.d.ts +6 -1
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/CLAUDE.md +4 -1
- package/src/scss/_color-classes.scss +27 -0
- package/src/scss/_selected-row.scss +2 -10
- package/src/scss/components/_hovercard.scss +11 -0
- package/src/scss/components/_sidebar.scss +8 -5
- package/src/scss/components/_tabs.scss +16 -17
- package/src/scss/elements/_notification.scss +30 -1
- package/src/scss/form/_combobox.scss +12 -0
- package/src/scss/form/_slider.scss +68 -0
- package/src/scss/form/_timeinput.scss +7 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Notification.js","sources":["../../../src/elements/Notification.tsx"],"sourcesContent":["import React, {\n useEffect,\n useMemo,\n useRef,\n useState,\n useCallback,\n useSyncExternalStore,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnUnstyledColor } from '../helpers/colorDeprecations';\nimport { groupIntoPositionStacks } from '../helpers/positionStacks';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { usePortalContainer } from '../helpers/portal';\nimport { LocalePortalScope } from '../helpers/LocaleProvider';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\n\n/**\n * Props for the Notification component.\n */\nexport interface NotificationProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * Bulma color modifier for the notification (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.notification`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * notification renders unstyled; those log a console warning in development\n * and will be removed from this union in the next major version.\n */\n color?: (typeof validColors)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Use the light color variant. */\n isLight?: boolean;\n /**\n * Shows a close (delete) button in the notification. It renders\n * `type=\"button\"`, so it does not submit a form around it.\n *\n * The notification also takes `has-delete`, which pads its end by\n * `--bulma-notification-delete-padding-inline-end` so the text clears the\n * button. That rule ships in bestax's stylesheets, not Bulma's, so an app\n * styled by Bulma's CSS alone keeps Bulma's padding.\n */\n hasDelete?: boolean;\n /** Callback fired when the delete button is clicked. */\n onDelete?: () => void;\n /** Content inside the notification. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Notification` component is a Bulma-styled alert/message area for providing feedback, warnings, or information to users.\n *\n * @function\n * @param {NotificationProps} props - Props for the Notification component.\n * @returns {JSX.Element} The rendered notification element.\n * @see {@link https://bulma.io/documentation/elements/notification/ | Bulma Notification documentation}\n */\nexport const Notification: React.FC<NotificationProps> = ({\n className,\n color,\n textColor,\n isLight,\n hasDelete,\n onDelete,\n children,\n ...props\n}) => {\n warnUnstyledColor('Notification', color);\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n const bulmaClasses = usePrefixedClassNames('notification', {\n [`is-${color}`]: color && validColors.includes(color),\n 'is-light': isLight,\n 'has-delete': hasDelete,\n });\n\n const deleteClasses = usePrefixedClassNames('delete');\n\n const notificationClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <div className={notificationClasses} {...rest}>\n {hasDelete && (\n <button\n type=\"button\"\n className={deleteClasses}\n onClick={onDelete}\n aria-label=\"Close notification\"\n />\n )}\n {children}\n </div>\n );\n};\n\n// Programmatic Notification API\n\n/** Screen positions where programmatic notifications can be displayed. */\nexport type NotificationPosition =\n 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right';\n\n/**\n * Options for showing a programmatic notification.\n */\nexport interface NotificationOptions {\n /**\n * The message to display.\n *\n * For a notification other than `danger` and `warning`, NotificationContainer\n * announces the text the message renders, with an element's `aria-label`,\n * or an image's `alt`, standing in for what's inside it, a break between\n * block-level elements, and parts that are `aria-hidden`, `hidden` or\n * inline-styled `display: none` left out. Other ways of naming or hiding\n * content, such as `aria-labelledby`, CSS-generated content or a\n * stylesheet's `display: none`, aren't followed, so a message that relies on\n * them can be announced differently from what a screen reader would read.\n */\n message: string | React.ReactNode;\n /**\n * Bulma color modifier for the notification (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.notification`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * notification renders unstyled; those log a console warning in development\n * and will be removed from this union in the next major version.\n */\n color?: (typeof validColors)[number];\n /** Use the light color variant. */\n isLight?: boolean;\n /** Duration in ms before auto-close. Default 3000. */\n duration?: number;\n /**\n * Position on the screen. A notification shown without one goes to\n * `NotificationContainer`'s `position`.\n */\n position?: NotificationPosition;\n /**\n * When true, notifications enter a FIFO queue and display one at a time,\n * one queue across every `position`. Default false.\n */\n queue?: boolean;\n /** Show a delete (close) button. Default true. */\n hasDelete?: boolean;\n /** Stay open until dismissed. */\n indefinite?: boolean;\n /** Pause auto-close timer on hover. Default true. */\n pauseOnHover?: boolean;\n}\n\n/**\n * Internal representation of a notification instance.\n */\ninterface NotificationInstance {\n /** Unique identifier for this notification. */\n id: string;\n /** Configuration options for the notification. */\n options: NotificationOptions;\n}\n\nlet notificationId = 0;\nconst notificationListeners: Set<(items: NotificationInstance[]) => void> =\n new Set();\nlet notifications: NotificationInstance[] = [];\n\n// Queue support\nlet queuedNotifications: NotificationInstance[] = [];\nlet currentQueuedNotification: NotificationInstance | null = null;\n\n// The server has nowhere to portal a notification to, and its copy of this\n// module is shared by every request, so server rendering reads an empty list.\n// Hydration reads it too, which keeps the first client render matching the\n// server's.\nconst noNotifications: NotificationInstance[] = [];\nconst getServerNotifications = () => noNotifications;\n\n// What a container shows right now: the stacked notifications, then the queued\n// one on screen. NotificationContainer renders from this rather than from\n// updates alone, so notifications raised before it mounted still appear. It is\n// replaced rather than mutated, and only when listeners are notified, because\n// useSyncExternalStore needs the same array back between changes. An empty\n// list is `noNotifications` itself, so an empty store reads the same snapshot\n// on the client as on the server, and a notify that leaves nothing showing\n// when nothing was showing doesn't render the container again.\nlet visibleNotifications: NotificationInstance[] = noNotifications;\nconst getVisibleNotifications = () => visibleNotifications;\n\nconst notifyNotificationListeners = () => {\n const allVisible = [...notifications];\n if (currentQueuedNotification) {\n allVisible.push(currentQueuedNotification);\n }\n visibleNotifications = allVisible.length > 0 ? allVisible : noNotifications;\n notificationListeners.forEach(listener => listener([...allVisible]));\n};\n\nconst processQueuedNotification = () => {\n if (currentQueuedNotification || queuedNotifications.length === 0) return;\n currentQueuedNotification = queuedNotifications.shift()!;\n notifyNotificationListeners();\n};\n\n/**\n * Programmatic notification API for showing, closing, and managing notifications.\n *\n * @example\n * notification.success('File saved successfully');\n * notification.danger('Something went wrong', { duration: 5000 });\n */\nexport const notification = {\n /**\n * Show a notification with the given options.\n * @param {NotificationOptions} options - Notification configuration.\n * @returns {string} The unique ID of the created notification.\n */\n show: (options: NotificationOptions): string => {\n const id = `notification-${++notificationId}`;\n const instance = { id, options };\n\n if (options.queue) {\n queuedNotifications.push(instance);\n processQueuedNotification();\n } else {\n notifications.push(instance);\n notifyNotificationListeners();\n }\n\n return id;\n },\n\n /**\n * Show a success notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n success: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'success', ...options });\n },\n\n /**\n * Show a danger notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n danger: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'danger', ...options });\n },\n\n /**\n * Show a warning notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n warning: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'warning', ...options });\n },\n\n /**\n * Show an info notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n info: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'info', ...options });\n },\n\n /**\n * Close a specific notification by ID.\n * @param {string} id - The notification ID to close.\n */\n close: (id: string): void => {\n if (currentQueuedNotification && currentQueuedNotification.id === id) {\n currentQueuedNotification = null;\n processQueuedNotification();\n } else {\n queuedNotifications = queuedNotifications.filter(n => n.id !== id);\n notifications = notifications.filter(n => n.id !== id);\n }\n notifyNotificationListeners();\n },\n\n /** Close all notifications and clear the queue. */\n closeAll: (): void => {\n notifications = [];\n queuedNotifications = [];\n currentQueuedNotification = null;\n notifyNotificationListeners();\n },\n\n /**\n * Subscribe to notification state changes.\n * @param {(items: NotificationInstance[]) => void} listener - Callback invoked on changes.\n * @returns {() => void} Unsubscribe function.\n */\n subscribe: (\n listener: (items: NotificationInstance[]) => void\n ): (() => void) => {\n notificationListeners.add(listener);\n return () => notificationListeners.delete(listener);\n },\n};\n\n/**\n * Whether a notification of this color announces itself as an alert, rather\n * than politely through NotificationContainer's status region.\n *\n * @function isUrgentColor\n * @param {NotificationOptions['color']} color - The notification's color.\n * @returns {boolean} True for `danger` and `warning`.\n */\nconst isUrgentColor = (color: NotificationOptions['color']): boolean =>\n color === 'danger' || color === 'warning';\n\n/**\n * Single auto-dismissing notification item used by NotificationContainer.\n *\n * @function\n * @param {{ instance: NotificationInstance; onClose: (id: string) => void; registerMessage: (id: string, node: HTMLElement | null) => void }} props - Component props.\n * @returns {JSX.Element} The rendered notification item.\n */\nconst NotificationItem: React.FC<{\n instance: NotificationInstance;\n onClose: (id: string) => void;\n registerMessage: (id: string, node: HTMLElement | null) => void;\n}> = ({ instance, onClose, registerMessage }) => {\n const {\n message,\n color,\n isLight,\n duration = 3000,\n hasDelete = true,\n indefinite = false,\n pauseOnHover = true,\n } = instance.options;\n\n const [isPaused, setIsPaused] = useState(false);\n const urgent = isUrgentColor(color);\n\n const handleClose = useCallback(() => {\n onClose(instance.id);\n }, [onClose, instance.id]);\n\n const messageRef = useCallback(\n (node: HTMLElement | null) => {\n registerMessage(instance.id, node);\n },\n [registerMessage, instance.id]\n );\n\n // Auto-close timer\n useEffect(() => {\n if (indefinite || duration === 0 || isPaused) return undefined;\n\n const timer = setTimeout(handleClose, duration);\n return () => clearTimeout(timer);\n }, [duration, indefinite, isPaused, handleClose]);\n\n const handleMouseEnter = useCallback(() => {\n if (pauseOnHover) setIsPaused(true);\n }, [pauseOnHover]);\n\n const handleMouseLeave = useCallback(() => {\n if (pauseOnHover) setIsPaused(false);\n }, [pauseOnHover]);\n\n return (\n <Notification\n color={color}\n isLight={isLight}\n hasDelete={hasDelete}\n onDelete={handleClose}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n style={{ pointerEvents: 'auto' }}\n >\n {/* Only the message is announced, not the close button Notification\n renders ahead of its children. Danger and warning announce\n themselves as an assertive alert, which a screen reader reliably\n reads out even when it arrives with its text. The rest are announced\n through the container's status region, which reads their text from\n this span, so it carries no role of its own that would announce them\n a second time. */}\n {urgent ? (\n <span role=\"alert\" aria-live=\"assertive\">\n {message}\n </span>\n ) : (\n <span ref={messageRef}>{message}</span>\n )}\n </Notification>\n );\n};\n\n// The order NotificationContainer renders its stacks in: across the top of the\n// screen, then across the bottom.\nconst notificationStackOrder: readonly NotificationPosition[] = [\n 'top-left',\n 'top',\n 'top-right',\n 'bottom-left',\n 'bottom',\n 'bottom-right',\n];\n\n/**\n * Inline style that fixes a stack of notifications to its place on the screen.\n *\n * @function\n * @param {NotificationPosition} position - Where the stack sits.\n * @returns {React.CSSProperties} The stack's style.\n */\nconst notificationStackStyle = (\n position: NotificationPosition\n): React.CSSProperties => {\n const isBottom = position.startsWith('bottom');\n const isCenter = position === 'top' || position === 'bottom';\n const isRight = position.endsWith('right');\n\n return {\n position: 'fixed',\n zIndex: 100,\n display: 'flex',\n flexDirection: isBottom ? 'column-reverse' : 'column',\n gap: '0.75rem',\n padding: '1rem',\n pointerEvents: 'none',\n maxWidth: '100%',\n ...(isBottom ? { bottom: 0 } : { top: 0 }),\n ...(isCenter\n ? { left: '50%', transform: 'translateX(-50%)', alignItems: 'center' }\n : isRight\n ? { right: 0, alignItems: 'flex-end' }\n : { left: 0, alignItems: 'flex-start' }),\n };\n};\n\n/**\n * Container component for rendering programmatic notifications.\n * Place once at your app root to enable the notification API. A notification\n * shown with a `position` appears there, and one shown without goes to the\n * container's `position`, so the container renders a stack for each position\n * in use.\n *\n * It keeps a visually hidden `role=\"status\"` live region in the page from the\n * moment it mounts, even while nothing is showing, and announces every\n * notification other than `danger` and `warning` through it, a moment after\n * the notification appears. Those notifications carry no `role=\"status\"` of\n * their own, so `getByRole('status')` finds the region, not the notification.\n * The text stays in the region briefly, even if the notification closes in\n * the meantime, and while both are up the page holds two copies of it. A\n * polite notification that closes before its announcement is written, a\n * moment after it appears, isn't announced at all. `danger` and `warning`\n * notifications announce themselves as assertive alerts. The region is hidden\n * with inline styles, so it needs no stylesheet.\n *\n * @function\n * @param {{ position?: NotificationPosition }} props - Container props.\n * @returns {JSX.Element | null} The rendered notification container, or null on the server and while hydrating.\n */\nexport const NotificationContainer: React.FC<{\n /**\n * Where a notification shown without a `position` of its own appears.\n * Default: 'top-right'. When it changes, those notifications move without\n * remounting, but one shown with its own `position` equal to the old or new\n * value remounts and starts over as if it had just been shown.\n */\n position?: NotificationPosition;\n}> = ({ position = 'top-right' }) => {\n // Starts from the notifications already showing instead of an empty list,\n // then follows changes.\n const items = useSyncExternalStore(\n notification.subscribe,\n getVisibleNotifications,\n getServerNotifications\n );\n // A portal needs a document, and it has no server-rendered counterpart, so\n // the server render and the hydrating one render nothing, and the container\n // portals in from the render after hydration.\n const isHydrated = useIsHydrated();\n const resolveContainer = usePortalContainer();\n\n // The notifications the status region announces. Danger and warning\n // announce themselves.\n const politeItems = useMemo(\n () => items.filter(item => !isUrgentColor(item.options.color)),\n [items]\n );\n\n // Each polite notification's message element, so the text the region\n // announces is the text on screen, whatever the message renders.\n const messageNodesRef = useRef(new Map<string, HTMLElement>());\n const registerMessage = useCallback(\n (id: string, node: HTMLElement | null) => {\n if (node) {\n messageNodesRef.current.set(id, node);\n } else {\n messageNodesRef.current.delete(id);\n }\n },\n []\n );\n // StatusRegion only describes polite notifications that are on screen, and\n // each of those registered its message element when it mounted. The\n // fallback is for a notification announced without being rendered, should\n // the container ever render fewer than it announces: a plain-text message\n // still says itself, and anything else is skipped.\n const describe = useCallback((item: NotificationInstance) => {\n const node = messageNodesRef.current.get(item.id);\n /* istanbul ignore if: every polite notification on screen registers its message element when it mounts */\n if (!node) {\n const { message } = item.options;\n return typeof message === 'string' ? message : null;\n }\n return spokenText(node);\n }, []);\n\n if (typeof document === 'undefined' || !isHydrated) {\n return null;\n }\n\n const stacks = groupIntoPositionStacks(\n items,\n item => item.options.position,\n position,\n notificationStackOrder\n );\n\n const target = resolveContainer();\n return createPortal(\n <LocalePortalScope target={target}>\n {stacks.map(stack => (\n <div key={stack.key} style={notificationStackStyle(stack.position)}>\n {stack.items.map(item => (\n <NotificationItem\n key={item.id}\n instance={item}\n onClose={notification.close}\n registerMessage={registerMessage}\n />\n ))}\n </div>\n ))}\n <StatusRegion items={politeItems} describe={describe} />\n </LocalePortalScope>,\n target\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Notification.js","sources":["../../../src/elements/Notification.tsx"],"sourcesContent":["import React, {\n useEffect,\n useMemo,\n useRef,\n useState,\n useCallback,\n useSyncExternalStore,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnUnstyledColor } from '../helpers/colorDeprecations';\nimport { groupIntoPositionStacks } from '../helpers/positionStacks';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { usePortalContainer } from '../helpers/portal';\nimport { LocalePortalScope } from '../helpers/LocaleProvider';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\n\n/**\n * Props for the Notification component.\n */\nexport interface NotificationProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * Bulma color modifier for the notification (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.notification`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * notification renders unstyled; those log a console warning in development\n * and will be removed from this union in the next major version.\n *\n * `dark` takes the dark color's own text and background from bestax's\n * stylesheets, as a dark `Button` has. With Bulma's CSS alone, a dark\n * notification's text inherits the color around it, which on a light page\n * is one shade off its background.\n */\n color?: (typeof validColors)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Use the light color variant. The dark color has none, so `color=\"dark\"`\n * with `isLight` looks the same as without it, as a dark `Button` does.\n */\n isLight?: boolean;\n /**\n * Shows a close (delete) button in the notification. It renders\n * `type=\"button\"`, so it does not submit a form around it.\n *\n * The notification also takes `has-delete`, which pads its end by\n * `--bulma-notification-delete-padding-inline-end` so the text clears the\n * button. That rule ships in bestax's stylesheets, not Bulma's, so an app\n * styled by Bulma's CSS alone keeps Bulma's padding.\n */\n hasDelete?: boolean;\n /** Callback fired when the delete button is clicked. */\n onDelete?: () => void;\n /** Content inside the notification. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Notification` component is a Bulma-styled alert/message area for providing feedback, warnings, or information to users.\n *\n * @function\n * @param {NotificationProps} props - Props for the Notification component.\n * @returns {JSX.Element} The rendered notification element.\n * @see {@link https://bulma.io/documentation/elements/notification/ | Bulma Notification documentation}\n */\nexport const Notification: React.FC<NotificationProps> = ({\n className,\n color,\n textColor,\n isLight,\n hasDelete,\n onDelete,\n children,\n ...props\n}) => {\n warnUnstyledColor('Notification', color);\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n const bulmaClasses = usePrefixedClassNames('notification', {\n [`is-${color}`]: color && validColors.includes(color),\n 'is-light': isLight,\n 'has-delete': hasDelete,\n });\n\n const deleteClasses = usePrefixedClassNames('delete');\n\n const notificationClasses = classNames(\n bulmaClasses,\n bulmaHelperClasses,\n className\n );\n\n return (\n <div className={notificationClasses} {...rest}>\n {hasDelete && (\n <button\n type=\"button\"\n className={deleteClasses}\n onClick={onDelete}\n aria-label=\"Close notification\"\n />\n )}\n {children}\n </div>\n );\n};\n\n// Programmatic Notification API\n\n/** Screen positions where programmatic notifications can be displayed. */\nexport type NotificationPosition =\n 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right';\n\n/**\n * Options for showing a programmatic notification.\n */\nexport interface NotificationOptions {\n /**\n * The message to display.\n *\n * For a notification other than `danger` and `warning`, NotificationContainer\n * announces the text the message renders, with an element's `aria-label`,\n * or an image's `alt`, standing in for what's inside it, a break between\n * block-level elements, and parts that are `aria-hidden`, `hidden` or\n * inline-styled `display: none` left out. Other ways of naming or hiding\n * content, such as `aria-labelledby`, CSS-generated content or a\n * stylesheet's `display: none`, aren't followed, so a message that relies on\n * them can be announced differently from what a screen reader would read.\n */\n message: string | React.ReactNode;\n /**\n * Bulma color modifier for the notification (renders `is-<color>`).\n *\n * Only `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`,\n * `white`, `light`, and `dark` have shipped CSS for `.notification`. Every\n * other value the union accepts emits a class no CSS rule matches, so the\n * notification renders unstyled; those log a console warning in development\n * and will be removed from this union in the next major version.\n *\n * `dark` takes the dark color's own text and background from bestax's\n * stylesheets, as a dark `Button` has. With Bulma's CSS alone, a dark\n * notification's text inherits the color around it, which on a light page\n * is one shade off its background.\n */\n color?: (typeof validColors)[number];\n /**\n * Use the light color variant. The dark color has none, so `color=\"dark\"`\n * with `isLight` looks the same as without it, as a dark `Button` does.\n */\n isLight?: boolean;\n /** Duration in ms before auto-close. Default 3000. */\n duration?: number;\n /**\n * Position on the screen. A notification shown without one goes to\n * `NotificationContainer`'s `position`.\n */\n position?: NotificationPosition;\n /**\n * When true, notifications enter a FIFO queue and display one at a time,\n * one queue across every `position`. Default false.\n */\n queue?: boolean;\n /** Show a delete (close) button. Default true. */\n hasDelete?: boolean;\n /** Stay open until dismissed. */\n indefinite?: boolean;\n /** Pause auto-close timer on hover. Default true. */\n pauseOnHover?: boolean;\n}\n\n/**\n * Internal representation of a notification instance.\n */\ninterface NotificationInstance {\n /** Unique identifier for this notification. */\n id: string;\n /** Configuration options for the notification. */\n options: NotificationOptions;\n}\n\nlet notificationId = 0;\nconst notificationListeners: Set<(items: NotificationInstance[]) => void> =\n new Set();\nlet notifications: NotificationInstance[] = [];\n\n// Queue support\nlet queuedNotifications: NotificationInstance[] = [];\nlet currentQueuedNotification: NotificationInstance | null = null;\n\n// The server has nowhere to portal a notification to, and its copy of this\n// module is shared by every request, so server rendering reads an empty list.\n// Hydration reads it too, which keeps the first client render matching the\n// server's.\nconst noNotifications: NotificationInstance[] = [];\nconst getServerNotifications = () => noNotifications;\n\n// What a container shows right now: the stacked notifications, then the queued\n// one on screen. NotificationContainer renders from this rather than from\n// updates alone, so notifications raised before it mounted still appear. It is\n// replaced rather than mutated, and only when listeners are notified, because\n// useSyncExternalStore needs the same array back between changes. An empty\n// list is `noNotifications` itself, so an empty store reads the same snapshot\n// on the client as on the server, and a notify that leaves nothing showing\n// when nothing was showing doesn't render the container again.\nlet visibleNotifications: NotificationInstance[] = noNotifications;\nconst getVisibleNotifications = () => visibleNotifications;\n\nconst notifyNotificationListeners = () => {\n const allVisible = [...notifications];\n if (currentQueuedNotification) {\n allVisible.push(currentQueuedNotification);\n }\n visibleNotifications = allVisible.length > 0 ? allVisible : noNotifications;\n notificationListeners.forEach(listener => listener([...allVisible]));\n};\n\nconst processQueuedNotification = () => {\n if (currentQueuedNotification || queuedNotifications.length === 0) return;\n currentQueuedNotification = queuedNotifications.shift()!;\n notifyNotificationListeners();\n};\n\n/**\n * Programmatic notification API for showing, closing, and managing notifications.\n *\n * @example\n * notification.success('File saved successfully');\n * notification.danger('Something went wrong', { duration: 5000 });\n */\nexport const notification = {\n /**\n * Show a notification with the given options.\n * @param {NotificationOptions} options - Notification configuration.\n * @returns {string} The unique ID of the created notification.\n */\n show: (options: NotificationOptions): string => {\n const id = `notification-${++notificationId}`;\n const instance = { id, options };\n\n if (options.queue) {\n queuedNotifications.push(instance);\n processQueuedNotification();\n } else {\n notifications.push(instance);\n notifyNotificationListeners();\n }\n\n return id;\n },\n\n /**\n * Show a success notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n success: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'success', ...options });\n },\n\n /**\n * Show a danger notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n danger: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'danger', ...options });\n },\n\n /**\n * Show a warning notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n warning: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'warning', ...options });\n },\n\n /**\n * Show an info notification.\n * @param {string|React.ReactNode} message - The message to display.\n * @param {Partial<NotificationOptions>} [options] - Additional options.\n * @returns {string} The notification ID.\n */\n info: (\n message: string | React.ReactNode,\n options?: Partial<NotificationOptions>\n ): string => {\n return notification.show({ message, color: 'info', ...options });\n },\n\n /**\n * Close a specific notification by ID.\n * @param {string} id - The notification ID to close.\n */\n close: (id: string): void => {\n if (currentQueuedNotification && currentQueuedNotification.id === id) {\n currentQueuedNotification = null;\n processQueuedNotification();\n } else {\n queuedNotifications = queuedNotifications.filter(n => n.id !== id);\n notifications = notifications.filter(n => n.id !== id);\n }\n notifyNotificationListeners();\n },\n\n /** Close all notifications and clear the queue. */\n closeAll: (): void => {\n notifications = [];\n queuedNotifications = [];\n currentQueuedNotification = null;\n notifyNotificationListeners();\n },\n\n /**\n * Subscribe to notification state changes.\n * @param {(items: NotificationInstance[]) => void} listener - Callback invoked on changes.\n * @returns {() => void} Unsubscribe function.\n */\n subscribe: (\n listener: (items: NotificationInstance[]) => void\n ): (() => void) => {\n notificationListeners.add(listener);\n return () => notificationListeners.delete(listener);\n },\n};\n\n/**\n * Whether a notification of this color announces itself as an alert, rather\n * than politely through NotificationContainer's status region.\n *\n * @function isUrgentColor\n * @param {NotificationOptions['color']} color - The notification's color.\n * @returns {boolean} True for `danger` and `warning`.\n */\nconst isUrgentColor = (color: NotificationOptions['color']): boolean =>\n color === 'danger' || color === 'warning';\n\n/**\n * Single auto-dismissing notification item used by NotificationContainer.\n *\n * @function\n * @param {{ instance: NotificationInstance; onClose: (id: string) => void; registerMessage: (id: string, node: HTMLElement | null) => void }} props - Component props.\n * @returns {JSX.Element} The rendered notification item.\n */\nconst NotificationItem: React.FC<{\n instance: NotificationInstance;\n onClose: (id: string) => void;\n registerMessage: (id: string, node: HTMLElement | null) => void;\n}> = ({ instance, onClose, registerMessage }) => {\n const {\n message,\n color,\n isLight,\n duration = 3000,\n hasDelete = true,\n indefinite = false,\n pauseOnHover = true,\n } = instance.options;\n\n const [isPaused, setIsPaused] = useState(false);\n const urgent = isUrgentColor(color);\n\n const handleClose = useCallback(() => {\n onClose(instance.id);\n }, [onClose, instance.id]);\n\n const messageRef = useCallback(\n (node: HTMLElement | null) => {\n registerMessage(instance.id, node);\n },\n [registerMessage, instance.id]\n );\n\n // Auto-close timer\n useEffect(() => {\n if (indefinite || duration === 0 || isPaused) return undefined;\n\n const timer = setTimeout(handleClose, duration);\n return () => clearTimeout(timer);\n }, [duration, indefinite, isPaused, handleClose]);\n\n const handleMouseEnter = useCallback(() => {\n if (pauseOnHover) setIsPaused(true);\n }, [pauseOnHover]);\n\n const handleMouseLeave = useCallback(() => {\n if (pauseOnHover) setIsPaused(false);\n }, [pauseOnHover]);\n\n return (\n <Notification\n color={color}\n isLight={isLight}\n hasDelete={hasDelete}\n onDelete={handleClose}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n style={{ pointerEvents: 'auto' }}\n >\n {/* Only the message is announced, not the close button Notification\n renders ahead of its children. Danger and warning announce\n themselves as an assertive alert, which a screen reader reliably\n reads out even when it arrives with its text. The rest are announced\n through the container's status region, which reads their text from\n this span, so it carries no role of its own that would announce them\n a second time. */}\n {urgent ? (\n <span role=\"alert\" aria-live=\"assertive\">\n {message}\n </span>\n ) : (\n <span ref={messageRef}>{message}</span>\n )}\n </Notification>\n );\n};\n\n// The order NotificationContainer renders its stacks in: across the top of the\n// screen, then across the bottom.\nconst notificationStackOrder: readonly NotificationPosition[] = [\n 'top-left',\n 'top',\n 'top-right',\n 'bottom-left',\n 'bottom',\n 'bottom-right',\n];\n\n/**\n * Inline style that fixes a stack of notifications to its place on the screen.\n *\n * @function\n * @param {NotificationPosition} position - Where the stack sits.\n * @returns {React.CSSProperties} The stack's style.\n */\nconst notificationStackStyle = (\n position: NotificationPosition\n): React.CSSProperties => {\n const isBottom = position.startsWith('bottom');\n const isCenter = position === 'top' || position === 'bottom';\n const isRight = position.endsWith('right');\n\n return {\n position: 'fixed',\n zIndex: 100,\n display: 'flex',\n flexDirection: isBottom ? 'column-reverse' : 'column',\n gap: '0.75rem',\n padding: '1rem',\n pointerEvents: 'none',\n maxWidth: '100%',\n ...(isBottom ? { bottom: 0 } : { top: 0 }),\n ...(isCenter\n ? { left: '50%', transform: 'translateX(-50%)', alignItems: 'center' }\n : isRight\n ? { right: 0, alignItems: 'flex-end' }\n : { left: 0, alignItems: 'flex-start' }),\n };\n};\n\n/**\n * Container component for rendering programmatic notifications.\n * Place once at your app root to enable the notification API. A notification\n * shown with a `position` appears there, and one shown without goes to the\n * container's `position`, so the container renders a stack for each position\n * in use.\n *\n * It keeps a visually hidden `role=\"status\"` live region in the page from the\n * moment it mounts, even while nothing is showing, and announces every\n * notification other than `danger` and `warning` through it, a moment after\n * the notification appears. Those notifications carry no `role=\"status\"` of\n * their own, so `getByRole('status')` finds the region, not the notification.\n * The text stays in the region briefly, even if the notification closes in\n * the meantime, and while both are up the page holds two copies of it. A\n * polite notification that closes before its announcement is written, a\n * moment after it appears, isn't announced at all. `danger` and `warning`\n * notifications announce themselves as assertive alerts. The region is hidden\n * with inline styles, so it needs no stylesheet.\n *\n * @function\n * @param {{ position?: NotificationPosition }} props - Container props.\n * @returns {JSX.Element | null} The rendered notification container, or null on the server and while hydrating.\n */\nexport const NotificationContainer: React.FC<{\n /**\n * Where a notification shown without a `position` of its own appears.\n * Default: 'top-right'. When it changes, those notifications move without\n * remounting, but one shown with its own `position` equal to the old or new\n * value remounts and starts over as if it had just been shown.\n */\n position?: NotificationPosition;\n}> = ({ position = 'top-right' }) => {\n // Starts from the notifications already showing instead of an empty list,\n // then follows changes.\n const items = useSyncExternalStore(\n notification.subscribe,\n getVisibleNotifications,\n getServerNotifications\n );\n // A portal needs a document, and it has no server-rendered counterpart, so\n // the server render and the hydrating one render nothing, and the container\n // portals in from the render after hydration.\n const isHydrated = useIsHydrated();\n const resolveContainer = usePortalContainer();\n\n // The notifications the status region announces. Danger and warning\n // announce themselves.\n const politeItems = useMemo(\n () => items.filter(item => !isUrgentColor(item.options.color)),\n [items]\n );\n\n // Each polite notification's message element, so the text the region\n // announces is the text on screen, whatever the message renders.\n const messageNodesRef = useRef(new Map<string, HTMLElement>());\n const registerMessage = useCallback(\n (id: string, node: HTMLElement | null) => {\n if (node) {\n messageNodesRef.current.set(id, node);\n } else {\n messageNodesRef.current.delete(id);\n }\n },\n []\n );\n // StatusRegion only describes polite notifications that are on screen, and\n // each of those registered its message element when it mounted. The\n // fallback is for a notification announced without being rendered, should\n // the container ever render fewer than it announces: a plain-text message\n // still says itself, and anything else is skipped.\n const describe = useCallback((item: NotificationInstance) => {\n const node = messageNodesRef.current.get(item.id);\n /* istanbul ignore if: every polite notification on screen registers its message element when it mounts */\n if (!node) {\n const { message } = item.options;\n return typeof message === 'string' ? message : null;\n }\n return spokenText(node);\n }, []);\n\n if (typeof document === 'undefined' || !isHydrated) {\n return null;\n }\n\n const stacks = groupIntoPositionStacks(\n items,\n item => item.options.position,\n position,\n notificationStackOrder\n );\n\n const target = resolveContainer();\n return createPortal(\n <LocalePortalScope target={target}>\n {stacks.map(stack => (\n <div key={stack.key} style={notificationStackStyle(stack.position)}>\n {stack.items.map(item => (\n <NotificationItem\n key={item.id}\n instance={item}\n onClose={notification.close}\n registerMessage={registerMessage}\n />\n ))}\n </div>\n ))}\n <StatusRegion items={politeItems} describe={describe} />\n </LocalePortalScope>,\n target\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -63,6 +63,7 @@ const standalone$1 = {
|
|
|
63
63
|
onFieldChange: noop$1,
|
|
64
64
|
reportPanel: registerNothing,
|
|
65
65
|
placement: { position: 'bottom-left' },
|
|
66
|
+
startAligned: true,
|
|
66
67
|
multiple: false,
|
|
67
68
|
inline: false,
|
|
68
69
|
appendToBody: false,
|
|
@@ -77,7 +78,7 @@ function setRefs$2(node, own, forwarded) {
|
|
|
77
78
|
else if (forwarded)
|
|
78
79
|
forwarded.current = node;
|
|
79
80
|
}
|
|
80
|
-
const ComboboxParts = forwardRef(({ children, below, onSettle, open, defaultOpen = false, onOpenChange, onSelect, keepFirst = false, multiple = false, inline = false, position
|
|
81
|
+
const ComboboxParts = forwardRef(({ children, below, onSettle, open, defaultOpen = false, onOpenChange, onSelect, keepFirst = false, multiple = false, inline = false, position, appendToBody = false, size, label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, className, ...props }, ref) => {
|
|
81
82
|
const insideField = useInsideField();
|
|
82
83
|
const insideControl = useInsideControl();
|
|
83
84
|
const ownField = rendersOwnField('Combobox', {
|
|
@@ -196,6 +197,7 @@ const ComboboxParts = forwardRef(({ children, below, onSettle, open, defaultOpen
|
|
|
196
197
|
onFieldChange,
|
|
197
198
|
reportPanel,
|
|
198
199
|
placement,
|
|
200
|
+
startAligned: position === undefined,
|
|
199
201
|
size: validSize,
|
|
200
202
|
multiple,
|
|
201
203
|
inline,
|
|
@@ -273,7 +275,7 @@ ComboboxInput.displayName = 'ComboboxInput';
|
|
|
273
275
|
* @returns {JSX.Element | null} The panel, or nothing while the list is closed or its children are all empty.
|
|
274
276
|
*/
|
|
275
277
|
const ComboboxMenu = ({ children, className, style, onMouseDown, onPointerDownCapture, ...props }) => {
|
|
276
|
-
const { engine, inline, appendToBody, placement, reportPanel, size } = useCombobox();
|
|
278
|
+
const { engine, inline, appendToBody, placement, startAligned, reportPanel, size, } = useCombobox();
|
|
277
279
|
// Children that are all `null`, `false` or `''` leave no panel, whatever
|
|
278
280
|
// `open` says. This reads the elements it's handed, not what they render.
|
|
279
281
|
const hasContent = flattenChildren(children).some(child => child !== '');
|
|
@@ -289,6 +291,9 @@ const ComboboxMenu = ({ children, className, style, onMouseDown, onPointerDownCa
|
|
|
289
291
|
}, [mounted, reportPanel]);
|
|
290
292
|
const menuClass = usePrefixedClassNames('dropdown-menu', 'combobox-menu', {
|
|
291
293
|
[`is-${placement.position}`]: true,
|
|
294
|
+
// The default lines up with the field's inline start, so the stylesheet
|
|
295
|
+
// moves it to the right edge on a right-to-left page.
|
|
296
|
+
'is-start-aligned': startAligned,
|
|
292
297
|
'is-portal': appendToBody,
|
|
293
298
|
[`is-${size}`]: !!size,
|
|
294
299
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.js","sources":["../../../src/form/Combobox.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { PopupPortal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { flattenChildren } from '../helpers/flattenChildren';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { useLocaleMatcher } from '../helpers/localeFormat';\nimport {\n AnchoredPosition,\n marginGap,\n useAnchoredPosition,\n} from '../helpers/useAnchoredPosition';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport { CheckIcon } from '../helpers/checkIcon';\nimport {\n ComboboxEngine,\n useComboboxEngine,\n} from '../helpers/useComboboxEngine';\nimport type { PopoverPosition } from '../components/Popover';\nimport { Field } from './Field';\nimport { Input, InputProps } from './Input';\nimport { FormFieldProps } from './fieldProps';\nimport {\n rendersOwnField,\n useFieldsetDisabled,\n useInsideControl,\n useInsideField,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { useControlLoading } from './controlLoading';\nimport { HiddenValues, ValueTags, tagIds } from './_selectInternals/ValueTags';\n\nconst validComboboxSizes = ['small', 'medium', 'large'] as const;\n\n// What the status region announces: the `Combobox.Empty` content, as the one\n// item it's handed while that content is on screen because of the user's\n// typing.\nconst typedNoMatches = [{ id: 'empty' }];\nconst nothingToAnnounce: Array<{ id: string }> = [];\n\n/**\n * One item in a Combobox's `data`. A string there is an item whose label is\n * its value.\n */\nexport interface ComboboxItemData {\n /**\n * What `onSelect` and `onChange` hand back, and what `name` posts. Unique\n * within the Combobox.\n */\n value: string;\n /** What the item shows, and what typing matches. The `value` when it's left out. */\n label?: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it.\n */\n disabled?: boolean;\n /**\n * The heading the item goes under. Groups show in the order `data` first\n * names them, and the items with no group show together where the first of\n * them is.\n */\n group?: string;\n}\n\n/** What a Combobox takes whether it's given `data` or built from parts. */\ninterface ComboboxBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'onChange' | 'onSelect' | 'defaultValue'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /**\n * The field's label, which names `Combobox.Input` through `htmlFor`, and\n * the list through `aria-labelledby`. Dropped inside an outer `Field`,\n * whose label names both instead when it points at the field. When\n * `Combobox.Input` has an `id` of its own, server markup names the field\n * through `aria-labelledby` until the page hydrates and the label's `for`\n * catches up.\n */\n label?: React.ReactNode;\n /**\n * Props for the label element. An explicit `htmlFor` takes over the\n * association: give `Combobox.Input` the same `id`, and the list is still\n * named after the label.\n */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /**\n * Controlled open state. When set, opening and closing only report\n * through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the open state asked for: `true` from typing, a click in\n * the field or Down Arrow, and `false` from Escape, Tab, a pick with one\n * value, focus leaving or a press outside. Fires in controlled and\n * uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called with an item's `value` when it's picked with Enter or a click.\n * A disabled item is never picked. With `data`, `onChange` reports the\n * value that follows. Built from parts, the Combobox keeps no value and\n * doesn't change the text in the field: update yours here.\n */\n onSelect?: (value: string) => void;\n /**\n * Highlights the first enabled item whenever the list opens or its\n * items change, so Enter picks the top match. It only highlights:\n * leaving the field still picks nothing, and so does Tab.\n * @defaultValue false\n */\n keepFirst?: boolean;\n /**\n * The list is always on screen, in the flow under the field, as in a\n * Popover or a page panel. There's no menu, so nothing closes it, and\n * Escape goes to whatever is around it.\n * @defaultValue false\n */\n inline?: boolean;\n /**\n * Where the menu opens against the field: below (`bottom-*`) or above\n * (`top-*`), lined up with its left or right edge. `auto` picks the one\n * that keeps the list in the viewport, preferring below. The same union\n * Popover takes.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Renders the menu through `Portal`, into the `portalContainer` a\n * `ConfigProvider` sets, else the `Modal`, `Dialog` or `Command.Dialog`\n * it's in, else `document.body`, fixed to the viewport at the field, so a\n * container that clips its overflow can't cut it off. It then shows from\n * the commit after hydration, never in server markup. Theming variables set\n * on an ancestor reach it only when the portal's container is inside that\n * ancestor, as with Popover.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /** Sizes the field and the items together. */\n size?: 'small' | 'medium' | 'large';\n}\n\n/** What a Combobox given `data` takes, with one value or several. */\ninterface ComboboxDataBaseProps extends ComboboxBaseProps {\n /** The field's placeholder, with `data`. */\n placeholder?: string;\n /**\n * A form field name, with `data`. A hidden input posts the value, empty\n * while there's none, and with `multiple` a hidden input posts each value.\n */\n name?: string;\n /**\n * What the menu shows in place of the list, with `data`, when nothing\n * matches the typing, such as \"No countries match\". It's announced the way\n * `Combobox.Empty` is. Without it, the menu closes while nothing matches.\n */\n empty?: React.ReactNode;\n /**\n * Renders an item's content, with `data`, in place of its label. It's\n * handed the item from `data`, a string there arriving as\n * `{ value, label }`.\n */\n itemTemplate?: (item: ComboboxItemData) => React.ReactNode;\n /**\n * The field can't be used, with `data`: it can't be focused or typed in,\n * its items can't be picked, its tags lose their buttons, and its hidden\n * inputs don't post, the way a disabled field's value doesn't.\n */\n disabled?: boolean;\n /**\n * A value is needed, with `data`. The field is `required` while nothing is\n * picked, so the browser's own check stops the form the way it does for\n * Autocomplete's field, and it's `aria-required` the whole time. The check\n * reads the field's text, which Enter, the list closing or leaving the\n * field puts back to the pick.\n */\n required?: boolean;\n /**\n * The id of the form the value posts with, with `data`, for a field\n * outside it. It goes on the hidden inputs, and on the field so that form\n * checks `required` too.\n */\n form?: string;\n /**\n * The field's `id`, with `data`, which the label then points at, and so\n * can a label of your own. Built from parts, it lands on `div.combobox`, so\n * give `Combobox.Input` the `id` instead.\n */\n id?: string;\n /**\n * Names the field and the list, with `data`, in place of a `label`. Built\n * from parts, it lands on `div.combobox`, so put it on `Combobox.Input`.\n */\n 'aria-label'?: string;\n /**\n * The ids of what names the field and the list, with `data`, in place of\n * a `label`. Built from parts, it lands on `div.combobox`, so put it on\n * `Combobox.Input`.\n */\n 'aria-labelledby'?: string;\n /** With `data`, the Combobox renders its own parts. */\n children?: never;\n}\n\n/** Props for a Combobox given `data`, with one value. */\nexport interface ComboboxSingleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders the field, the menu, the list,\n * the groups and the empty message itself. A string is an item whose label\n * is its value, and an object is `{ value, label?, disabled?, group? }`.\n * Typing filters the items by label, ignoring case, and inside a\n * `LocaleProvider` with a `locale`, ignoring accents too where that\n * language does, so \"cafe\" finds \"Café\". The Combobox keeps the value. Leave it out to build the Combobox from parts.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`. With `data`, the value is an array, and the picks show\n * as tags under the field, inside its Field, each with a button that takes\n * it off. The field's description lists them, since its text is the\n * search.\n * @defaultValue false\n */\n multiple?: false;\n /**\n * The value, controlled, with `data`: the picked item's `value`, or `null`\n * for none, and with `multiple` an array of them. With one value, the\n * field shows the picked item's label while you aren't typing in it, and\n * the list closing or the field being left puts it back over any typing.\n * A field emptied and left like that clears the value.\n */\n value?: string | null;\n /** The value to start with when uncontrolled, with `data`. */\n defaultValue?: string | null;\n /**\n * Called with the new value, with `data`, when a pick, a tag's button or\n * a field left empty changes it: an item's `value` or `null`, or with\n * `multiple` the array.\n */\n onChange?: (value: string | null) => void;\n /** With one value there are no tags to name. */\n ariaCloseLabel?: never;\n}\n\n/** Props for a Combobox given `data`, with several values. */\nexport interface ComboboxMultipleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders itself. A string is an item whose\n * label is its value, and an object is `{ value, label?, disabled?, group? }`.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked: the value is an array, and the picks show\n * as tags under the field, each with a button that takes it off. The\n * field's description lists them.\n */\n multiple: true;\n /** The values, controlled: the picked items' `value`s. */\n value?: string[];\n /** The values to start with when uncontrolled. */\n defaultValue?: string[];\n /** Called with the new array when a pick or a tag's button changes it. */\n onChange?: (value: string[]) => void;\n /**\n * Names each tag's button, in place of \"Remove\" and the item's label, as\n * Taginput's does. The button is then described by its tag's label, so it\n * still says which tag it takes off.\n */\n ariaCloseLabel?: string;\n}\n\n/** Props for a Combobox given `data`. */\ntype ComboboxDataProps = ComboboxSingleDataProps | ComboboxMultipleDataProps;\n\n/** Props for a Combobox built from parts. */\nexport interface ComboboxPartsProps extends ComboboxBaseProps {\n /**\n * The parts, in order: `Combobox.Input`, then `Combobox.Menu` with\n * `Combobox.List` and `Combobox.Empty` in it. With `inline`, the\n * `Combobox.List` and `Combobox.Empty` go straight in. Render\n * `Combobox.List` while there are items and `Combobox.Empty` while\n * there aren't: the empty message sits beside the list, not in it. With\n * `data` there are none to give: children given with it are ignored, with\n * a warning in development.\n */\n children?: React.ReactNode;\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`.\n * @defaultValue false\n */\n multiple?: boolean;\n /** Built from parts, there's no `data`. */\n data?: never;\n /** Built from parts, the app keeps the value. */\n value?: never;\n /** Built from parts, the app keeps the value. */\n defaultValue?: never;\n /** Built from parts, `onSelect` reports a pick. */\n onChange?: never;\n /** Built from parts, `Combobox.Input` takes the placeholder. */\n placeholder?: never;\n /** Built from parts, the app posts the value. */\n name?: never;\n /** Built from parts, `Combobox.Empty` is the empty message. */\n empty?: never;\n /** Built from parts, `Combobox.Item` renders its own content. */\n itemTemplate?: never;\n /** Built from parts, `Combobox.Input` takes `disabled`. */\n disabled?: never;\n /** Built from parts, `Combobox.Input` takes `required`. */\n required?: never;\n /** Built from parts, the app posts the value. */\n form?: never;\n}\n\n/**\n * Props for the Combobox component: given `data`, it renders itself and\n * keeps the value, and without it, it's built from parts. The helper props,\n * the other attributes and the `ref` land on the `div.combobox` around the\n * field and the list. It renders the `Field` and the label itself, unless an\n * outer `Field` already does.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the `div.combobox` around the field and the list.\n */\nexport type ComboboxProps =\n ComboboxSingleDataProps | ComboboxMultipleDataProps | ComboboxPartsProps;\n\n/**\n * Props for Combobox.Input, the text field. It renders `Input`, so its icons,\n * `isLoading` and `color` work as they do there. The Field props go on the\n * Combobox, and the size comes from it. The field is `autoComplete=\"off\"`,\n * so the browser's own suggestions don't open over the list, and that isn't\n * yours to set.\n */\nexport type ComboboxInputProps = Omit<\n InputProps,\n // By name, since the docs read only names out of an Omit, and\n // `__typetests__/combobox.tsx` fails if one goes missing. The Field props:\n | 'label'\n | 'labelSize'\n | 'labelProps'\n | 'horizontal'\n | 'message'\n | 'messageColor'\n | 'fieldClassName'\n // And what the Combobox sets on the field itself:\n | 'size'\n | 'role'\n | 'autoComplete'\n>;\n\n/** Props for Combobox.Menu, the floating panel under the field. */\nexport interface ComboboxMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * What the panel shows: `Combobox.List` while there are items, and\n * `Combobox.Empty` while there aren't. Children that are all `null`,\n * `false` or `''`, or empty Fragments, keep the panel shut, so write the\n * conditional here. A component that renders nothing, or a\n * `Combobox.List` with no items in it, still counts, and shows an\n * empty panel.\n */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.List, the list. Its `id` is the one the field's\n * `aria-controls` names, so it isn't yours to set.\n */\nexport interface ComboboxListProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'id'\n> {\n /** `Combobox.Item`s and `Combobox.Group`s, in the order they're shown. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.Item, one choice in the list. Its `id` follows from\n * its `value`, since the field's `aria-activedescendant` names it, so it\n * isn't yours to set.\n */\nexport interface ComboboxItemProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'onSelect' | 'id'\n> {\n /** What `onSelect` hands back. Unique within the Combobox. */\n value: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it, and it's never `aria-selected`.\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * It's the value, or one of them. It shows a check mark, the list opens\n * with the highlight on it, and with `multiple` it's the `aria-selected`.\n * @defaultValue false\n */\n checked?: boolean;\n /** What the item shows: text, or text with an avatar, a tag or a hint. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Group, items under a heading. */\nexport interface ComboboxGroupProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role'\n> {\n /**\n * The heading, which also names the group for assistive tech, unless you\n * give the group an `aria-label` or `aria-labelledby` of its own.\n */\n label: React.ReactNode;\n /** The group's `Combobox.Item`s. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Empty, the message shown in place of the list. */\nexport interface ComboboxEmptyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The message, such as \"No countries match\". Its text is announced when\n * typing brings it on screen and isn't read again while it stays, so a\n * message that names the query is heard for the first query only.\n */\n children?: React.ReactNode;\n}\n\n/** What the Combobox hands its parts. */\ninterface ComboboxContextValue {\n engine: ComboboxEngine;\n /** The id the field takes when it's given none. */\n inputId: string | undefined;\n /** Tells the Combobox the id the field was given, so the label follows it. */\n reportInputId: (id: string | undefined) => void;\n /** The id of the label that names the field, which names the list too. */\n labelId: string | undefined;\n /**\n * The id of the label the Combobox renders itself, when it names the field.\n * The field points at it while its own `id` hasn't reached the label yet.\n */\n ownLabelId: string | undefined;\n /** Tells the Combobox the field's `isLoading`, which holds the empty message's announcement. */\n reportLoading: (loading: boolean) => void;\n /** Records the empty message while it's on screen. Returns the function that forgets it. */\n reportEmpty: (element: HTMLElement) => () => void;\n /** A change to the field's value, which is the user typing. */\n onFieldChange: (value: string) => void;\n /**\n * Records the menu's panel while it's on screen, so it's placed and\n * counts as inside. Returns the function that forgets it.\n */\n reportPanel: (element: HTMLElement) => () => void;\n /** Where the panel goes against the field. */\n placement: AnchoredPosition;\n size?: ComboboxProps['size'];\n multiple: boolean;\n inline: boolean;\n appendToBody: boolean;\n}\n\nconst noop = () => {};\nconst registerNothing = () => noop;\n\n// What a part rendered outside a Combobox reads: closed, with nothing to\n// report to, so it renders its markup and does nothing.\nconst standalone: ComboboxContextValue = {\n engine: {\n open: false,\n expanded: false,\n highlighted: null,\n typed: false,\n listboxId: '',\n itemId: () => '',\n rootRef: { current: null },\n inputRef: { current: null },\n listboxRef: { current: null },\n registerPopup: registerNothing,\n registerItem: registerNothing,\n onKeyDown: noop,\n onChange: noop,\n onClick: noop,\n onBlur: noop,\n hover: noop,\n pick: noop,\n keepFocus: noop,\n markInside: noop,\n },\n inputId: undefined,\n reportInputId: noop,\n labelId: undefined,\n ownLabelId: undefined,\n reportLoading: noop,\n reportEmpty: registerNothing,\n onFieldChange: noop,\n reportPanel: registerNothing,\n placement: { position: 'bottom-left' },\n multiple: false,\n inline: false,\n appendToBody: false,\n};\n\nconst ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nconst useCombobox = () => useContext(ComboboxContext) ?? standalone;\n\n/** Hands a node to a forwarded ref and to one of the component's own. */\nfunction setRefs<T>(\n node: T | null,\n own: React.MutableRefObject<T | null>,\n forwarded: React.ForwardedRef<T>\n) {\n own.current = node;\n if (typeof forwarded === 'function') forwarded(node);\n else if (forwarded) forwarded.current = node;\n}\n\n/**\n * The Combobox built from parts: the field, the menu, the list and the\n * keys, with the data, the filtering and the value left to the app.\n */\n/** What the parts root takes from the Combobox given `data`, beyond the parts' props. */\ninterface ComboboxPartsRootProps extends ComboboxPartsProps {\n /**\n * Shown under the Combobox, inside its Field and ahead of the message: the\n * tags of several values. While it's given, the two share a wrapper, so\n * they stay together in a horizontal Field's body.\n */\n below?: React.ReactNode;\n /**\n * Called when Enter goes on to the form with nothing to pick, so the\n * Combobox given `data` can put the field's text back first, `inline`\n * included, where nothing closes.\n */\n onSettle?: () => void;\n}\n\nconst ComboboxParts = forwardRef<HTMLDivElement, ComboboxPartsRootProps>(\n (\n {\n children,\n below,\n onSettle,\n open,\n defaultOpen = false,\n onOpenChange,\n onSelect,\n keepFirst = false,\n multiple = false,\n inline = false,\n position = 'bottom-left',\n appendToBody = false,\n size,\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Combobox', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n // The field's own `id`, when `Combobox.Input` was given one, which the\n // label then points at.\n const [givenInputId, setGivenInputId] = useState<string | undefined>();\n const {\n controlId,\n fieldLabelProps,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id: givenInputId,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: true,\n });\n const engine = useComboboxEngine({\n open,\n defaultOpen,\n onOpenChange,\n onSelect,\n onSettle,\n keepFirst,\n multiple,\n inline,\n // A portaled panel has no server markup to point at.\n deferred: appendToBody && !inline,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const validSize = (validComboboxSizes as readonly string[]).includes(\n size as string\n )\n ? size\n : undefined;\n const rootClass = usePrefixedClassNames('combobox', {\n [`is-${validSize}`]: !!validSize,\n 'is-inline': inline,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // A polite status region, in the page from the start so it's there\n // before anything is written into it, announces `Combobox.Empty` when\n // the user's typing leaves it on screen: once each time that happens,\n // not again on each keystroke while it stays. An empty field isn't a\n // search, so it stays quiet then. While the field's `isLoading`, or a\n // loading Control around the Combobox, says results are on their way, it\n // waits, and it's said once loading ends with the message still there.\n const [inputLoading, setInputLoading] = useState(false);\n const controlLoading = useControlLoading();\n const [hasText, setHasText] = useState(false);\n const emptyRef = useRef<HTMLElement | null>(null);\n const [emptyShown, setEmptyShown] = useState(false);\n const announced =\n engine.typed && hasText && emptyShown && !inputLoading && !controlLoading\n ? typedNoMatches\n : nothingToAnnounce;\n // The region reads the text on screen, whatever the message renders.\n const describeEmpty = useCallback(() => {\n const node = emptyRef.current;\n /* istanbul ignore if: it's only announced while it's on screen */\n if (!node) return null;\n return spokenText(node);\n }, []);\n\n const reportEmpty = useCallback((element: HTMLElement) => {\n emptyRef.current = element;\n setEmptyShown(true);\n return () => {\n emptyRef.current = null;\n setEmptyShown(false);\n };\n }, []);\n // The menu is placed from here rather than from the part, since this\n // is where the field's element is known by the time the panel mounts.\n const panelRef = useRef<HTMLElement | null>(null);\n const [panelShown, setPanelShown] = useState(false);\n const placement = useAnchoredPosition(engine.rootRef, panelRef, {\n active: panelShown,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-combobox-menu-offset` as a margin, so\n // the coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n matchWidth: true,\n // The list filters as the user types, so the menu's height changes.\n followContent: true,\n });\n const { registerPopup } = engine;\n const reportPanel = useCallback(\n (element: HTMLElement) => {\n const forget = registerPopup(element);\n panelRef.current = element;\n setPanelShown(true);\n return () => {\n forget();\n panelRef.current = null;\n setPanelShown(false);\n };\n },\n [registerPopup]\n );\n\n const onFieldChange = (value: string) => {\n setHasText(value !== '');\n engine.onChange();\n };\n\n // A new value each render: the engine's state and handlers are, and the\n // parts read the highlight and the open state from it.\n const context: ComboboxContextValue = {\n engine,\n inputId: controlId,\n reportInputId: setGivenInputId,\n labelId: listLabelId,\n ownLabelId: label && ownField ? listLabelId : undefined,\n reportLoading: setInputLoading,\n reportEmpty,\n onFieldChange,\n reportPanel,\n placement,\n size: validSize,\n multiple,\n inline,\n appendToBody,\n };\n\n const { rootRef } = engine;\n const rootRefs = useCallback(\n (node: HTMLDivElement | null) => setRefs(node, rootRef, ref),\n [rootRef, ref]\n );\n\n const comboboxElement = (\n // The ref after the spread, so the element stays the Combobox's.\n <div\n className={classNames(rootClass, bulmaHelperClasses, className)}\n {...rest}\n ref={rootRefs}\n >\n <ComboboxContext.Provider value={context}>\n {children}\n </ComboboxContext.Provider>\n <StatusRegion items={announced} describe={describeEmpty} />\n </div>\n );\n const fieldElement =\n below === undefined ? (\n comboboxElement\n ) : (\n <div>\n {comboboxElement}\n {/* Part of the Combobox, as the menu is: a press here keeps focus\n in the field and doesn't count as outside, so the list and the\n search stay put. */}\n <div\n onPointerDownCapture={engine.markInside}\n onMouseDown={engine.keepFocus}\n >\n {below}\n </div>\n </div>\n );\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {fieldElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fieldElement}\n {messageEl}\n </>\n );\n }\n);\nComboboxParts.displayName = 'ComboboxParts';\n\n/**\n * The text field, with the combobox role and the keys, rendered as an `Input`.\n *\n * @function\n * @param {ComboboxInputProps} props - Props for the Combobox.Input component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the `<input>`.\n * @returns {JSX.Element} The field in its Control.\n */\nexport const ComboboxInput = forwardRef<HTMLInputElement, ComboboxInputProps>(\n (\n {\n id,\n isLoading,\n controlSize,\n onKeyDown,\n onChange,\n onClick,\n onBlur,\n 'aria-autocomplete': ariaAutocomplete,\n ...props\n },\n ref\n ) => {\n const context = useCombobox();\n const { engine, reportInputId, reportLoading } = context;\n // Inside a caller's Control the field renders none of its own, so the\n // Combobox's size isn't handed to one there.\n const insideControl = useInsideControl();\n useClientLayoutEffect(() => {\n reportInputId(id);\n return () => reportInputId(undefined);\n }, [reportInputId, id]);\n useClientLayoutEffect(() => {\n reportLoading(!!isLoading);\n return () => reportLoading(false);\n }, [reportLoading, isLoading]);\n const { inputRef } = engine;\n const inputRefs = useCallback(\n (node: HTMLInputElement | null) => setRefs(node, inputRef, ref),\n [inputRef, ref]\n );\n const { expanded, highlighted } = engine;\n // An `id` of the field's own reaches the label from a layout effect, so\n // in server markup, and the first render, the label's `for` still names\n // the generated id. Until then the field points at the label itself,\n // unless the caller named it.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n const labelledBy = callerNamed\n ? props['aria-labelledby']\n : id !== undefined && id !== context.inputId\n ? context.ownLabelId\n : undefined;\n\n return (\n // The attributes the Combobox owns after the caller's, so a stray\n // `aria-expanded` never wins.\n <Input\n {...props}\n ref={inputRefs}\n id={id ?? context.inputId}\n aria-labelledby={labelledBy}\n isLoading={isLoading}\n size={context.size}\n controlSize={controlSize ?? (insideControl ? undefined : context.size)}\n role=\"combobox\"\n aria-autocomplete={ariaAutocomplete ?? 'list'}\n aria-haspopup=\"listbox\"\n aria-expanded={expanded}\n aria-controls={expanded ? engine.listboxId : undefined}\n aria-activedescendant={\n expanded && highlighted !== null\n ? engine.itemId(highlighted)\n : undefined\n }\n autoComplete=\"off\"\n onKeyDown={event => {\n onKeyDown?.(event);\n engine.onKeyDown(event);\n }}\n onChange={event => {\n onChange?.(event);\n context.onFieldChange(event.target.value);\n }}\n onClick={event => {\n onClick?.(event);\n if (!event.defaultPrevented) engine.onClick();\n }}\n onBlur={event => {\n onBlur?.(event);\n engine.onBlur(event);\n }}\n />\n );\n }\n);\nComboboxInput.displayName = 'ComboboxInput';\n\n/**\n * The floating panel under the field, on screen while the list is open and its children aren't all empty.\n *\n * @function\n * @param {ComboboxMenuProps} props - Props for the Combobox.Menu component.\n * @returns {JSX.Element | null} The panel, or nothing while the list is closed or its children are all empty.\n */\nexport const ComboboxMenu: React.FC<ComboboxMenuProps> = ({\n children,\n className,\n style,\n onMouseDown,\n onPointerDownCapture,\n ...props\n}) => {\n const { engine, inline, appendToBody, placement, reportPanel, size } =\n useCombobox();\n // Children that are all `null`, `false` or `''` leave no panel, whatever\n // `open` says. This reads the elements it's handed, not what they render.\n const hasContent = flattenChildren(children).some(child => child !== '');\n const shown = engine.open && !inline && hasContent;\n // A portaled panel has no server markup, so it only exists from the\n // commit after hydration. Everything that measures it waits for that.\n const hydrated = useIsHydrated();\n const mounted = shown && (hydrated || !appendToBody);\n const panelRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(() => {\n const panel = panelRef.current;\n return mounted && panel ? reportPanel(panel) : undefined;\n }, [mounted, reportPanel]);\n\n const menuClass = usePrefixedClassNames('dropdown-menu', 'combobox-menu', {\n [`is-${placement.position}`]: true,\n 'is-portal': appendToBody,\n [`is-${size}`]: !!size,\n });\n const contentClass = usePrefixedClassNames('dropdown-content');\n\n // Inline, the list is in the flow already.\n if (inline) return <>{children}</>;\n if (!shown) return null;\n\n return (\n <PopupPortal disabled={!appendToBody}>\n <div\n {...props}\n ref={panelRef}\n className={classNames(menuClass, className)}\n style={\n appendToBody\n ? {\n ...style,\n position: 'fixed',\n top: placement.top,\n left: placement.left,\n minWidth: placement.minWidth,\n }\n : style\n }\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n onPointerDownCapture={event => {\n onPointerDownCapture?.(event);\n engine.markInside(event);\n }}\n >\n <div className={contentClass}>{children}</div>\n </div>\n </PopupPortal>\n );\n};\nComboboxMenu.displayName = 'ComboboxMenu';\n\n/**\n * The list of items, a `listbox` named by the label that names the field.\n *\n * @function\n * @param {ComboboxListProps} props - Props for the Combobox.List component.\n * @returns {JSX.Element} The listbox.\n */\nexport const ComboboxList: React.FC<ComboboxListProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, labelId, multiple } = useCombobox();\n const { listboxRef, listboxId, keepFocus } = engine;\n const listClass = usePrefixedClassNames('combobox-list');\n // A name the caller gave the list wins over the label's.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(listClass, className)}\n {...props}\n ref={listboxRef}\n id={listboxId || undefined}\n role=\"listbox\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n aria-label={\n callerNamed ? props['aria-label'] : labelId ? undefined : 'Suggestions'\n }\n aria-multiselectable={multiple || undefined}\n onMouseDown={event => {\n onMouseDown?.(event);\n keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxList.displayName = 'ComboboxList';\n\n/**\n * One choice in the list, with a check mark while it's `checked`.\n *\n * @function\n * @param {ComboboxItemProps} props - Props for the Combobox.Item component.\n * @returns {JSX.Element} The item.\n */\nexport const ComboboxItem: React.FC<ComboboxItemProps> = ({\n value,\n disabled = false,\n checked = false,\n children,\n className,\n onClick,\n onPointerMove,\n ...props\n}) => {\n const { engine, multiple } = useCombobox();\n const itemRef = useRef<HTMLDivElement>(null);\n const { registerItem } = engine;\n useClientLayoutEffect(\n () =>\n registerItem(itemRef.current as HTMLDivElement, {\n value,\n disabled,\n checked,\n }),\n [registerItem, value, disabled, checked]\n );\n const highlighted = engine.highlighted === value;\n const itemClass = usePrefixedClassNames('dropdown-item', 'combobox-item', {\n 'is-active': highlighted,\n 'is-checked': checked,\n 'is-disabled': disabled,\n });\n const checkClass = usePrefixedClassNames('combobox-check');\n // One value: the highlighted option, as the ARIA Authoring Practices'\n // combobox has it, and no attribute on the rest. Several: each option says\n // whether it's chosen. Never a disabled option.\n const selected = disabled\n ? undefined\n : multiple\n ? checked\n : highlighted || undefined;\n\n return (\n <div\n className={classNames(itemClass, className)}\n {...props}\n ref={itemRef}\n id={engine.itemId(value) || undefined}\n role=\"option\"\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n onClick={event => {\n onClick?.(event);\n if (!disabled && !event.defaultPrevented) engine.pick(value);\n }}\n onPointerMove={event => {\n onPointerMove?.(event);\n if (!disabled && !highlighted) engine.hover(value);\n }}\n >\n {checked && (\n <span className={checkClass} aria-hidden=\"true\">\n <CheckIcon />\n </span>\n )}\n {children}\n </div>\n );\n};\nComboboxItem.displayName = 'ComboboxItem';\n\n/**\n * Items under a heading, a `group` named by it.\n *\n * @function\n * @param {ComboboxGroupProps} props - Props for the Combobox.Group component.\n * @returns {JSX.Element} The group and its heading.\n */\nexport const ComboboxGroup: React.FC<ComboboxGroupProps> = ({\n label,\n children,\n className,\n ...props\n}) => {\n const labelId = useId();\n const groupClass = usePrefixedClassNames('combobox-group');\n const labelClass = usePrefixedClassNames('combobox-group-label');\n // A name the caller gave the group wins over its heading's, as on the list.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(groupClass, className)}\n {...props}\n role=\"group\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n >\n <div className={labelClass} id={labelId}>\n {label}\n </div>\n {children}\n </div>\n );\n};\nComboboxGroup.displayName = 'ComboboxGroup';\n\n/**\n * The message shown in place of the list when nothing matches, announced when typing brings it on screen.\n *\n * @function\n * @param {ComboboxEmptyProps} props - Props for the Combobox.Empty component.\n * @returns {JSX.Element} The message.\n */\nexport const ComboboxEmpty: React.FC<ComboboxEmptyProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, reportEmpty } = useCombobox();\n const emptyRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(\n () => reportEmpty(emptyRef.current as HTMLDivElement),\n [reportEmpty]\n );\n const emptyClass = usePrefixedClassNames('combobox-empty');\n return (\n <div\n className={classNames(emptyClass, className)}\n {...props}\n ref={emptyRef}\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxEmpty.displayName = 'ComboboxEmpty';\n\n/** An entry in `data` as an item: a string is its own label. */\nconst toItem = (entry: string | ComboboxItemData): ComboboxItemData =>\n typeof entry === 'string' ? { value: entry, label: entry } : entry;\n\nconst labelOf = (item: ComboboxItemData): string => item.label ?? item.value;\n\n/** One value or several, as a list: one value is a list of none or one. */\nconst asList = (value: string | string[] | null | undefined): string[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n\n/**\n * The Combobox given `data`. It renders the parts itself, filters the items\n * by label as the user types, and keeps the value, so a pick goes through\n * the same parts, keys and ARIA as one built by hand.\n */\nconst ComboboxFromData = forwardRef<HTMLDivElement, ComboboxDataProps>(\n (props, ref) => {\n const {\n data,\n value,\n defaultValue,\n // Called below through `props`, which knows which value it takes.\n onChange: _onChange,\n multiple = false,\n placeholder,\n name,\n empty,\n itemTemplate,\n onSelect,\n onOpenChange,\n inline = false,\n disabled: disabledProp,\n required = false,\n form,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ariaCloseLabel,\n children,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n // A name given in place of a label is the field's and the list's, not\n // the wrapper's. Only the ones given are passed, since an\n // `aria-labelledby` that's there at all, even undefined, keeps the\n // label's name off the field.\n const named = {\n ...(ariaLabel !== undefined && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy !== undefined && {\n 'aria-labelledby': ariaLabelledBy,\n }),\n };\n if (flattenChildren(children).length > 0) {\n warnOnce(\n 'Combobox:data-children',\n '[bestax-bulma] <Combobox data> renders its own field, menu and ' +\n 'items, so its children are ignored. Give it data or build it ' +\n 'from parts, not both.'\n );\n }\n const items = data.map(toItem);\n const labelFor = (picked: string) => {\n const item = items.find(entry => entry.value === picked);\n return item ? labelOf(item) : picked;\n };\n\n const controlled = value !== undefined;\n const [ownValue, setOwnValue] = useState(() => asList(defaultValue));\n const matchText = useLocaleMatcher();\n const picked = controlled ? asList(value) : ownValue;\n const change = (next: string[]) => {\n if (!controlled) setOwnValue(next);\n if (props.multiple === true) props.onChange?.(next);\n else props.onChange?.(next[0] ?? null);\n };\n\n // What's typed, or `null` while the field shows the value instead. The\n // ref holds it as it is now, since a pick sets it and the list's closing\n // reads it in the same event, before a render.\n const [query, setQueryState] = useState<string | null>(null);\n const queryRef = useRef<string | null>(null);\n const setQuery = (next: string | null) => {\n queryRef.current = next;\n setQueryState(next);\n };\n // Once the list closes or the field is left, the field shows the value\n // again: typed text goes back to the pick, and with one value a field\n // left empty clears it.\n const settle = () => {\n if (!multiple && queryRef.current === '' && picked.length > 0) {\n change([]);\n }\n setQuery(null);\n };\n const typed = (query ?? '').trim();\n const term = typed.toLowerCase();\n const shown = items.filter(item =>\n matchText\n ? matchText(labelOf(item), typed)\n : labelOf(item).toLowerCase().includes(term)\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n const select = (pick: string) => {\n onSelect?.(pick);\n if (multiple) {\n change(\n picked.includes(pick)\n ? picked.filter(v => v !== pick)\n : [...picked, pick]\n );\n } else {\n if (picked[0] !== pick) change([pick]);\n setQuery(null);\n }\n };\n const remove = (pick: string) => {\n change(picked.filter(v => v !== pick));\n inputRef.current?.focus();\n };\n // The picks, for the field's description, since its text is the search.\n const tagsId = useId();\n const ids = tagIds(tagsId, picked);\n\n // Each group where `data` first names it, and the items with none\n // together where the first of them is.\n const sections = new Map<string, ComboboxItemData[]>();\n for (const item of shown) {\n const group = item.group ?? '';\n sections.set(group, [...(sections.get(group) ?? []), item]);\n }\n const renderItem = (item: ComboboxItemData) => (\n <ComboboxItem\n key={item.value}\n value={item.value}\n disabled={disabled || item.disabled}\n checked={picked.includes(item.value)}\n >\n {itemTemplate ? itemTemplate(item) : labelOf(item)}\n </ComboboxItem>\n );\n const list =\n shown.length > 0 ? (\n <ComboboxList {...named}>\n {Array.from(sections, ([group, members]) =>\n group ? (\n <ComboboxGroup key={group} label={group}>\n {members.map(renderItem)}\n </ComboboxGroup>\n ) : (\n members.map(renderItem)\n )\n )}\n </ComboboxList>\n ) : empty ? (\n <ComboboxEmpty>{empty}</ComboboxEmpty>\n ) : null;\n\n return (\n <ComboboxParts\n {...rest}\n ref={ref}\n multiple={multiple}\n inline={inline}\n onSelect={select}\n onSettle={settle}\n onOpenChange={next => {\n if (!next) settle();\n onOpenChange?.(next);\n }}\n below={\n multiple ? (\n <ValueTags\n values={picked}\n ids={ids}\n labelFor={labelFor}\n disabled={disabled}\n ariaCloseLabel={ariaCloseLabel}\n onRemove={remove}\n />\n ) : undefined\n }\n >\n <ComboboxInput\n {...named}\n ref={inputRef}\n id={id}\n disabled={disabled}\n // The browser's check reads the field's text, and only a pick\n // fills it for good, so it's required until there is one.\n required={required && picked.length === 0}\n aria-required={required || undefined}\n form={form}\n aria-describedby={\n multiple && picked.length > 0 ? ids.join(' ') : undefined\n }\n placeholder={placeholder}\n value={\n query ??\n (multiple || picked.length === 0 ? '' : labelFor(picked[0]))\n }\n onChange={event => setQuery(event.target.value)}\n onBlur={settle}\n />\n {inline ? list : <ComboboxMenu>{list}</ComboboxMenu>}\n <HiddenValues\n name={name}\n values={multiple ? picked : [picked[0] ?? '']}\n form={form}\n disabled={disabled}\n />\n </ComboboxParts>\n );\n }\n);\nComboboxFromData.displayName = 'ComboboxFromData';\n\n/**\n * The `Combobox` component is a text field with a list to pick from under it, for a searchable select, a multi-select with tags, grouped items or a server search: given `data` it does the rest, and built from parts it leaves the data to you.\n *\n * Given `data`, it's one element. It renders the field, the menu, the list,\n * the groups and the empty message, filters the items by label as the user\n * types, and keeps the value, which `onChange` reports. With `multiple`, the\n * picks show as tags under the field.\n *\n * Built from parts, the app owns the data: what's in the list, how it's\n * filtered, and the value. A pick calls `onSelect` with the item's `value`,\n * and the Combobox keeps no value and never changes the text in the field,\n * so the app sets both there. Nothing filters the items either, so a\n * server's answer shows as it came. For a free-text field with suggestions,\n * `Autocomplete` is the simpler choice.\n *\n * Either way, focus stays in the field, and the highlighted item is its\n * `aria-activedescendant`. With one value, the highlighted item is the\n * `aria-selected` one, as the ARIA Authoring Practices' combobox does it, and\n * a `checked` item shows a check mark and takes the highlight when the list\n * opens. With `multiple`, `checked` is each item's `aria-selected`. Tab and\n * focus leaving close the menu without picking.\n *\n * When typing leaves the empty message on screen, its text is announced\n * through a polite status region, once, after any loading ends. Result\n * counts aren't announced: a screen reader reads the list's size from the\n * markup, and a count on every keystroke talks over the typing. Show one in\n * a `role=\"status\"` line beside the field when it matters.\n *\n * @function\n * @param {ComboboxProps} props - Props for the Combobox component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the `div.combobox`.\n * @returns {JSX.Element} The field and its list, in a `Field` with the label unless one is around it.\n *\n * @example\n * <Combobox\n * label=\"Country\"\n * data={['Canada', 'France', 'Japan']}\n * placeholder=\"Pick a country\"\n * empty=\"No countries match\"\n * />\n *\n * @example\n * <Combobox label=\"Country\" onSelect={pick}>\n * <Combobox.Input value={query} onChange={e => setQuery(e.target.value)} />\n * <Combobox.Menu>\n * {matches.length > 0 ? (\n * <Combobox.List>\n * {matches.map(c => (\n * <Combobox.Item key={c} value={c} checked={c === value}>\n * {c}\n * </Combobox.Item>\n * ))}\n * </Combobox.List>\n * ) : (\n * <Combobox.Empty>No countries match</Combobox.Empty>\n * )}\n * </Combobox.Menu>\n * </Combobox>\n */\nconst ComboboxRoot = forwardRef<HTMLDivElement, ComboboxProps>((props, ref) =>\n props.data === undefined ? (\n <ComboboxParts {...props} ref={ref} />\n ) : (\n <ComboboxFromData {...props} ref={ref} />\n )\n);\n\n/** Combobox with Input, Menu, List, Item, Group and Empty sub-components. */\nexport const Combobox = withSubComponents(\n ComboboxRoot,\n {\n Input: ComboboxInput,\n Menu: ComboboxMenu,\n List: ComboboxList,\n Item: ComboboxItem,\n Group: ComboboxGroup,\n Empty: ComboboxEmpty,\n },\n 'Combobox'\n);\n\nexport default Combobox;\n"],"names":["noop","standalone","setRefs","_jsxs","_jsx","_Fragment","asList"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Combobox.js","sources":["../../../src/form/Combobox.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { PopupPortal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { flattenChildren } from '../helpers/flattenChildren';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { useLocaleMatcher } from '../helpers/localeFormat';\nimport {\n AnchoredPosition,\n marginGap,\n useAnchoredPosition,\n} from '../helpers/useAnchoredPosition';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport { CheckIcon } from '../helpers/checkIcon';\nimport {\n ComboboxEngine,\n useComboboxEngine,\n} from '../helpers/useComboboxEngine';\nimport type { PopoverPosition } from '../components/Popover';\nimport { Field } from './Field';\nimport { Input, InputProps } from './Input';\nimport { FormFieldProps } from './fieldProps';\nimport {\n rendersOwnField,\n useFieldsetDisabled,\n useInsideControl,\n useInsideField,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { useControlLoading } from './controlLoading';\nimport { HiddenValues, ValueTags, tagIds } from './_selectInternals/ValueTags';\n\nconst validComboboxSizes = ['small', 'medium', 'large'] as const;\n\n// What the status region announces: the `Combobox.Empty` content, as the one\n// item it's handed while that content is on screen because of the user's\n// typing.\nconst typedNoMatches = [{ id: 'empty' }];\nconst nothingToAnnounce: Array<{ id: string }> = [];\n\n/**\n * One item in a Combobox's `data`. A string there is an item whose label is\n * its value.\n */\nexport interface ComboboxItemData {\n /**\n * What `onSelect` and `onChange` hand back, and what `name` posts. Unique\n * within the Combobox.\n */\n value: string;\n /** What the item shows, and what typing matches. The `value` when it's left out. */\n label?: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it.\n */\n disabled?: boolean;\n /**\n * The heading the item goes under. Groups show in the order `data` first\n * names them, and the items with no group show together where the first of\n * them is.\n */\n group?: string;\n}\n\n/** What a Combobox takes whether it's given `data` or built from parts. */\ninterface ComboboxBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'onChange' | 'onSelect' | 'defaultValue'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /**\n * The field's label, which names `Combobox.Input` through `htmlFor`, and\n * the list through `aria-labelledby`. Dropped inside an outer `Field`,\n * whose label names both instead when it points at the field. When\n * `Combobox.Input` has an `id` of its own, server markup names the field\n * through `aria-labelledby` until the page hydrates and the label's `for`\n * catches up.\n */\n label?: React.ReactNode;\n /**\n * Props for the label element. An explicit `htmlFor` takes over the\n * association: give `Combobox.Input` the same `id`, and the list is still\n * named after the label.\n */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /**\n * Controlled open state. When set, opening and closing only report\n * through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the open state asked for: `true` from typing, a click in\n * the field or Down Arrow, and `false` from Escape, Tab, a pick with one\n * value, focus leaving or a press outside. Fires in controlled and\n * uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called with an item's `value` when it's picked with Enter or a click.\n * A disabled item is never picked. With `data`, `onChange` reports the\n * value that follows. Built from parts, the Combobox keeps no value and\n * doesn't change the text in the field: update yours here.\n */\n onSelect?: (value: string) => void;\n /**\n * Highlights the first enabled item whenever the list opens or its\n * items change, so Enter picks the top match. It only highlights:\n * leaving the field still picks nothing, and so does Tab.\n * @defaultValue false\n */\n keepFirst?: boolean;\n /**\n * The list is always on screen, in the flow under the field, as in a\n * Popover or a page panel. There's no menu, so nothing closes it, and\n * Escape goes to whatever is around it.\n * @defaultValue false\n */\n inline?: boolean;\n /**\n * Where the menu opens against the field: below (`bottom-*`) or above\n * (`top-*`), lined up with its left or right edge. `auto` picks the one\n * that keeps the list in the viewport, preferring below. The same union\n * Popover takes. Left out, it opens below and lines up with the field's\n * start edge, which is its right edge on a right-to-left page, so a menu\n * wider than the field doesn't hang off the screen. A corner you pass\n * stays physical, so `bottom-left` lines up the left edges on either page.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Renders the menu through `Portal`, into the `portalContainer` a\n * `ConfigProvider` sets, else the `Modal`, `Dialog` or `Command.Dialog`\n * it's in, else `document.body`, fixed to the viewport at the field, so a\n * container that clips its overflow can't cut it off. It then shows from\n * the commit after hydration, never in server markup. Theming variables set\n * on an ancestor reach it only when the portal's container is inside that\n * ancestor, as with Popover.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /** Sizes the field and the items together. */\n size?: 'small' | 'medium' | 'large';\n}\n\n/** What a Combobox given `data` takes, with one value or several. */\ninterface ComboboxDataBaseProps extends ComboboxBaseProps {\n /** The field's placeholder, with `data`. */\n placeholder?: string;\n /**\n * A form field name, with `data`. A hidden input posts the value, empty\n * while there's none, and with `multiple` a hidden input posts each value.\n */\n name?: string;\n /**\n * What the menu shows in place of the list, with `data`, when nothing\n * matches the typing, such as \"No countries match\". It's announced the way\n * `Combobox.Empty` is. Without it, the menu closes while nothing matches.\n */\n empty?: React.ReactNode;\n /**\n * Renders an item's content, with `data`, in place of its label. It's\n * handed the item from `data`, a string there arriving as\n * `{ value, label }`.\n */\n itemTemplate?: (item: ComboboxItemData) => React.ReactNode;\n /**\n * The field can't be used, with `data`: it can't be focused or typed in,\n * its items can't be picked, its tags lose their buttons, and its hidden\n * inputs don't post, the way a disabled field's value doesn't.\n */\n disabled?: boolean;\n /**\n * A value is needed, with `data`. The field is `required` while nothing is\n * picked, so the browser's own check stops the form the way it does for\n * Autocomplete's field, and it's `aria-required` the whole time. The check\n * reads the field's text, which Enter, the list closing or leaving the\n * field puts back to the pick.\n */\n required?: boolean;\n /**\n * The id of the form the value posts with, with `data`, for a field\n * outside it. It goes on the hidden inputs, and on the field so that form\n * checks `required` too.\n */\n form?: string;\n /**\n * The field's `id`, with `data`, which the label then points at, and so\n * can a label of your own. Built from parts, it lands on `div.combobox`, so\n * give `Combobox.Input` the `id` instead.\n */\n id?: string;\n /**\n * Names the field and the list, with `data`, in place of a `label`. Built\n * from parts, it lands on `div.combobox`, so put it on `Combobox.Input`.\n */\n 'aria-label'?: string;\n /**\n * The ids of what names the field and the list, with `data`, in place of\n * a `label`. Built from parts, it lands on `div.combobox`, so put it on\n * `Combobox.Input`.\n */\n 'aria-labelledby'?: string;\n /** With `data`, the Combobox renders its own parts. */\n children?: never;\n}\n\n/** Props for a Combobox given `data`, with one value. */\nexport interface ComboboxSingleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders the field, the menu, the list,\n * the groups and the empty message itself. A string is an item whose label\n * is its value, and an object is `{ value, label?, disabled?, group? }`.\n * Typing filters the items by label, ignoring case, and inside a\n * `LocaleProvider` with a `locale`, ignoring accents too where that\n * language does, so \"cafe\" finds \"Café\". The Combobox keeps the value. Leave it out to build the Combobox from parts.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`. With `data`, the value is an array, and the picks show\n * as tags under the field, inside its Field, each with a button that takes\n * it off. The field's description lists them, since its text is the\n * search.\n * @defaultValue false\n */\n multiple?: false;\n /**\n * The value, controlled, with `data`: the picked item's `value`, or `null`\n * for none, and with `multiple` an array of them. With one value, the\n * field shows the picked item's label while you aren't typing in it, and\n * the list closing or the field being left puts it back over any typing.\n * A field emptied and left like that clears the value.\n */\n value?: string | null;\n /** The value to start with when uncontrolled, with `data`. */\n defaultValue?: string | null;\n /**\n * Called with the new value, with `data`, when a pick, a tag's button or\n * a field left empty changes it: an item's `value` or `null`, or with\n * `multiple` the array.\n */\n onChange?: (value: string | null) => void;\n /** With one value there are no tags to name. */\n ariaCloseLabel?: never;\n}\n\n/** Props for a Combobox given `data`, with several values. */\nexport interface ComboboxMultipleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders itself. A string is an item whose\n * label is its value, and an object is `{ value, label?, disabled?, group? }`.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked: the value is an array, and the picks show\n * as tags under the field, each with a button that takes it off. The\n * field's description lists them.\n */\n multiple: true;\n /** The values, controlled: the picked items' `value`s. */\n value?: string[];\n /** The values to start with when uncontrolled. */\n defaultValue?: string[];\n /** Called with the new array when a pick or a tag's button changes it. */\n onChange?: (value: string[]) => void;\n /**\n * Names each tag's button, in place of \"Remove\" and the item's label, as\n * Taginput's does. The button is then described by its tag's label, so it\n * still says which tag it takes off.\n */\n ariaCloseLabel?: string;\n}\n\n/** Props for a Combobox given `data`. */\ntype ComboboxDataProps = ComboboxSingleDataProps | ComboboxMultipleDataProps;\n\n/** Props for a Combobox built from parts. */\nexport interface ComboboxPartsProps extends ComboboxBaseProps {\n /**\n * The parts, in order: `Combobox.Input`, then `Combobox.Menu` with\n * `Combobox.List` and `Combobox.Empty` in it. With `inline`, the\n * `Combobox.List` and `Combobox.Empty` go straight in. Render\n * `Combobox.List` while there are items and `Combobox.Empty` while\n * there aren't: the empty message sits beside the list, not in it. With\n * `data` there are none to give: children given with it are ignored, with\n * a warning in development.\n */\n children?: React.ReactNode;\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`.\n * @defaultValue false\n */\n multiple?: boolean;\n /** Built from parts, there's no `data`. */\n data?: never;\n /** Built from parts, the app keeps the value. */\n value?: never;\n /** Built from parts, the app keeps the value. */\n defaultValue?: never;\n /** Built from parts, `onSelect` reports a pick. */\n onChange?: never;\n /** Built from parts, `Combobox.Input` takes the placeholder. */\n placeholder?: never;\n /** Built from parts, the app posts the value. */\n name?: never;\n /** Built from parts, `Combobox.Empty` is the empty message. */\n empty?: never;\n /** Built from parts, `Combobox.Item` renders its own content. */\n itemTemplate?: never;\n /** Built from parts, `Combobox.Input` takes `disabled`. */\n disabled?: never;\n /** Built from parts, `Combobox.Input` takes `required`. */\n required?: never;\n /** Built from parts, the app posts the value. */\n form?: never;\n}\n\n/**\n * Props for the Combobox component: given `data`, it renders itself and\n * keeps the value, and without it, it's built from parts. The helper props,\n * the other attributes and the `ref` land on the `div.combobox` around the\n * field and the list. It renders the `Field` and the label itself, unless an\n * outer `Field` already does.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the `div.combobox` around the field and the list.\n */\nexport type ComboboxProps =\n ComboboxSingleDataProps | ComboboxMultipleDataProps | ComboboxPartsProps;\n\n/**\n * Props for Combobox.Input, the text field. It renders `Input`, so its icons,\n * `isLoading` and `color` work as they do there. The Field props go on the\n * Combobox, and the size comes from it. The field is `autoComplete=\"off\"`,\n * so the browser's own suggestions don't open over the list, and that isn't\n * yours to set.\n */\nexport type ComboboxInputProps = Omit<\n InputProps,\n // By name, since the docs read only names out of an Omit, and\n // `__typetests__/combobox.tsx` fails if one goes missing. The Field props:\n | 'label'\n | 'labelSize'\n | 'labelProps'\n | 'horizontal'\n | 'message'\n | 'messageColor'\n | 'fieldClassName'\n // And what the Combobox sets on the field itself:\n | 'size'\n | 'role'\n | 'autoComplete'\n>;\n\n/** Props for Combobox.Menu, the floating panel under the field. */\nexport interface ComboboxMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * What the panel shows: `Combobox.List` while there are items, and\n * `Combobox.Empty` while there aren't. Children that are all `null`,\n * `false` or `''`, or empty Fragments, keep the panel shut, so write the\n * conditional here. A component that renders nothing, or a\n * `Combobox.List` with no items in it, still counts, and shows an\n * empty panel.\n */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.List, the list. Its `id` is the one the field's\n * `aria-controls` names, so it isn't yours to set.\n */\nexport interface ComboboxListProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'id'\n> {\n /** `Combobox.Item`s and `Combobox.Group`s, in the order they're shown. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.Item, one choice in the list. Its `id` follows from\n * its `value`, since the field's `aria-activedescendant` names it, so it\n * isn't yours to set.\n */\nexport interface ComboboxItemProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'onSelect' | 'id'\n> {\n /** What `onSelect` hands back. Unique within the Combobox. */\n value: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it, and it's never `aria-selected`.\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * It's the value, or one of them. It shows a check mark, the list opens\n * with the highlight on it, and with `multiple` it's the `aria-selected`.\n * @defaultValue false\n */\n checked?: boolean;\n /** What the item shows: text, or text with an avatar, a tag or a hint. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Group, items under a heading. */\nexport interface ComboboxGroupProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role'\n> {\n /**\n * The heading, which also names the group for assistive tech, unless you\n * give the group an `aria-label` or `aria-labelledby` of its own.\n */\n label: React.ReactNode;\n /** The group's `Combobox.Item`s. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Empty, the message shown in place of the list. */\nexport interface ComboboxEmptyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The message, such as \"No countries match\". Its text is announced when\n * typing brings it on screen and isn't read again while it stays, so a\n * message that names the query is heard for the first query only.\n */\n children?: React.ReactNode;\n}\n\n/** What the Combobox hands its parts. */\ninterface ComboboxContextValue {\n engine: ComboboxEngine;\n /** The id the field takes when it's given none. */\n inputId: string | undefined;\n /** Tells the Combobox the id the field was given, so the label follows it. */\n reportInputId: (id: string | undefined) => void;\n /** The id of the label that names the field, which names the list too. */\n labelId: string | undefined;\n /**\n * The id of the label the Combobox renders itself, when it names the field.\n * The field points at it while its own `id` hasn't reached the label yet.\n */\n ownLabelId: string | undefined;\n /** Tells the Combobox the field's `isLoading`, which holds the empty message's announcement. */\n reportLoading: (loading: boolean) => void;\n /** Records the empty message while it's on screen. Returns the function that forgets it. */\n reportEmpty: (element: HTMLElement) => () => void;\n /** A change to the field's value, which is the user typing. */\n onFieldChange: (value: string) => void;\n /**\n * Records the menu's panel while it's on screen, so it's placed and\n * counts as inside. Returns the function that forgets it.\n */\n reportPanel: (element: HTMLElement) => () => void;\n /** Where the panel goes against the field. */\n placement: AnchoredPosition;\n /**\n * No `position` was passed, so the panel lines up with the field's inline\n * start, which the stylesheet moves to its right edge right to left.\n */\n startAligned: boolean;\n size?: ComboboxProps['size'];\n multiple: boolean;\n inline: boolean;\n appendToBody: boolean;\n}\n\nconst noop = () => {};\nconst registerNothing = () => noop;\n\n// What a part rendered outside a Combobox reads: closed, with nothing to\n// report to, so it renders its markup and does nothing.\nconst standalone: ComboboxContextValue = {\n engine: {\n open: false,\n expanded: false,\n highlighted: null,\n typed: false,\n listboxId: '',\n itemId: () => '',\n rootRef: { current: null },\n inputRef: { current: null },\n listboxRef: { current: null },\n registerPopup: registerNothing,\n registerItem: registerNothing,\n onKeyDown: noop,\n onChange: noop,\n onClick: noop,\n onBlur: noop,\n hover: noop,\n pick: noop,\n keepFocus: noop,\n markInside: noop,\n },\n inputId: undefined,\n reportInputId: noop,\n labelId: undefined,\n ownLabelId: undefined,\n reportLoading: noop,\n reportEmpty: registerNothing,\n onFieldChange: noop,\n reportPanel: registerNothing,\n placement: { position: 'bottom-left' },\n startAligned: true,\n multiple: false,\n inline: false,\n appendToBody: false,\n};\n\nconst ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nconst useCombobox = () => useContext(ComboboxContext) ?? standalone;\n\n/** Hands a node to a forwarded ref and to one of the component's own. */\nfunction setRefs<T>(\n node: T | null,\n own: React.MutableRefObject<T | null>,\n forwarded: React.ForwardedRef<T>\n) {\n own.current = node;\n if (typeof forwarded === 'function') forwarded(node);\n else if (forwarded) forwarded.current = node;\n}\n\n/**\n * The Combobox built from parts: the field, the menu, the list and the\n * keys, with the data, the filtering and the value left to the app.\n */\n/** What the parts root takes from the Combobox given `data`, beyond the parts' props. */\ninterface ComboboxPartsRootProps extends ComboboxPartsProps {\n /**\n * Shown under the Combobox, inside its Field and ahead of the message: the\n * tags of several values. While it's given, the two share a wrapper, so\n * they stay together in a horizontal Field's body.\n */\n below?: React.ReactNode;\n /**\n * Called when Enter goes on to the form with nothing to pick, so the\n * Combobox given `data` can put the field's text back first, `inline`\n * included, where nothing closes.\n */\n onSettle?: () => void;\n}\n\nconst ComboboxParts = forwardRef<HTMLDivElement, ComboboxPartsRootProps>(\n (\n {\n children,\n below,\n onSettle,\n open,\n defaultOpen = false,\n onOpenChange,\n onSelect,\n keepFirst = false,\n multiple = false,\n inline = false,\n position,\n appendToBody = false,\n size,\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Combobox', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n // The field's own `id`, when `Combobox.Input` was given one, which the\n // label then points at.\n const [givenInputId, setGivenInputId] = useState<string | undefined>();\n const {\n controlId,\n fieldLabelProps,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id: givenInputId,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: true,\n });\n const engine = useComboboxEngine({\n open,\n defaultOpen,\n onOpenChange,\n onSelect,\n onSettle,\n keepFirst,\n multiple,\n inline,\n // A portaled panel has no server markup to point at.\n deferred: appendToBody && !inline,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const validSize = (validComboboxSizes as readonly string[]).includes(\n size as string\n )\n ? size\n : undefined;\n const rootClass = usePrefixedClassNames('combobox', {\n [`is-${validSize}`]: !!validSize,\n 'is-inline': inline,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // A polite status region, in the page from the start so it's there\n // before anything is written into it, announces `Combobox.Empty` when\n // the user's typing leaves it on screen: once each time that happens,\n // not again on each keystroke while it stays. An empty field isn't a\n // search, so it stays quiet then. While the field's `isLoading`, or a\n // loading Control around the Combobox, says results are on their way, it\n // waits, and it's said once loading ends with the message still there.\n const [inputLoading, setInputLoading] = useState(false);\n const controlLoading = useControlLoading();\n const [hasText, setHasText] = useState(false);\n const emptyRef = useRef<HTMLElement | null>(null);\n const [emptyShown, setEmptyShown] = useState(false);\n const announced =\n engine.typed && hasText && emptyShown && !inputLoading && !controlLoading\n ? typedNoMatches\n : nothingToAnnounce;\n // The region reads the text on screen, whatever the message renders.\n const describeEmpty = useCallback(() => {\n const node = emptyRef.current;\n /* istanbul ignore if: it's only announced while it's on screen */\n if (!node) return null;\n return spokenText(node);\n }, []);\n\n const reportEmpty = useCallback((element: HTMLElement) => {\n emptyRef.current = element;\n setEmptyShown(true);\n return () => {\n emptyRef.current = null;\n setEmptyShown(false);\n };\n }, []);\n // The menu is placed from here rather than from the part, since this\n // is where the field's element is known by the time the panel mounts.\n const panelRef = useRef<HTMLElement | null>(null);\n const [panelShown, setPanelShown] = useState(false);\n const placement = useAnchoredPosition(engine.rootRef, panelRef, {\n active: panelShown,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-combobox-menu-offset` as a margin, so\n // the coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n matchWidth: true,\n // The list filters as the user types, so the menu's height changes.\n followContent: true,\n });\n const { registerPopup } = engine;\n const reportPanel = useCallback(\n (element: HTMLElement) => {\n const forget = registerPopup(element);\n panelRef.current = element;\n setPanelShown(true);\n return () => {\n forget();\n panelRef.current = null;\n setPanelShown(false);\n };\n },\n [registerPopup]\n );\n\n const onFieldChange = (value: string) => {\n setHasText(value !== '');\n engine.onChange();\n };\n\n // A new value each render: the engine's state and handlers are, and the\n // parts read the highlight and the open state from it.\n const context: ComboboxContextValue = {\n engine,\n inputId: controlId,\n reportInputId: setGivenInputId,\n labelId: listLabelId,\n ownLabelId: label && ownField ? listLabelId : undefined,\n reportLoading: setInputLoading,\n reportEmpty,\n onFieldChange,\n reportPanel,\n placement,\n startAligned: position === undefined,\n size: validSize,\n multiple,\n inline,\n appendToBody,\n };\n\n const { rootRef } = engine;\n const rootRefs = useCallback(\n (node: HTMLDivElement | null) => setRefs(node, rootRef, ref),\n [rootRef, ref]\n );\n\n const comboboxElement = (\n // The ref after the spread, so the element stays the Combobox's.\n <div\n className={classNames(rootClass, bulmaHelperClasses, className)}\n {...rest}\n ref={rootRefs}\n >\n <ComboboxContext.Provider value={context}>\n {children}\n </ComboboxContext.Provider>\n <StatusRegion items={announced} describe={describeEmpty} />\n </div>\n );\n const fieldElement =\n below === undefined ? (\n comboboxElement\n ) : (\n <div>\n {comboboxElement}\n {/* Part of the Combobox, as the menu is: a press here keeps focus\n in the field and doesn't count as outside, so the list and the\n search stay put. */}\n <div\n onPointerDownCapture={engine.markInside}\n onMouseDown={engine.keepFocus}\n >\n {below}\n </div>\n </div>\n );\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {fieldElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fieldElement}\n {messageEl}\n </>\n );\n }\n);\nComboboxParts.displayName = 'ComboboxParts';\n\n/**\n * The text field, with the combobox role and the keys, rendered as an `Input`.\n *\n * @function\n * @param {ComboboxInputProps} props - Props for the Combobox.Input component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the `<input>`.\n * @returns {JSX.Element} The field in its Control.\n */\nexport const ComboboxInput = forwardRef<HTMLInputElement, ComboboxInputProps>(\n (\n {\n id,\n isLoading,\n controlSize,\n onKeyDown,\n onChange,\n onClick,\n onBlur,\n 'aria-autocomplete': ariaAutocomplete,\n ...props\n },\n ref\n ) => {\n const context = useCombobox();\n const { engine, reportInputId, reportLoading } = context;\n // Inside a caller's Control the field renders none of its own, so the\n // Combobox's size isn't handed to one there.\n const insideControl = useInsideControl();\n useClientLayoutEffect(() => {\n reportInputId(id);\n return () => reportInputId(undefined);\n }, [reportInputId, id]);\n useClientLayoutEffect(() => {\n reportLoading(!!isLoading);\n return () => reportLoading(false);\n }, [reportLoading, isLoading]);\n const { inputRef } = engine;\n const inputRefs = useCallback(\n (node: HTMLInputElement | null) => setRefs(node, inputRef, ref),\n [inputRef, ref]\n );\n const { expanded, highlighted } = engine;\n // An `id` of the field's own reaches the label from a layout effect, so\n // in server markup, and the first render, the label's `for` still names\n // the generated id. Until then the field points at the label itself,\n // unless the caller named it.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n const labelledBy = callerNamed\n ? props['aria-labelledby']\n : id !== undefined && id !== context.inputId\n ? context.ownLabelId\n : undefined;\n\n return (\n // The attributes the Combobox owns after the caller's, so a stray\n // `aria-expanded` never wins.\n <Input\n {...props}\n ref={inputRefs}\n id={id ?? context.inputId}\n aria-labelledby={labelledBy}\n isLoading={isLoading}\n size={context.size}\n controlSize={controlSize ?? (insideControl ? undefined : context.size)}\n role=\"combobox\"\n aria-autocomplete={ariaAutocomplete ?? 'list'}\n aria-haspopup=\"listbox\"\n aria-expanded={expanded}\n aria-controls={expanded ? engine.listboxId : undefined}\n aria-activedescendant={\n expanded && highlighted !== null\n ? engine.itemId(highlighted)\n : undefined\n }\n autoComplete=\"off\"\n onKeyDown={event => {\n onKeyDown?.(event);\n engine.onKeyDown(event);\n }}\n onChange={event => {\n onChange?.(event);\n context.onFieldChange(event.target.value);\n }}\n onClick={event => {\n onClick?.(event);\n if (!event.defaultPrevented) engine.onClick();\n }}\n onBlur={event => {\n onBlur?.(event);\n engine.onBlur(event);\n }}\n />\n );\n }\n);\nComboboxInput.displayName = 'ComboboxInput';\n\n/**\n * The floating panel under the field, on screen while the list is open and its children aren't all empty.\n *\n * @function\n * @param {ComboboxMenuProps} props - Props for the Combobox.Menu component.\n * @returns {JSX.Element | null} The panel, or nothing while the list is closed or its children are all empty.\n */\nexport const ComboboxMenu: React.FC<ComboboxMenuProps> = ({\n children,\n className,\n style,\n onMouseDown,\n onPointerDownCapture,\n ...props\n}) => {\n const {\n engine,\n inline,\n appendToBody,\n placement,\n startAligned,\n reportPanel,\n size,\n } = useCombobox();\n // Children that are all `null`, `false` or `''` leave no panel, whatever\n // `open` says. This reads the elements it's handed, not what they render.\n const hasContent = flattenChildren(children).some(child => child !== '');\n const shown = engine.open && !inline && hasContent;\n // A portaled panel has no server markup, so it only exists from the\n // commit after hydration. Everything that measures it waits for that.\n const hydrated = useIsHydrated();\n const mounted = shown && (hydrated || !appendToBody);\n const panelRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(() => {\n const panel = panelRef.current;\n return mounted && panel ? reportPanel(panel) : undefined;\n }, [mounted, reportPanel]);\n\n const menuClass = usePrefixedClassNames('dropdown-menu', 'combobox-menu', {\n [`is-${placement.position}`]: true,\n // The default lines up with the field's inline start, so the stylesheet\n // moves it to the right edge on a right-to-left page.\n 'is-start-aligned': startAligned,\n 'is-portal': appendToBody,\n [`is-${size}`]: !!size,\n });\n const contentClass = usePrefixedClassNames('dropdown-content');\n\n // Inline, the list is in the flow already.\n if (inline) return <>{children}</>;\n if (!shown) return null;\n\n return (\n <PopupPortal disabled={!appendToBody}>\n <div\n {...props}\n ref={panelRef}\n className={classNames(menuClass, className)}\n style={\n appendToBody\n ? {\n ...style,\n position: 'fixed',\n top: placement.top,\n left: placement.left,\n minWidth: placement.minWidth,\n }\n : style\n }\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n onPointerDownCapture={event => {\n onPointerDownCapture?.(event);\n engine.markInside(event);\n }}\n >\n <div className={contentClass}>{children}</div>\n </div>\n </PopupPortal>\n );\n};\nComboboxMenu.displayName = 'ComboboxMenu';\n\n/**\n * The list of items, a `listbox` named by the label that names the field.\n *\n * @function\n * @param {ComboboxListProps} props - Props for the Combobox.List component.\n * @returns {JSX.Element} The listbox.\n */\nexport const ComboboxList: React.FC<ComboboxListProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, labelId, multiple } = useCombobox();\n const { listboxRef, listboxId, keepFocus } = engine;\n const listClass = usePrefixedClassNames('combobox-list');\n // A name the caller gave the list wins over the label's.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(listClass, className)}\n {...props}\n ref={listboxRef}\n id={listboxId || undefined}\n role=\"listbox\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n aria-label={\n callerNamed ? props['aria-label'] : labelId ? undefined : 'Suggestions'\n }\n aria-multiselectable={multiple || undefined}\n onMouseDown={event => {\n onMouseDown?.(event);\n keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxList.displayName = 'ComboboxList';\n\n/**\n * One choice in the list, with a check mark while it's `checked`.\n *\n * @function\n * @param {ComboboxItemProps} props - Props for the Combobox.Item component.\n * @returns {JSX.Element} The item.\n */\nexport const ComboboxItem: React.FC<ComboboxItemProps> = ({\n value,\n disabled = false,\n checked = false,\n children,\n className,\n onClick,\n onPointerMove,\n ...props\n}) => {\n const { engine, multiple } = useCombobox();\n const itemRef = useRef<HTMLDivElement>(null);\n const { registerItem } = engine;\n useClientLayoutEffect(\n () =>\n registerItem(itemRef.current as HTMLDivElement, {\n value,\n disabled,\n checked,\n }),\n [registerItem, value, disabled, checked]\n );\n const highlighted = engine.highlighted === value;\n const itemClass = usePrefixedClassNames('dropdown-item', 'combobox-item', {\n 'is-active': highlighted,\n 'is-checked': checked,\n 'is-disabled': disabled,\n });\n const checkClass = usePrefixedClassNames('combobox-check');\n // One value: the highlighted option, as the ARIA Authoring Practices'\n // combobox has it, and no attribute on the rest. Several: each option says\n // whether it's chosen. Never a disabled option.\n const selected = disabled\n ? undefined\n : multiple\n ? checked\n : highlighted || undefined;\n\n return (\n <div\n className={classNames(itemClass, className)}\n {...props}\n ref={itemRef}\n id={engine.itemId(value) || undefined}\n role=\"option\"\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n onClick={event => {\n onClick?.(event);\n if (!disabled && !event.defaultPrevented) engine.pick(value);\n }}\n onPointerMove={event => {\n onPointerMove?.(event);\n if (!disabled && !highlighted) engine.hover(value);\n }}\n >\n {checked && (\n <span className={checkClass} aria-hidden=\"true\">\n <CheckIcon />\n </span>\n )}\n {children}\n </div>\n );\n};\nComboboxItem.displayName = 'ComboboxItem';\n\n/**\n * Items under a heading, a `group` named by it.\n *\n * @function\n * @param {ComboboxGroupProps} props - Props for the Combobox.Group component.\n * @returns {JSX.Element} The group and its heading.\n */\nexport const ComboboxGroup: React.FC<ComboboxGroupProps> = ({\n label,\n children,\n className,\n ...props\n}) => {\n const labelId = useId();\n const groupClass = usePrefixedClassNames('combobox-group');\n const labelClass = usePrefixedClassNames('combobox-group-label');\n // A name the caller gave the group wins over its heading's, as on the list.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(groupClass, className)}\n {...props}\n role=\"group\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n >\n <div className={labelClass} id={labelId}>\n {label}\n </div>\n {children}\n </div>\n );\n};\nComboboxGroup.displayName = 'ComboboxGroup';\n\n/**\n * The message shown in place of the list when nothing matches, announced when typing brings it on screen.\n *\n * @function\n * @param {ComboboxEmptyProps} props - Props for the Combobox.Empty component.\n * @returns {JSX.Element} The message.\n */\nexport const ComboboxEmpty: React.FC<ComboboxEmptyProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, reportEmpty } = useCombobox();\n const emptyRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(\n () => reportEmpty(emptyRef.current as HTMLDivElement),\n [reportEmpty]\n );\n const emptyClass = usePrefixedClassNames('combobox-empty');\n return (\n <div\n className={classNames(emptyClass, className)}\n {...props}\n ref={emptyRef}\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxEmpty.displayName = 'ComboboxEmpty';\n\n/** An entry in `data` as an item: a string is its own label. */\nconst toItem = (entry: string | ComboboxItemData): ComboboxItemData =>\n typeof entry === 'string' ? { value: entry, label: entry } : entry;\n\nconst labelOf = (item: ComboboxItemData): string => item.label ?? item.value;\n\n/** One value or several, as a list: one value is a list of none or one. */\nconst asList = (value: string | string[] | null | undefined): string[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n\n/**\n * The Combobox given `data`. It renders the parts itself, filters the items\n * by label as the user types, and keeps the value, so a pick goes through\n * the same parts, keys and ARIA as one built by hand.\n */\nconst ComboboxFromData = forwardRef<HTMLDivElement, ComboboxDataProps>(\n (props, ref) => {\n const {\n data,\n value,\n defaultValue,\n // Called below through `props`, which knows which value it takes.\n onChange: _onChange,\n multiple = false,\n placeholder,\n name,\n empty,\n itemTemplate,\n onSelect,\n onOpenChange,\n inline = false,\n disabled: disabledProp,\n required = false,\n form,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ariaCloseLabel,\n children,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n // A name given in place of a label is the field's and the list's, not\n // the wrapper's. Only the ones given are passed, since an\n // `aria-labelledby` that's there at all, even undefined, keeps the\n // label's name off the field.\n const named = {\n ...(ariaLabel !== undefined && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy !== undefined && {\n 'aria-labelledby': ariaLabelledBy,\n }),\n };\n if (flattenChildren(children).length > 0) {\n warnOnce(\n 'Combobox:data-children',\n '[bestax-bulma] <Combobox data> renders its own field, menu and ' +\n 'items, so its children are ignored. Give it data or build it ' +\n 'from parts, not both.'\n );\n }\n const items = data.map(toItem);\n const labelFor = (picked: string) => {\n const item = items.find(entry => entry.value === picked);\n return item ? labelOf(item) : picked;\n };\n\n const controlled = value !== undefined;\n const [ownValue, setOwnValue] = useState(() => asList(defaultValue));\n const matchText = useLocaleMatcher();\n const picked = controlled ? asList(value) : ownValue;\n const change = (next: string[]) => {\n if (!controlled) setOwnValue(next);\n if (props.multiple === true) props.onChange?.(next);\n else props.onChange?.(next[0] ?? null);\n };\n\n // What's typed, or `null` while the field shows the value instead. The\n // ref holds it as it is now, since a pick sets it and the list's closing\n // reads it in the same event, before a render.\n const [query, setQueryState] = useState<string | null>(null);\n const queryRef = useRef<string | null>(null);\n const setQuery = (next: string | null) => {\n queryRef.current = next;\n setQueryState(next);\n };\n // Once the list closes or the field is left, the field shows the value\n // again: typed text goes back to the pick, and with one value a field\n // left empty clears it.\n const settle = () => {\n if (!multiple && queryRef.current === '' && picked.length > 0) {\n change([]);\n }\n setQuery(null);\n };\n const typed = (query ?? '').trim();\n const term = typed.toLowerCase();\n const shown = items.filter(item =>\n matchText\n ? matchText(labelOf(item), typed)\n : labelOf(item).toLowerCase().includes(term)\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n const select = (pick: string) => {\n onSelect?.(pick);\n if (multiple) {\n change(\n picked.includes(pick)\n ? picked.filter(v => v !== pick)\n : [...picked, pick]\n );\n } else {\n if (picked[0] !== pick) change([pick]);\n setQuery(null);\n }\n };\n const remove = (pick: string) => {\n change(picked.filter(v => v !== pick));\n inputRef.current?.focus();\n };\n // The picks, for the field's description, since its text is the search.\n const tagsId = useId();\n const ids = tagIds(tagsId, picked);\n\n // Each group where `data` first names it, and the items with none\n // together where the first of them is.\n const sections = new Map<string, ComboboxItemData[]>();\n for (const item of shown) {\n const group = item.group ?? '';\n sections.set(group, [...(sections.get(group) ?? []), item]);\n }\n const renderItem = (item: ComboboxItemData) => (\n <ComboboxItem\n key={item.value}\n value={item.value}\n disabled={disabled || item.disabled}\n checked={picked.includes(item.value)}\n >\n {itemTemplate ? itemTemplate(item) : labelOf(item)}\n </ComboboxItem>\n );\n const list =\n shown.length > 0 ? (\n <ComboboxList {...named}>\n {Array.from(sections, ([group, members]) =>\n group ? (\n <ComboboxGroup key={group} label={group}>\n {members.map(renderItem)}\n </ComboboxGroup>\n ) : (\n members.map(renderItem)\n )\n )}\n </ComboboxList>\n ) : empty ? (\n <ComboboxEmpty>{empty}</ComboboxEmpty>\n ) : null;\n\n return (\n <ComboboxParts\n {...rest}\n ref={ref}\n multiple={multiple}\n inline={inline}\n onSelect={select}\n onSettle={settle}\n onOpenChange={next => {\n if (!next) settle();\n onOpenChange?.(next);\n }}\n below={\n multiple ? (\n <ValueTags\n values={picked}\n ids={ids}\n labelFor={labelFor}\n disabled={disabled}\n ariaCloseLabel={ariaCloseLabel}\n onRemove={remove}\n />\n ) : undefined\n }\n >\n <ComboboxInput\n {...named}\n ref={inputRef}\n id={id}\n disabled={disabled}\n // The browser's check reads the field's text, and only a pick\n // fills it for good, so it's required until there is one.\n required={required && picked.length === 0}\n aria-required={required || undefined}\n form={form}\n aria-describedby={\n multiple && picked.length > 0 ? ids.join(' ') : undefined\n }\n placeholder={placeholder}\n value={\n query ??\n (multiple || picked.length === 0 ? '' : labelFor(picked[0]))\n }\n onChange={event => setQuery(event.target.value)}\n onBlur={settle}\n />\n {inline ? list : <ComboboxMenu>{list}</ComboboxMenu>}\n <HiddenValues\n name={name}\n values={multiple ? picked : [picked[0] ?? '']}\n form={form}\n disabled={disabled}\n />\n </ComboboxParts>\n );\n }\n);\nComboboxFromData.displayName = 'ComboboxFromData';\n\n/**\n * The `Combobox` component is a text field with a list to pick from under it, for a searchable select, a multi-select with tags, grouped items or a server search: given `data` it does the rest, and built from parts it leaves the data to you.\n *\n * Given `data`, it's one element. It renders the field, the menu, the list,\n * the groups and the empty message, filters the items by label as the user\n * types, and keeps the value, which `onChange` reports. With `multiple`, the\n * picks show as tags under the field.\n *\n * Built from parts, the app owns the data: what's in the list, how it's\n * filtered, and the value. A pick calls `onSelect` with the item's `value`,\n * and the Combobox keeps no value and never changes the text in the field,\n * so the app sets both there. Nothing filters the items either, so a\n * server's answer shows as it came. For a free-text field with suggestions,\n * `Autocomplete` is the simpler choice.\n *\n * Either way, focus stays in the field, and the highlighted item is its\n * `aria-activedescendant`. With one value, the highlighted item is the\n * `aria-selected` one, as the ARIA Authoring Practices' combobox does it, and\n * a `checked` item shows a check mark and takes the highlight when the list\n * opens. With `multiple`, `checked` is each item's `aria-selected`. Tab and\n * focus leaving close the menu without picking.\n *\n * When typing leaves the empty message on screen, its text is announced\n * through a polite status region, once, after any loading ends. Result\n * counts aren't announced: a screen reader reads the list's size from the\n * markup, and a count on every keystroke talks over the typing. Show one in\n * a `role=\"status\"` line beside the field when it matters.\n *\n * @function\n * @param {ComboboxProps} props - Props for the Combobox component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the `div.combobox`.\n * @returns {JSX.Element} The field and its list, in a `Field` with the label unless one is around it.\n *\n * @example\n * <Combobox\n * label=\"Country\"\n * data={['Canada', 'France', 'Japan']}\n * placeholder=\"Pick a country\"\n * empty=\"No countries match\"\n * />\n *\n * @example\n * <Combobox label=\"Country\" onSelect={pick}>\n * <Combobox.Input value={query} onChange={e => setQuery(e.target.value)} />\n * <Combobox.Menu>\n * {matches.length > 0 ? (\n * <Combobox.List>\n * {matches.map(c => (\n * <Combobox.Item key={c} value={c} checked={c === value}>\n * {c}\n * </Combobox.Item>\n * ))}\n * </Combobox.List>\n * ) : (\n * <Combobox.Empty>No countries match</Combobox.Empty>\n * )}\n * </Combobox.Menu>\n * </Combobox>\n */\nconst ComboboxRoot = forwardRef<HTMLDivElement, ComboboxProps>((props, ref) =>\n props.data === undefined ? (\n <ComboboxParts {...props} ref={ref} />\n ) : (\n <ComboboxFromData {...props} ref={ref} />\n )\n);\n\n/** Combobox with Input, Menu, List, Item, Group and Empty sub-components. */\nexport const Combobox = withSubComponents(\n ComboboxRoot,\n {\n Input: ComboboxInput,\n Menu: ComboboxMenu,\n List: ComboboxList,\n Item: ComboboxItem,\n Group: ComboboxGroup,\n Empty: ComboboxEmpty,\n },\n 'Combobox'\n);\n\nexport default Combobox;\n"],"names":["noop","standalone","setRefs","_jsxs","_jsx","_Fragment","asList"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Control.js","sources":["../../../src/form/Control.tsx"],"sourcesContent":["import React from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { Icon, IconProps } from '../elements/Icon';\nimport { isIconProps } from '../elements/iconProps';\nimport { useConfig } from '../helpers/Config';\nimport { ControlProvider } from './FormContext';\nimport { ControlLoadingProvider } from './controlLoading';\n\n/**\n * Props for the Control component.\n */\nexport interface ControlBaseProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Adds left icon container. */\n hasIconsLeft?: boolean;\n /** Adds right icon container. */\n hasIconsRight?: boolean;\n /**\n * Shows a loading spinner inside the control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * The spinner sits at the right edge, where a right icon also sits, and the\n * two overlap; leave the right icon out while loading.\n */\n isLoading?: boolean;\n /** Makes the control expand to fill available space. */\n isExpanded?: boolean;\n /** Sets the control size. */\n size?: 'small' | 'medium' | 'large';\n /** Sets text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the control. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Icon props for left icon, or a custom node (an inline SVG, a `react-icons` component, …) rendered in place of a class-based glyph.\n * Bulma gives control icons `pointer-events: none`, so a click lands on\n * the input and a clickable node placed here never receives one. Put a button beside the input\n * in its own addon `Control` instead.\n */\n iconLeft?: IconProps | React.ReactNode;\n /**\n * Icon props for right icon, or a custom node (an inline SVG, a `react-icons` component, …) rendered in place of a class-based glyph.\n * Bulma gives control icons `pointer-events: none`, so a click lands on\n * the input and a clickable node placed here never receives one. Put a button beside the input\n * in its own addon `Control` instead.\n */\n iconRight?: IconProps | React.ReactNode;\n /** Shortcut for left icon name. */\n iconLeftName?: string;\n /** Shortcut for left icon size. */\n iconLeftSize?: 'small' | 'medium' | 'large';\n /** Shortcut for right icon name. */\n iconRightName?: string;\n /** Shortcut for right icon size. */\n iconRightSize?: 'small' | 'medium' | 'large';\n /** Additional CSS classes to apply. */\n className?: string;\n /** Content inside the control. */\n children?: React.ReactNode;\n}\n\n/** Props for the Control component, supporting either `div` or `p` as the root element. */\ntype ControlProps =\n | ({\n /** Element type for the control (`div` by default). */\n as?: 'div';\n } & ControlBaseProps & {\n /** Ref for the control element. */\n ref?: React.Ref<HTMLDivElement>;\n })\n | ({\n /** Element type for the control (`div` by default). */\n as: 'p';\n } & Omit<ControlBaseProps, keyof React.HTMLAttributes<HTMLDivElement>> &\n React.HTMLAttributes<HTMLParagraphElement> & {\n /** Ref for the control element. */\n ref?: React.Ref<HTMLParagraphElement>;\n });\n\nconst allowedColors = [...validColors, 'inherit', 'current'] as const;\n\n/**\n * The `Control` component is a Bulma-styled wrapper for form controls (`Input`, `Select`, `TextArea`, etc.), supporting icons (left/right), loading state, expansion, size, and Bulma helper props for layout and color.\n *\n * @function\n * @param {ControlProps} props - Props for the Control component.\n * @returns {JSX.Element} The rendered control container.\n * @see {@link https://bulma.io/documentation/form/general/#control | Bulma Control documentation}\n *\n * @example\n * // Control with left icon\n * <Control iconLeftName=\"envelope\" iconLeftSize=\"small\">\n * <input className=\"input\" type=\"email\" placeholder=\"Email\" />\n * </Control>\n */\nexport const Control = React.forwardRef<\n HTMLDivElement | HTMLParagraphElement,\n ControlProps\n>(\n (\n {\n as = 'div',\n hasIconsLeft,\n hasIconsRight,\n isLoading,\n isExpanded,\n size,\n textColor,\n bgColor,\n iconLeft,\n iconRight,\n iconLeftName,\n iconLeftSize,\n iconRightName,\n iconRightSize,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const Component = (as === 'p' ? 'p' : 'div') as 'div' | 'p';\n const { classPrefix } = useConfig();\n\n const safeTextColor = allowedColors.includes(\n textColor as (typeof allowedColors)[number]\n )\n ? textColor\n : undefined;\n\n const safeBgColor = allowedColors.includes(\n bgColor as (typeof allowedColors)[number]\n )\n ? bgColor\n : undefined;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: safeTextColor,\n backgroundColor: safeBgColor,\n ...(props as Record<string, unknown>),\n });\n\n // Prepare icon props for the shortcut. A truthiness test (not `!== undefined`)\n // so a falsy node from the idiomatic `iconLeft={cond && <Node/>}` / `iconLeft={maybe ?? null}`\n // pattern counts as \"no icon\" — otherwise `false`/`null` would reserve the icon column and\n // mount an empty `.icon` span. A falsy `iconLeft` also correctly falls through to the\n // `iconLeftName` shortcut, matching the pre-node behavior.\n const leftIconValue: IconProps | React.ReactNode | undefined =\n iconLeft ||\n (iconLeftName\n ? {\n name: iconLeftName,\n size: iconLeftSize,\n }\n : undefined);\n\n const rightIconValue: IconProps | React.ReactNode | undefined =\n iconRight ||\n (iconRightName\n ? {\n name: iconRightName,\n size: iconRightSize,\n }\n : undefined);\n\n const mainClass = usePrefixedClassNames('control', {\n 'has-icons-left': hasIconsLeft || !!leftIconValue,\n 'has-icons-right': hasIconsRight || !!rightIconValue,\n 'is-loading': isLoading,\n 'is-expanded': isExpanded,\n [`is-${size}`]: !!size,\n });\n const controlClass = classNames(mainClass, bulmaHelperClasses, className);\n\n return (\n <ControlProvider value={true}>\n <Component className={controlClass} ref={ref as typeof ref} {...rest}>\n <ControlLoadingProvider value={!!isLoading}>\n {children}\n </ControlLoadingProvider>\n {leftIconValue &&\n (isIconProps(leftIconValue) ? (\n <Icon\n {...leftIconValue}\n className={prefixedClassNames(classPrefix, 'is-left')}\n />\n ) : (\n <Icon className={prefixedClassNames(classPrefix, 'is-left')}>\n {leftIconValue}\n </Icon>\n ))}\n {rightIconValue &&\n (isIconProps(rightIconValue) ? (\n <Icon\n {...rightIconValue}\n className={prefixedClassNames(classPrefix, 'is-right')}\n />\n ) : (\n <Icon className={prefixedClassNames(classPrefix, 'is-right')}>\n {rightIconValue}\n </Icon>\n ))}\n </Component>\n </ControlProvider>\n );\n }\n);\n\nControl.displayName = 'Control';\n\nexport default Control;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Control.js","sources":["../../../src/form/Control.tsx"],"sourcesContent":["import React from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { Icon, IconProps } from '../elements/Icon';\nimport { isIconProps } from '../elements/iconProps';\nimport { useConfig } from '../helpers/Config';\nimport { ControlProvider } from './FormContext';\nimport { ControlLoadingProvider } from './controlLoading';\n\n/**\n * Props for the Control component.\n */\nexport interface ControlBaseProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * Adds left icon container.\n * Over a `TextArea` the icon covers the text.\n */\n hasIconsLeft?: boolean;\n /**\n * Adds right icon container.\n * Over a `TextArea` the icon covers the text.\n */\n hasIconsRight?: boolean;\n /**\n * Shows a loading spinner inside the control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * The spinner sits at the right edge, where a right icon also sits, and the\n * two overlap; leave the right icon out while loading.\n */\n isLoading?: boolean;\n /** Makes the control expand to fill available space. */\n isExpanded?: boolean;\n /** Sets the control size. */\n size?: 'small' | 'medium' | 'large';\n /** Sets text color. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the control. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Icon props for left icon, or a custom node (an inline SVG, a `react-icons` component, …) rendered in place of a class-based glyph.\n * Over a `TextArea` the icon covers the text.\n * Bulma gives control icons `pointer-events: none`, so a click lands on\n * the input and a clickable node placed here never receives one. Put a button beside the input\n * in its own addon `Control` instead.\n */\n iconLeft?: IconProps | React.ReactNode;\n /**\n * Icon props for right icon, or a custom node (an inline SVG, a `react-icons` component, …) rendered in place of a class-based glyph.\n * Over a `TextArea` the icon covers the text.\n * Bulma gives control icons `pointer-events: none`, so a click lands on\n * the input and a clickable node placed here never receives one. Put a button beside the input\n * in its own addon `Control` instead.\n */\n iconRight?: IconProps | React.ReactNode;\n /**\n * Shortcut for left icon name.\n * Over a `TextArea` the icon covers the text.\n */\n iconLeftName?: string;\n /** Shortcut for left icon size. */\n iconLeftSize?: 'small' | 'medium' | 'large';\n /**\n * Shortcut for right icon name.\n * Over a `TextArea` the icon covers the text.\n */\n iconRightName?: string;\n /** Shortcut for right icon size. */\n iconRightSize?: 'small' | 'medium' | 'large';\n /** Additional CSS classes to apply. */\n className?: string;\n /** Content inside the control. */\n children?: React.ReactNode;\n}\n\n/** Props for the Control component, supporting either `div` or `p` as the root element. */\ntype ControlProps =\n | ({\n /** Element type for the control (`div` by default). */\n as?: 'div';\n } & ControlBaseProps & {\n /** Ref for the control element. */\n ref?: React.Ref<HTMLDivElement>;\n })\n | ({\n /** Element type for the control (`div` by default). */\n as: 'p';\n } & Omit<ControlBaseProps, keyof React.HTMLAttributes<HTMLDivElement>> &\n React.HTMLAttributes<HTMLParagraphElement> & {\n /** Ref for the control element. */\n ref?: React.Ref<HTMLParagraphElement>;\n });\n\nconst allowedColors = [...validColors, 'inherit', 'current'] as const;\n\n/**\n * The `Control` component is a Bulma-styled wrapper for form controls (`Input`, `Select`, `TextArea`, etc.), supporting icons (left/right), loading state, expansion, size, and Bulma helper props for layout and color.\n *\n * @function\n * @param {ControlProps} props - Props for the Control component.\n * @returns {JSX.Element} The rendered control container.\n * @see {@link https://bulma.io/documentation/form/general/#control | Bulma Control documentation}\n *\n * @example\n * // Control with left icon\n * <Control iconLeftName=\"envelope\" iconLeftSize=\"small\">\n * <input className=\"input\" type=\"email\" placeholder=\"Email\" />\n * </Control>\n */\nexport const Control = React.forwardRef<\n HTMLDivElement | HTMLParagraphElement,\n ControlProps\n>(\n (\n {\n as = 'div',\n hasIconsLeft,\n hasIconsRight,\n isLoading,\n isExpanded,\n size,\n textColor,\n bgColor,\n iconLeft,\n iconRight,\n iconLeftName,\n iconLeftSize,\n iconRightName,\n iconRightSize,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const Component = (as === 'p' ? 'p' : 'div') as 'div' | 'p';\n const { classPrefix } = useConfig();\n\n const safeTextColor = allowedColors.includes(\n textColor as (typeof allowedColors)[number]\n )\n ? textColor\n : undefined;\n\n const safeBgColor = allowedColors.includes(\n bgColor as (typeof allowedColors)[number]\n )\n ? bgColor\n : undefined;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: safeTextColor,\n backgroundColor: safeBgColor,\n ...(props as Record<string, unknown>),\n });\n\n // Prepare icon props for the shortcut. A truthiness test (not `!== undefined`)\n // so a falsy node from the idiomatic `iconLeft={cond && <Node/>}` / `iconLeft={maybe ?? null}`\n // pattern counts as \"no icon\" — otherwise `false`/`null` would reserve the icon column and\n // mount an empty `.icon` span. A falsy `iconLeft` also correctly falls through to the\n // `iconLeftName` shortcut, matching the pre-node behavior.\n const leftIconValue: IconProps | React.ReactNode | undefined =\n iconLeft ||\n (iconLeftName\n ? {\n name: iconLeftName,\n size: iconLeftSize,\n }\n : undefined);\n\n const rightIconValue: IconProps | React.ReactNode | undefined =\n iconRight ||\n (iconRightName\n ? {\n name: iconRightName,\n size: iconRightSize,\n }\n : undefined);\n\n const mainClass = usePrefixedClassNames('control', {\n 'has-icons-left': hasIconsLeft || !!leftIconValue,\n 'has-icons-right': hasIconsRight || !!rightIconValue,\n 'is-loading': isLoading,\n 'is-expanded': isExpanded,\n [`is-${size}`]: !!size,\n });\n const controlClass = classNames(mainClass, bulmaHelperClasses, className);\n\n return (\n <ControlProvider value={true}>\n <Component className={controlClass} ref={ref as typeof ref} {...rest}>\n <ControlLoadingProvider value={!!isLoading}>\n {children}\n </ControlLoadingProvider>\n {leftIconValue &&\n (isIconProps(leftIconValue) ? (\n <Icon\n {...leftIconValue}\n className={prefixedClassNames(classPrefix, 'is-left')}\n />\n ) : (\n <Icon className={prefixedClassNames(classPrefix, 'is-left')}>\n {leftIconValue}\n </Icon>\n ))}\n {rightIconValue &&\n (isIconProps(rightIconValue) ? (\n <Icon\n {...rightIconValue}\n className={prefixedClassNames(classPrefix, 'is-right')}\n />\n ) : (\n <Icon className={prefixedClassNames(classPrefix, 'is-right')}>\n {rightIconValue}\n </Icon>\n ))}\n </Component>\n </ControlProvider>\n );\n }\n);\n\nControl.displayName = 'Control';\n\nexport default Control;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|