@allxsmith/bestax-bulma 5.67.11 → 5.67.12

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.
@@ -30,7 +30,9 @@ const Button = forwardRef(function Button(props, ref) {
30
30
  validButtonColors.includes(color),
31
31
  [`is-${size}`]: size,
32
32
  'is-outlined': isOutlined,
33
- 'is-light': isLight,
33
+ // The light color's own class is this key too, and this one comes later,
34
+ // so it has to set the class for `light` as well or it erases it.
35
+ 'is-light': isLight || color === 'light',
34
36
  'is-loading': isLoading,
35
37
  'is-static': isStatic,
36
38
  'is-disabled': isDisabled,
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sources":["../../../src/elements/Button.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n isCustomElement,\n type PolymorphicComponent,\n} from '../helpers/polymorphic';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * The Button component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface ButtonOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor' | 'size'\n> {\n /**\n * Not accepted under this name. `useBulmaClasses` consumes any\n * `backgroundColor` key before `rest` is spread, so a custom `as` target\n * declaring one would never receive it. Use `bgColor`.\n * @internal\n */\n backgroundColor?: never;\n /** Bulma color variant for the button. `ghost` renders a link-like button; `text` renders a minimal text-only button. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'white'\n | 'light'\n | 'dark'\n | 'black'\n | 'text'\n | 'ghost';\n /** Size of the button. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /** Applies a lighter color variant. */\n isLight?: boolean;\n /** Makes the button rounded. */\n isRounded?: boolean;\n /**\n * Displays a loading spinner, with everything inside the button hidden\n * behind it, in forced colors (Windows' contrast themes) too. Under\n * `prefers-reduced-motion: reduce` the spinner stops and stays drawn.\n * Bulma alone hides only the label, so the rest needs bestax's CSS loaded.\n */\n isLoading?: boolean;\n /** Makes the button non-interactive. */\n isStatic?: boolean;\n /** Makes the button full-width. */\n isFullwidth?: boolean;\n /** Makes the button full-width. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Applies outlined styling (requires color). */\n isOutlined?: boolean;\n /** Applies inverted styling (requires color). */\n isInverted?: boolean;\n /** Applies focused styling (visual only). */\n isFocused?: boolean;\n /** Applies active styling (visual only), with no `aria-pressed`. For a button that stays pressed, use `ToggleButton`. */\n isActive?: boolean;\n /** Applies hovered styling (visual only). */\n isHovered?: boolean;\n /** Applies disabled styling. */\n isDisabled?: boolean;\n /** Custom class name. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Button content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the Button component. The DOM attributes and the `ref` both follow\n * `as`: with `as=\"a\"` the anchor attributes are accepted, with `as=\"div\"` they\n * are not.\n *\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders, typed from `as`: the DOM node for an intrinsic tag, or whatever handle a custom component exposes.\n */\nexport type ButtonProps<T extends React.ElementType = 'button'> =\n ButtonOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof ButtonOwnProps | 'as'> & {\n /** Render as a `<button>`, `<a>`, or a custom component (e.g. a router `Link`). Defaults to `'button'`; anything else renders through the anchor path, which adds `href`/`target`/`rel` and withholds the submit-override attributes (`formAction` and friends) from an `<a>`. */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `ButtonProps<T>` above — the body cannot see through `T`, so it reads the\n * widest form of the props it actually touches.\n */\ntype ButtonImplProps = ButtonOwnProps & {\n as?: React.ElementType;\n href?: string;\n target?: string;\n rel?: string;\n onClick?:\n | React.MouseEventHandler<HTMLButtonElement>\n | React.MouseEventHandler<HTMLAnchorElement>;\n};\n\nconst validButtonColors = [...validColors, 'text', 'ghost'] as const;\n\n/**\n * The `Button` component provides a flexible and highly customizable button for your Bulma React UI.\n *\n * @function\n * @param {ButtonProps} props - Props for the Button component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered button, anchor, or custom element.\n * @see {@link https://bulma.io/documentation/elements/button/ | Bulma Button documentation}\n */\n\nexport const Button = forwardRef(function Button(\n props: ButtonProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n color,\n size,\n isLight,\n isRounded,\n isLoading,\n isStatic,\n isFullwidth,\n isFullWidth,\n isOutlined,\n isInverted,\n isFocused,\n isActive,\n isHovered,\n isDisabled,\n className,\n children,\n textColor,\n bgColor,\n as: Component = 'button',\n href,\n onClick,\n target,\n rel,\n ...bulmaProps\n } = props as ButtonImplProps;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...bulmaProps,\n });\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('button', {\n [`is-${color}`]:\n color &&\n validButtonColors.includes(color as (typeof validButtonColors)[number]),\n [`is-${size}`]: size,\n 'is-outlined': isOutlined,\n 'is-light': isLight,\n 'is-loading': isLoading,\n 'is-static': isStatic,\n 'is-disabled': isDisabled,\n 'is-rounded': isRounded,\n 'is-hovered': isHovered,\n 'is-focused': isFocused,\n 'is-active': isActive,\n 'is-inverted': isInverted,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n });\n\n // Combine prefixed Bulma classes with unprefixed user className and prefixed helper classes\n const buttonClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n if (Component !== 'button') {\n // Strip the form-control attributes a link-like element cannot carry, so a\n // JavaScript consumer or a spread object doesn't put them on the DOM. The\n // types no longer allow them through; this is the runtime backstop.\n //\n // Only for INTRINSIC tags. A custom component (a router Link, ...) owns its\n // prop contract, and `ComponentPropsWithoutRef<T>` promises the caller that\n // its props reach it. Stripping names by their spelling alone broke that\n // promise silently: `<Button as={Custom} name=\"x\" />` type-checked while\n // `Custom` never received the `name` it requires.\n //\n // `autoFocus` and `type` are deliberately NOT stripped: both are valid on\n // targets this list was filtering them from. `autoFocus` is a global\n // attribute (React decides per element whether to honour it, which is not\n // ours to pre-empt), and `type` on an anchor is the MIME hint that\n // `ButtonProps<'a'>` now types it as.\n //\n // The types already answer this for a TypeScript caller: `ButtonProps<T>`\n // derives from `ComponentPropsWithoutRef<T>`, so only what the target\n // accepts can be passed. What is left is a runtime backstop for JavaScript\n // consumers and spread objects.\n //\n // Keep it to the two cases where a stray attribute does something. The\n // submit-overrides belong to a submit control and never make sense on the\n // anchor path. `disabled` is the one that is VISIBLE: Bulma styles\n // `.button[disabled]` (background, border, shadow, opacity), so letting it\n // through to a `<span>` greys the element out — main stripped it, and not\n // stripping it would be a silent visual change on a types-only release.\n //\n // Everything else (`name`, `value`, `form`) is inert where it does not\n // belong, and enumerating which tags own it is what kept going wrong:\n // first all nine names on every non-button tag (so `<Button as=\"input\"\n // name=\"query\" value=\"Search\">` submitted nothing), then a form-control\n // allowlist that still lost `formAction` on an input and `value` on an\n // option. Those now ride on the types instead.\n //\n // A custom component is exempt entirely — it owns its prop contract, and\n // `ComponentPropsWithoutRef<T>` promises the caller its props arrive.\n //\n // The elements that own `disabled`, per the HTML spec. A closed set, unlike\n // the open-ended question of which tag owns which attribute.\n const SUBMIT_OVERRIDES = [\n 'formAction',\n 'formEncType',\n 'formMethod',\n 'formNoValidate',\n 'formTarget',\n ];\n const OWNS_DISABLED = [\n 'button',\n 'fieldset',\n 'input',\n 'optgroup',\n 'option',\n 'select',\n 'textarea',\n ];\n\n // Two independent filters. They are not exclusive — an `<a>` owns neither\n // the submit-overrides nor `disabled`, so it takes both — and deriving them\n // from one destructure, or from one if/else, is what broke each of them in\n // turn: first the overrides came off every intrinsic (an `as=\"input\"` lost\n // `formAction`), then scoping them to the anchor let `disabled` back onto\n // it.\n const forwardedRest: Record<string, unknown> = { ...rest };\n if (typeof Component === 'string' && !isCustomElement(Component)) {\n // Meaningless anywhere but a submit control, and an anchor is not one.\n if (Component === 'a') {\n for (const key of SUBMIT_OVERRIDES) delete forwardedRest[key];\n }\n // Visible via Bulma's `.button[disabled]`, so withheld from any element\n // that does not own it.\n if (!OWNS_DISABLED.includes(Component)) delete forwardedRest.disabled;\n }\n\n return (\n <Component\n ref={ref as React.Ref<HTMLAnchorElement>}\n className={buttonClasses}\n href={href}\n target={target}\n rel={rel}\n aria-disabled={isDisabled}\n tabIndex={isDisabled ? -1 : undefined}\n onClick={\n isDisabled\n ? // Guarded, because this handler is installed into whatever `as`\n // renders and a custom component's `onClick` need not be a DOM\n // event handler at all. One declaring `onClick: (v: string) =>\n // void` calls this with a string, and an unguarded\n // `e.preventDefault()` throws `is not a function`. Blocking the\n // real event is the point; a foreign payload is simply not ours\n // to act on.\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (typeof e?.preventDefault === 'function') e.preventDefault();\n }\n : (onClick as\n React.MouseEventHandler<HTMLAnchorElement> | undefined)\n }\n {...(forwardedRest as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {children}\n </Component>\n );\n }\n\n return (\n <button\n ref={ref as React.Ref<HTMLButtonElement>}\n className={buttonClasses}\n disabled={isDisabled}\n onClick={\n onClick as React.MouseEventHandler<HTMLButtonElement> | undefined\n }\n {...rest}\n >\n {children}\n </button>\n );\n}) as PolymorphicComponent<ButtonOwnProps, 'button'>;\n\nButton.displayName = 'Button';\n\nexport default Button;\n"],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Button.js","sources":["../../../src/elements/Button.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n isCustomElement,\n type PolymorphicComponent,\n} from '../helpers/polymorphic';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\n\n/**\n * The Button component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface ButtonOwnProps extends Omit<\n BulmaClassesProps,\n 'color' | 'backgroundColor' | 'size'\n> {\n /**\n * Not accepted under this name. `useBulmaClasses` consumes any\n * `backgroundColor` key before `rest` is spread, so a custom `as` target\n * declaring one would never receive it. Use `bgColor`.\n * @internal\n */\n backgroundColor?: never;\n /** Bulma color variant for the button. `ghost` renders a link-like button; `text` renders a minimal text-only button. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'white'\n | 'light'\n | 'dark'\n | 'black'\n | 'text'\n | 'ghost';\n /** Size of the button. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /** Applies a lighter color variant. */\n isLight?: boolean;\n /** Makes the button rounded. */\n isRounded?: boolean;\n /**\n * Displays a loading spinner, with everything inside the button hidden\n * behind it, in forced colors (Windows' contrast themes) too. Under\n * `prefers-reduced-motion: reduce` the spinner stops and stays drawn.\n * Bulma alone hides only the label, so the rest needs bestax's CSS loaded.\n */\n isLoading?: boolean;\n /** Makes the button non-interactive. */\n isStatic?: boolean;\n /** Makes the button full-width. */\n isFullwidth?: boolean;\n /** Makes the button full-width. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Applies outlined styling (requires color). */\n isOutlined?: boolean;\n /** Applies inverted styling (requires color). */\n isInverted?: boolean;\n /** Applies focused styling (visual only). */\n isFocused?: boolean;\n /** Applies active styling (visual only), with no `aria-pressed`. For a button that stays pressed, use `ToggleButton`. */\n isActive?: boolean;\n /** Applies hovered styling (visual only). */\n isHovered?: boolean;\n /** Applies disabled styling. */\n isDisabled?: boolean;\n /** Custom class name. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Background color helper. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Button content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the Button component. The DOM attributes and the `ref` both follow\n * `as`: with `as=\"a\"` the anchor attributes are accepted, with `as=\"div\"` they\n * are not.\n *\n * @extraProp {PolymorphicRef<React.ElementType>} [ref] - Ref forwarded to the element `as` renders, typed from `as`: the DOM node for an intrinsic tag, or whatever handle a custom component exposes.\n */\nexport type ButtonProps<T extends React.ElementType = 'button'> =\n ButtonOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof ButtonOwnProps | 'as'> & {\n /** Render as a `<button>`, `<a>`, or a custom component (e.g. a router `Link`). Defaults to `'button'`; anything else renders through the anchor path, which adds `href`/`target`/`rel` and withholds the submit-override attributes (`formAction` and friends) from an `<a>`. */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `ButtonProps<T>` above — the body cannot see through `T`, so it reads the\n * widest form of the props it actually touches.\n */\ntype ButtonImplProps = ButtonOwnProps & {\n as?: React.ElementType;\n href?: string;\n target?: string;\n rel?: string;\n onClick?:\n | React.MouseEventHandler<HTMLButtonElement>\n | React.MouseEventHandler<HTMLAnchorElement>;\n};\n\nconst validButtonColors = [...validColors, 'text', 'ghost'] as const;\n\n/**\n * The `Button` component provides a flexible and highly customizable button for your Bulma React UI.\n *\n * @function\n * @param {ButtonProps} props - Props for the Button component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered button, anchor, or custom element.\n * @see {@link https://bulma.io/documentation/elements/button/ | Bulma Button documentation}\n */\n\nexport const Button = forwardRef(function Button(\n props: ButtonProps,\n ref: React.Ref<HTMLElement>\n) {\n const {\n color,\n size,\n isLight,\n isRounded,\n isLoading,\n isStatic,\n isFullwidth,\n isFullWidth,\n isOutlined,\n isInverted,\n isFocused,\n isActive,\n isHovered,\n isDisabled,\n className,\n children,\n textColor,\n bgColor,\n as: Component = 'button',\n href,\n onClick,\n target,\n rel,\n ...bulmaProps\n } = props as ButtonImplProps;\n\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...bulmaProps,\n });\n\n // Generate Bulma classes with prefix\n const bulmaClasses = usePrefixedClassNames('button', {\n [`is-${color}`]:\n color &&\n validButtonColors.includes(color as (typeof validButtonColors)[number]),\n [`is-${size}`]: size,\n 'is-outlined': isOutlined,\n // The light color's own class is this key too, and this one comes later,\n // so it has to set the class for `light` as well or it erases it.\n 'is-light': isLight || color === 'light',\n 'is-loading': isLoading,\n 'is-static': isStatic,\n 'is-disabled': isDisabled,\n 'is-rounded': isRounded,\n 'is-hovered': isHovered,\n 'is-focused': isFocused,\n 'is-active': isActive,\n 'is-inverted': isInverted,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n });\n\n // Combine prefixed Bulma classes with unprefixed user className and prefixed helper classes\n const buttonClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n if (Component !== 'button') {\n // Strip the form-control attributes a link-like element cannot carry, so a\n // JavaScript consumer or a spread object doesn't put them on the DOM. The\n // types no longer allow them through; this is the runtime backstop.\n //\n // Only for INTRINSIC tags. A custom component (a router Link, ...) owns its\n // prop contract, and `ComponentPropsWithoutRef<T>` promises the caller that\n // its props reach it. Stripping names by their spelling alone broke that\n // promise silently: `<Button as={Custom} name=\"x\" />` type-checked while\n // `Custom` never received the `name` it requires.\n //\n // `autoFocus` and `type` are deliberately NOT stripped: both are valid on\n // targets this list was filtering them from. `autoFocus` is a global\n // attribute (React decides per element whether to honour it, which is not\n // ours to pre-empt), and `type` on an anchor is the MIME hint that\n // `ButtonProps<'a'>` now types it as.\n //\n // The types already answer this for a TypeScript caller: `ButtonProps<T>`\n // derives from `ComponentPropsWithoutRef<T>`, so only what the target\n // accepts can be passed. What is left is a runtime backstop for JavaScript\n // consumers and spread objects.\n //\n // Keep it to the two cases where a stray attribute does something. The\n // submit-overrides belong to a submit control and never make sense on the\n // anchor path. `disabled` is the one that is VISIBLE: Bulma styles\n // `.button[disabled]` (background, border, shadow, opacity), so letting it\n // through to a `<span>` greys the element out — main stripped it, and not\n // stripping it would be a silent visual change on a types-only release.\n //\n // Everything else (`name`, `value`, `form`) is inert where it does not\n // belong, and enumerating which tags own it is what kept going wrong:\n // first all nine names on every non-button tag (so `<Button as=\"input\"\n // name=\"query\" value=\"Search\">` submitted nothing), then a form-control\n // allowlist that still lost `formAction` on an input and `value` on an\n // option. Those now ride on the types instead.\n //\n // A custom component is exempt entirely — it owns its prop contract, and\n // `ComponentPropsWithoutRef<T>` promises the caller its props arrive.\n //\n // The elements that own `disabled`, per the HTML spec. A closed set, unlike\n // the open-ended question of which tag owns which attribute.\n const SUBMIT_OVERRIDES = [\n 'formAction',\n 'formEncType',\n 'formMethod',\n 'formNoValidate',\n 'formTarget',\n ];\n const OWNS_DISABLED = [\n 'button',\n 'fieldset',\n 'input',\n 'optgroup',\n 'option',\n 'select',\n 'textarea',\n ];\n\n // Two independent filters. They are not exclusive — an `<a>` owns neither\n // the submit-overrides nor `disabled`, so it takes both — and deriving them\n // from one destructure, or from one if/else, is what broke each of them in\n // turn: first the overrides came off every intrinsic (an `as=\"input\"` lost\n // `formAction`), then scoping them to the anchor let `disabled` back onto\n // it.\n const forwardedRest: Record<string, unknown> = { ...rest };\n if (typeof Component === 'string' && !isCustomElement(Component)) {\n // Meaningless anywhere but a submit control, and an anchor is not one.\n if (Component === 'a') {\n for (const key of SUBMIT_OVERRIDES) delete forwardedRest[key];\n }\n // Visible via Bulma's `.button[disabled]`, so withheld from any element\n // that does not own it.\n if (!OWNS_DISABLED.includes(Component)) delete forwardedRest.disabled;\n }\n\n return (\n <Component\n ref={ref as React.Ref<HTMLAnchorElement>}\n className={buttonClasses}\n href={href}\n target={target}\n rel={rel}\n aria-disabled={isDisabled}\n tabIndex={isDisabled ? -1 : undefined}\n onClick={\n isDisabled\n ? // Guarded, because this handler is installed into whatever `as`\n // renders and a custom component's `onClick` need not be a DOM\n // event handler at all. One declaring `onClick: (v: string) =>\n // void` calls this with a string, and an unguarded\n // `e.preventDefault()` throws `is not a function`. Blocking the\n // real event is the point; a foreign payload is simply not ours\n // to act on.\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (typeof e?.preventDefault === 'function') e.preventDefault();\n }\n : (onClick as\n React.MouseEventHandler<HTMLAnchorElement> | undefined)\n }\n {...(forwardedRest as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n >\n {children}\n </Component>\n );\n }\n\n return (\n <button\n ref={ref as React.Ref<HTMLButtonElement>}\n className={buttonClasses}\n disabled={isDisabled}\n onClick={\n onClick as React.MouseEventHandler<HTMLButtonElement> | undefined\n }\n {...rest}\n >\n {children}\n </button>\n );\n}) as PolymorphicComponent<ButtonOwnProps, 'button'>;\n\nButton.displayName = 'Button';\n\nexport default Button;\n"],"names":["_jsx"],"mappings":"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"}
@@ -33,7 +33,9 @@ const Notification = ({ className, color, textColor, isLight, hasDelete, onDelet
33
33
  });
34
34
  const bulmaClasses = usePrefixedClassNames('notification', {
35
35
  [`is-${color}`]: color && validColors.includes(color),
36
- 'is-light': isLight,
36
+ // The light color's own class is this key too, and this one comes later,
37
+ // so it has to set the class for `light` as well or it erases it.
38
+ 'is-light': isLight || color === 'light',
37
39
  'has-delete': hasDelete,
38
40
  });
39
41
  const deleteClasses = usePrefixedClassNames('delete');
@@ -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';\nimport { scrollLockOffset } from '../helpers/scrollLock';\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 * While an overlay locks the page, each side adds the room the page's\n * scrollbar gave back there, so the stack stays put as the scrollbar goes.\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 const left = scrollLockOffset('left');\n const right = scrollLockOffset('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: `calc(100% - ${left} - ${right})`,\n ...(isBottom ? { bottom: 0 } : { top: 0 }),\n ...(isCenter\n ? {\n left: `calc(50% + (${left} - ${right}) / 2)`,\n transform: 'translateX(-50%)',\n alignItems: 'center',\n }\n : isRight\n ? { right, alignItems: 'flex-end' }\n : { left, 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';\nimport { scrollLockOffset } from '../helpers/scrollLock';\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` and `light` take their color's own text and background from\n * bestax's stylesheets, as a dark or light `Button` has. With Bulma's CSS\n * alone, their text inherits the color around it, which on a light page is\n * one shade off a dark notification's background, and on a dark page is\n * hard to read on a light one.\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 light and dark colors have none, so\n * `color=\"light\"` or `color=\"dark\"` with `isLight` looks the same as\n * without it, as a light or 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 // The light color's own class is this key too, and this one comes later,\n // so it has to set the class for `light` as well or it erases it.\n 'is-light': isLight || color === 'light',\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` and `light` take their color's own text and background from\n * bestax's stylesheets, as a dark or light `Button` has. With Bulma's CSS\n * alone, their text inherits the color around it, which on a light page is\n * one shade off a dark notification's background, and on a dark page is\n * hard to read on a light one.\n */\n color?: (typeof validColors)[number];\n /**\n * Use the light color variant. The light and dark colors have none, so\n * `color=\"light\"` or `color=\"dark\"` with `isLight` looks the same as\n * without it, as a light or 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 * While an overlay locks the page, each side adds the room the page's\n * scrollbar gave back there, so the stack stays put as the scrollbar goes.\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 const left = scrollLockOffset('left');\n const right = scrollLockOffset('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: `calc(100% - ${left} - ${right})`,\n ...(isBottom ? { bottom: 0 } : { top: 0 }),\n ...(isCenter\n ? {\n left: `calc(50% + (${left} - ${right}) / 2)`,\n transform: 'translateX(-50%)',\n alignItems: 'center',\n }\n : isRight\n ? { right, alignItems: 'flex-end' }\n : { left, 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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"}
@@ -34,7 +34,9 @@ const Tag = ({ className, color, size, isLight, isRounded, isDelete, isHoverable
34
34
  const bulmaClasses = usePrefixedClassNames('tag', {
35
35
  [`is-${color}`]: color && validTagColors.includes(color),
36
36
  [`is-${size}`]: size && size !== 'normal' && validTagSizes.includes(size),
37
- 'is-light': isLight,
37
+ // The light color's own class is this key too, and this one comes later,
38
+ // so it has to set the class for `light` as well or it erases it.
39
+ 'is-light': isLight || color === 'light',
38
40
  'is-rounded': isRounded,
39
41
  'is-delete': isDelete,
40
42
  'is-hoverable': isHoverable,
@@ -1 +1 @@
1
- {"version":3,"file":"Tag.js","sources":["../../../src/elements/Tag.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { buttonType } from '../helpers/buttonType';\n\nconst validTagColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n 'black',\n 'dark',\n 'light',\n 'white',\n] as const;\n\n/**\n * Valid color values for the Tag component (Bulma tag colors).\n */\nexport type TagColor = (typeof validTagColors)[number];\n\nconst validTagSizes = ['normal', 'medium', 'large'] as const;\n/**\n * Valid size values for the Tag component (Bulma tag sizes).\n */\nexport type TagSize = (typeof validTagSizes)[number];\n\n/**\n * Props for the Tag component.\n */\nexport interface TagProps\n extends\n Omit<React.HTMLAttributes<HTMLSpanElement>, 'color'>,\n Omit<BulmaClassesProps, 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Bulma color modifier for the tag. */\n color?: TagColor;\n /** Tag size. */\n size?: TagSize;\n /** Use the light color variant. */\n isLight?: boolean;\n /** Renders a rounded tag. */\n isRounded?: boolean;\n /**\n * Renders a delete-style tag (delete button). The button renders\n * `type=\"button\"`, so it does not submit a form around it, and is named\n * \"Delete tag\" unless you pass an `aria-label`. An empty one, or a spread\n * carrying `'aria-label': undefined`, keeps that name rather than leaving\n * the button unnamed.\n */\n isDelete?: boolean;\n /** Adds hover effect to the tag. */\n isHoverable?: boolean;\n /** Callback for delete tag/button. */\n onDelete?: () => void;\n /** Tag content. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Tag` component renders a Bulma-styled label or badge.\n *\n * @function\n * @param {TagProps} props - Props for the Tag component.\n * @returns {JSX.Element} The rendered tag element.\n * @see {@link https://bulma.io/documentation/elements/tag/ | Bulma Tag documentation}\n */\nexport const Tag: React.FC<TagProps> = ({\n className,\n color,\n size,\n isLight,\n isRounded,\n isDelete,\n isHoverable,\n onDelete,\n children,\n ...props\n}) => {\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const bulmaClasses = usePrefixedClassNames('tag', {\n [`is-${color}`]: color && validTagColors.includes(color),\n [`is-${size}`]: size && size !== 'normal' && validTagSizes.includes(size),\n 'is-light': isLight,\n 'is-rounded': isRounded,\n 'is-delete': isDelete,\n 'is-hoverable': isHoverable,\n });\n\n const tagClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n if (isDelete) {\n return (\n <button\n className={tagClasses}\n onClick={onDelete}\n {...rest}\n // After the spread, reading through it: a key the spread carries with\n // no value would otherwise erase the default, leaving a nameless\n // button that submits the form around it. An empty label falls back\n // too: the button is drawn as an icon, so `''` would leave it unnamed.\n // A caller's own value still wins; `buttonType` says more.\n aria-label={rest['aria-label'] || 'Delete tag'}\n type={buttonType((rest as { type?: unknown }).type)}\n />\n );\n }\n\n return (\n <span className={tagClasses} {...rest}>\n {children}\n </span>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;AAKA,MAAM,cAAc,GAAG;IACrB,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;CACC;AAOV,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAU;AAuC5D;;;;;;;AAOG;AACI,MAAM,GAAG,GAAuB,CAAC,EACtC,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,EACP,SAAS,EACT,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;AAElE,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,KAAK,EAAE;AAChD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxD,QAAA,CAAC,MAAM,IAAI,CAAA,CAAE,GAAG,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;AACzE,QAAA,UAAU,EAAE,OAAO;AACnB,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,cAAc,EAAE,WAAW;AAC5B,KAAA,CAAC;IAEF,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC;IAE1E,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,QAAQ,EAAA,GACb,IAAI,EAAA,YAAA,EAMI,IAAI,CAAC,YAAY,CAAC,IAAI,YAAY,EAC9C,IAAI,EAAE,UAAU,CAAE,IAA2B,CAAC,IAAI,CAAC,EAAA,CACnD;IAEN;IAEA,QACEA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,UAAU,EAAA,GAAM,IAAI,EAAA,QAAA,EAClC,QAAQ,EAAA,CACJ;AAEX;;"}
1
+ {"version":3,"file":"Tag.js","sources":["../../../src/elements/Tag.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { buttonType } from '../helpers/buttonType';\n\nconst validTagColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n 'black',\n 'dark',\n 'light',\n 'white',\n] as const;\n\n/**\n * Valid color values for the Tag component (Bulma tag colors).\n */\nexport type TagColor = (typeof validTagColors)[number];\n\nconst validTagSizes = ['normal', 'medium', 'large'] as const;\n/**\n * Valid size values for the Tag component (Bulma tag sizes).\n */\nexport type TagSize = (typeof validTagSizes)[number];\n\n/**\n * Props for the Tag component.\n */\nexport interface TagProps\n extends\n Omit<React.HTMLAttributes<HTMLSpanElement>, 'color'>,\n Omit<BulmaClassesProps, 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * Bulma color modifier for the tag.\n *\n * `light` takes the light color's own text from bestax's stylesheets. With\n * Bulma's CSS alone, a light tag's text inherits the color around it, which\n * on a dark page is hard to read.\n */\n color?: TagColor;\n /** Tag size. */\n size?: TagSize;\n /**\n * Use the light color variant. The light color has none, so\n * `color=\"light\"` with `isLight` looks the same as without it.\n */\n isLight?: boolean;\n /** Renders a rounded tag. */\n isRounded?: boolean;\n /**\n * Renders a delete-style tag (delete button). The button renders\n * `type=\"button\"`, so it does not submit a form around it, and is named\n * \"Delete tag\" unless you pass an `aria-label`. An empty one, or a spread\n * carrying `'aria-label': undefined`, keeps that name rather than leaving\n * the button unnamed.\n */\n isDelete?: boolean;\n /** Adds hover effect to the tag. */\n isHoverable?: boolean;\n /** Callback for delete tag/button. */\n onDelete?: () => void;\n /** Tag content. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Tag` component renders a Bulma-styled label or badge.\n *\n * @function\n * @param {TagProps} props - Props for the Tag component.\n * @returns {JSX.Element} The rendered tag element.\n * @see {@link https://bulma.io/documentation/elements/tag/ | Bulma Tag documentation}\n */\nexport const Tag: React.FC<TagProps> = ({\n className,\n color,\n size,\n isLight,\n isRounded,\n isDelete,\n isHoverable,\n onDelete,\n children,\n ...props\n}) => {\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const bulmaClasses = usePrefixedClassNames('tag', {\n [`is-${color}`]: color && validTagColors.includes(color),\n [`is-${size}`]: size && size !== 'normal' && validTagSizes.includes(size),\n // The light color's own class is this key too, and this one comes later,\n // so it has to set the class for `light` as well or it erases it.\n 'is-light': isLight || color === 'light',\n 'is-rounded': isRounded,\n 'is-delete': isDelete,\n 'is-hoverable': isHoverable,\n });\n\n const tagClasses = classNames(bulmaClasses, bulmaHelperClasses, className);\n\n if (isDelete) {\n return (\n <button\n className={tagClasses}\n onClick={onDelete}\n {...rest}\n // After the spread, reading through it: a key the spread carries with\n // no value would otherwise erase the default, leaving a nameless\n // button that submits the form around it. An empty label falls back\n // too: the button is drawn as an icon, so `''` would leave it unnamed.\n // A caller's own value still wins; `buttonType` says more.\n aria-label={rest['aria-label'] || 'Delete tag'}\n type={buttonType((rest as { type?: unknown }).type)}\n />\n );\n }\n\n return (\n <span className={tagClasses} {...rest}>\n {children}\n </span>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;AAKA,MAAM,cAAc,GAAG;IACrB,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;CACC;AAOV,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAU;AAgD5D;;;;;;;AAOG;AACI,MAAM,GAAG,GAAuB,CAAC,EACtC,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,EACP,SAAS,EACT,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;AAElE,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,KAAK,EAAE;AAChD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxD,QAAA,CAAC,MAAM,IAAI,CAAA,CAAE,GAAG,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;;;AAGzE,QAAA,UAAU,EAAE,OAAO,IAAI,KAAK,KAAK,OAAO;AACxC,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,cAAc,EAAE,WAAW;AAC5B,KAAA,CAAC;IAEF,MAAM,UAAU,GAAG,UAAU,CAAC,YAAY,EAAE,kBAAkB,EAAE,SAAS,CAAC;IAE1E,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEA,GAAA,CAAA,QAAA,EAAA,EACE,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,QAAQ,EAAA,GACb,IAAI,EAAA,YAAA,EAMI,IAAI,CAAC,YAAY,CAAC,IAAI,YAAY,EAC9C,IAAI,EAAE,UAAU,CAAE,IAA2B,CAAC,IAAI,CAAC,EAAA,CACnD;IAEN;IAEA,QACEA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,UAAU,EAAA,GAAM,IAAI,EAAA,QAAA,EAClC,QAAQ,EAAA,CACJ;AAEX;;"}
@@ -127,7 +127,9 @@ const ColorInputBase = forwardRef((props, ref) => {
127
127
  [`is-${color}`]: !!color,
128
128
  [`is-${size}`]: !!size,
129
129
  'is-rounded': !!isRounded,
130
- 'is-danger': invalid && !color,
130
+ // The danger color's own class is this key too, and this one comes
131
+ // later, so it has to set the class for `danger` as well or it erases it.
132
+ 'is-danger': color === 'danger' || (invalid && !color),
131
133
  });
132
134
  const containerClass = usePrefixedClassNames('colorinput', {
133
135
  'has-trigger': triggerIcon,
@@ -1 +1 @@
1
- {"version":3,"file":"ColorInputBase.js","sources":["../../../src/form/ColorInputBase.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useFieldHelperClasses } from '../helpers/useFieldHelperClasses';\nimport { Icon } from '../elements/Icon';\nimport { ColorSwatch } from '../elements/ColorSwatch';\nimport {\n ColorPickerAlphaSlider,\n ColorPickerArea,\n ColorPickerHueSlider,\n ColorPickerSwatches,\n type ColorFormat,\n type ColorPickerLabels,\n type ColorPickerSwatch,\n} from './ColorPicker';\nimport { formatColor, parseColor } from './_colorInternals/colorMath';\nimport {\n BLACK,\n ColorPickerContext,\n keepingChannels,\n mergeColorLabels,\n useColorPicker,\n} from './_colorInternals/pickerState';\nimport { EyeDropperButton } from './_colorInternals/EyeDropperButton';\nimport { PickerPopover } from './_pickerInternals/PickerPopover';\nimport {\n isPopoverToggleKey,\n type PickerPosition,\n} from './_pickerInternals/pickerTypes';\nimport { usePickerLocaleScope } from './_pickerInternals/useLocaleDefaults';\nimport { useControlLoading } from './controlLoading';\nimport { useFieldLabelTarget, useFieldsetDisabled } from './FormContext';\n\n/**\n * Props for the raw ColorInput base. Use the higher-level `ColorInput` for\n * Field/Control composition; `ColorInputBase` is the field and its popover\n * only.\n *\n * @helperProps Helper props go on the `.colorinput` `<div>`, with\n * `className`, except that the background helpers go on the text `<input>`,\n * and the text helpers on both, since Bulma's `.input` sets its own\n * background and font, and the popover inside the `<div>` takes the text\n * ones. The other attributes go on the `<input>`.\n * @extraProp {string} [name] - Form field name. The field submits the text it shows, the value in `format`, or nothing when it's empty.\n * @extraProp {boolean} [required=false] - Marks the field required, so an empty one fails the form's constraint validation.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Forwarded to the text `<input>`.\n */\nexport interface ColorInputBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'size'\n | 'color'\n | 'type'\n | 'popover'\n >,\n Omit<BulmaClassesProps, 'color'> {\n /**\n * The color, controlled, as a CSS color the picker reads (hex, `rgb()`,\n * `hsl()` or a color name), or `''` for none.\n */\n value?: string;\n /** The color to start with, uncontrolled; empty without one. */\n defaultValue?: string;\n /**\n * Called with the color, in `format`, as it changes: on every step of a\n * drag in the panel, on a key or a swatch, and when typed text is\n * committed. Clearing the field calls it with `''`.\n */\n onChange?: (value: string) => void;\n /**\n * Called with the color, in `format`, once a change is done: when a drag\n * ends, and with `onChange` for everything else. The place to save it.\n */\n onChangeEnd?: (value: string) => void;\n /**\n * How the value is written: `'hsl'` (`hsl(171, 100%, 41%)`), `'hex'` or\n * `'rgb'`, with alpha as `hsla()`, `#rrggbbaa` and `rgba()`. Typed text in\n * any of them is written back in this one.\n * @defaultValue 'hsl'\n */\n format?: ColorFormat;\n /** Adds an alpha slider to the panel and writes the alpha into the value. */\n alpha?: boolean;\n /**\n * Preset colors in the panel: a list of CSS colors, each a string or\n * `{ color, label }`, or `\"bulma\"` for the page's theme colors.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n /**\n * Adds a button to the panel that picks a color from anywhere on the\n * screen, where the browser has the EyeDropper API.\n */\n eyeDropper?: boolean;\n /** Fired when the panel opens. */\n onOpen?: () => void;\n /** Fired when the panel closes. */\n onClose?: () => void;\n /**\n * Opens the panel when the field takes focus, and moves focus into it.\n * Off by default, since typing a value is the quick way in and the\n * launcher, a click on the swatch or Alt+ArrowDown open it.\n */\n openOnFocus?: boolean;\n /** Closes the panel once a swatch is chosen. */\n closeOnSwatchClick?: boolean;\n /**\n * Where the panel opens against the field. Left out, it opens below and\n * lines up with the field's start edge, which is its right edge when the\n * picker reads right to left. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges either way.\n * @defaultValue 'bottom-left'\n */\n position?: PickerPosition;\n /**\n * Renders the panel through a portal, into the `portalContainer` a\n * `ConfigProvider` sets, else the overlay it's in that takes its popups,\n * such as a `Modal`, else `document.body`.\n */\n appendToBody?: boolean;\n /** Bulma color modifier for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** The field's size. */\n size?: 'small' | 'medium' | 'large';\n /** Renders the field with rounded ends. */\n isRounded?: boolean;\n /** Disables the field and its panel. A disabled `Fieldset` does too. */\n disabled?: boolean;\n /** Makes the field read-only, with no panel. */\n readOnly?: boolean;\n /** Text shown while the field is empty. */\n placeholder?: string;\n /**\n * Shows the launcher on the field's end that toggles the panel. Hidden by\n * default while a `Control` it sits in shows its `isLoading` spinner,\n * which shares that edge.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** The launcher's glyph. */\n triggerIconName?: string;\n /** The strings it says, each with an English default. */\n labels?: ColorPickerLabels;\n}\n\n/**\n * The raw ColorInput: a text field with a swatch and a launcher that opens a color picker in a popover, without Field/Control wrapping.\n *\n * Use `ColorInput` for the convenience wrapper.\n *\n * @function\n * @param {ColorInputBaseProps} props - Props for ColorInputBase.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the text `<input>`.\n * @returns {JSX.Element} The rendered field.\n */\nexport const ColorInputBase = forwardRef<HTMLInputElement, ColorInputBaseProps>(\n (props, ref) => {\n const {\n value: controlledValue,\n defaultValue,\n onChange,\n onChangeEnd,\n format = 'hsl',\n alpha = false,\n swatches,\n eyeDropper = false,\n onOpen,\n onClose,\n openOnFocus = false,\n closeOnSwatchClick = false,\n position,\n appendToBody = false,\n color,\n size,\n isRounded,\n disabled: disabledProp,\n readOnly,\n placeholder,\n triggerIcon: triggerIconProp,\n triggerIconName = 'chevron-down',\n labels,\n className,\n id: idProp,\n onFocus,\n onBlur,\n onKeyDown,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n const id = useFieldLabelTarget(idProp, true);\n const localeScope = usePickerLocaleScope(undefined, props.dir);\n const controlLoading = useControlLoading();\n const triggerIcon = triggerIconProp ?? !controlLoading;\n const t = mergeColorLabels(labels);\n // The field takes the background and text helpers, since Bulma's `.input`\n // sets its own background and font. The container keeps the rest, and the\n // text helpers too where a popover inside it takes them.\n const {\n backgroundClasses,\n textClasses,\n otherClasses,\n rest: cleanRest,\n } = useFieldHelperClasses(rest);\n\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? '');\n const value = isControlled ? controlledValue : internalValue;\n // What's been typed and not yet committed, or null while the field\n // shows the value.\n const [draft, setDraft] = useState<string | null>(null);\n // The last color it held, which the panel shows while the field is\n // empty, so clearing the field doesn't send the picker back to black.\n const [remembered, setRemembered] = useState(value);\n if (value && value !== remembered) setRemembered(value);\n\n const [open, setOpenState] = useState(false);\n const canOpen = !disabled && !readOnly;\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n // Focus a closing panel hands back to the field opens nothing.\n const returningRef = useRef(false);\n const reactId = useId();\n const popoverId = id ? `${id}-popover` : `colorinput-${reactId}`;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (next === open) return;\n if (!next) returningRef.current = true;\n setOpenState(next);\n if (next) onOpen?.();\n else onClose?.();\n },\n [open, onOpen, onClose]\n );\n\n // Cleared once the close has handed focus back, or hasn't.\n useEffect(() => {\n if (!open) returningRef.current = false;\n }, [open]);\n\n const setValue = (next: string, end = true) => {\n if (!isControlled) setInternalValue(next);\n if (next !== value) onChange?.(next);\n if (end) onChangeEnd?.(next);\n };\n\n // The picker in the panel, controlled by this field's value.\n const picker = useColorPicker({\n value: value || remembered || formatColor(BLACK, format, alpha),\n defaultValue: undefined,\n onChange: next => setValue(next, false),\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n // Empty, the panel shows the last color the field held, or black, and\n // choosing that same color still fills the field.\n empty: value === '',\n });\n\n const commit = () => {\n if (draft === null) return;\n const typed = draft.trim();\n setDraft(null);\n if (typed === '') {\n if (value !== '') setValue('');\n return;\n }\n const parsed = parseColor(typed);\n if (!parsed) return;\n // A gray typed as hex, rgb() or a name keeps the panel's hue, as the\n // picker's own field does; one typed as hsl() names its own.\n const kept = keepingChannels(parsed, picker.color, typed);\n setValue(formatColor(alpha ? kept : { ...kept, a: 1 }, format, alpha));\n };\n const invalid = draft !== null && draft.trim() !== '' && !parseColor(draft);\n // The value as the field writes it: in `format`, however it was given.\n const parsedValue = parseColor(value);\n const valueText = parsedValue\n ? formatColor(\n alpha ? parsedValue : { ...parsedValue, a: 1 },\n format,\n alpha\n )\n : value;\n // What the swatch shows: a readable draft as it's typed, else the value.\n const shown = draft !== null && !invalid ? draft.trim() : value;\n\n const inputClass = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': !!isRounded,\n 'is-danger': invalid && !color,\n });\n const containerClass = usePrefixedClassNames('colorinput', {\n 'has-trigger': triggerIcon,\n });\n const swatchClass = usePrefixedClassNames('colorinput-swatch');\n const triggerClass = usePrefixedClassNames('colorinput-trigger');\n const panelClass = usePrefixedClassNames('color-picker');\n const eyeDropperClass = usePrefixedClassNames('colorinput-eyedropper');\n\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref]\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (isPopoverToggleKey(event) && event.key === 'ArrowDown') {\n event.preventDefault();\n if (canOpen) setOpen(true);\n } else if (draft !== null && event.key === 'Enter') {\n // Commits rather than submitting a form; an unreadable value stays\n // to be fixed.\n event.preventDefault();\n if (!invalid) commit();\n } else if (draft !== null && event.key === 'Escape') {\n // Puts the value back, and keeps a Modal around it open.\n event.preventDefault();\n event.stopPropagation();\n setDraft(null);\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n const returning = returningRef.current;\n returningRef.current = false;\n if (openOnFocus && canOpen && !returning) setOpen(true);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n onBlur?.(event);\n commit();\n };\n\n const popupAttrs = {\n 'aria-haspopup': 'dialog',\n 'aria-controls': popoverId,\n 'aria-expanded': open,\n } as const;\n\n return (\n <div\n ref={containerRef}\n className={classNames(\n containerClass,\n otherClasses,\n textClasses,\n className\n )}\n {...localeScope.rootAttrs}\n >\n <input\n {...cleanRest}\n ref={combinedRef}\n type=\"text\"\n role=\"combobox\"\n {...popupAttrs}\n autoComplete=\"off\"\n spellCheck={false}\n autoCapitalize=\"off\"\n className={classNames(inputClass, textClasses, backgroundClasses)}\n value={draft ?? valueText}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={invalid || cleanRest['aria-invalid'] || undefined}\n id={id}\n onChange={event => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n {/* For the pointer: the launcher does the same from the keyboard. */}\n <button\n type=\"button\"\n className={swatchClass}\n tabIndex={-1}\n aria-hidden=\"true\"\n disabled={!canOpen}\n onMouseDown={event => event.preventDefault()}\n onClick={() => setOpen(true)}\n >\n <ColorSwatch color={shown || 'transparent'} aria-hidden=\"true\" />\n </button>\n {triggerIcon && (\n <button\n type=\"button\"\n className={triggerClass}\n {...popupAttrs}\n aria-label={t.chooseColor}\n disabled={!canOpen}\n onClick={() => setOpen(!open)}\n >\n <Icon name={triggerIconName} size={size} />\n </button>\n )}\n <PickerPopover\n localeScope={localeScope.panel}\n isOpen={open}\n onClose={() => setOpen(false)}\n anchorRef={containerRef}\n position={position}\n appendToBody={appendToBody}\n ariaLabel={t.chooseColor}\n id={popoverId}\n restoreFocusRef={inputRef}\n >\n <ColorPickerContext.Provider value={picker}>\n <div className={panelClass}>\n <ColorPickerArea />\n <ColorPickerHueSlider />\n {alpha && <ColorPickerAlphaSlider />}\n {swatches && (\n <ColorPickerSwatches\n // A click on a swatch, or Enter or Space on one, closes\n // the panel when asked to; the arrows only choose.\n onClick={event => {\n const target = event.target as Element;\n if (\n closeOnSwatchClick &&\n target.closest('[role=\"radio\"]')\n ) {\n setOpen(false);\n }\n }}\n />\n )}\n <EyeDropperButton className={eyeDropperClass} />\n </div>\n </ColorPickerContext.Provider>\n </PickerPopover>\n </div>\n );\n }\n);\n\nColorInputBase.displayName = 'ColorInputBase';\n\nexport default ColorInputBase;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"ColorInputBase.js","sources":["../../../src/form/ColorInputBase.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useFieldHelperClasses } from '../helpers/useFieldHelperClasses';\nimport { Icon } from '../elements/Icon';\nimport { ColorSwatch } from '../elements/ColorSwatch';\nimport {\n ColorPickerAlphaSlider,\n ColorPickerArea,\n ColorPickerHueSlider,\n ColorPickerSwatches,\n type ColorFormat,\n type ColorPickerLabels,\n type ColorPickerSwatch,\n} from './ColorPicker';\nimport { formatColor, parseColor } from './_colorInternals/colorMath';\nimport {\n BLACK,\n ColorPickerContext,\n keepingChannels,\n mergeColorLabels,\n useColorPicker,\n} from './_colorInternals/pickerState';\nimport { EyeDropperButton } from './_colorInternals/EyeDropperButton';\nimport { PickerPopover } from './_pickerInternals/PickerPopover';\nimport {\n isPopoverToggleKey,\n type PickerPosition,\n} from './_pickerInternals/pickerTypes';\nimport { usePickerLocaleScope } from './_pickerInternals/useLocaleDefaults';\nimport { useControlLoading } from './controlLoading';\nimport { useFieldLabelTarget, useFieldsetDisabled } from './FormContext';\n\n/**\n * Props for the raw ColorInput base. Use the higher-level `ColorInput` for\n * Field/Control composition; `ColorInputBase` is the field and its popover\n * only.\n *\n * @helperProps Helper props go on the `.colorinput` `<div>`, with\n * `className`, except that the background helpers go on the text `<input>`,\n * and the text helpers on both, since Bulma's `.input` sets its own\n * background and font, and the popover inside the `<div>` takes the text\n * ones. The other attributes go on the `<input>`.\n * @extraProp {string} [name] - Form field name. The field submits the text it shows, the value in `format`, or nothing when it's empty.\n * @extraProp {boolean} [required=false] - Marks the field required, so an empty one fails the form's constraint validation.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Forwarded to the text `<input>`.\n */\nexport interface ColorInputBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'size'\n | 'color'\n | 'type'\n | 'popover'\n >,\n Omit<BulmaClassesProps, 'color'> {\n /**\n * The color, controlled, as a CSS color the picker reads (hex, `rgb()`,\n * `hsl()` or a color name), or `''` for none.\n */\n value?: string;\n /** The color to start with, uncontrolled; empty without one. */\n defaultValue?: string;\n /**\n * Called with the color, in `format`, as it changes: on every step of a\n * drag in the panel, on a key or a swatch, and when typed text is\n * committed. Clearing the field calls it with `''`.\n */\n onChange?: (value: string) => void;\n /**\n * Called with the color, in `format`, once a change is done: when a drag\n * ends, and with `onChange` for everything else. The place to save it.\n */\n onChangeEnd?: (value: string) => void;\n /**\n * How the value is written: `'hsl'` (`hsl(171, 100%, 41%)`), `'hex'` or\n * `'rgb'`, with alpha as `hsla()`, `#rrggbbaa` and `rgba()`. Typed text in\n * any of them is written back in this one.\n * @defaultValue 'hsl'\n */\n format?: ColorFormat;\n /** Adds an alpha slider to the panel and writes the alpha into the value. */\n alpha?: boolean;\n /**\n * Preset colors in the panel: a list of CSS colors, each a string or\n * `{ color, label }`, or `\"bulma\"` for the page's theme colors.\n */\n swatches?: ColorPickerSwatch[] | 'bulma';\n /**\n * Adds a button to the panel that picks a color from anywhere on the\n * screen, where the browser has the EyeDropper API.\n */\n eyeDropper?: boolean;\n /** Fired when the panel opens. */\n onOpen?: () => void;\n /** Fired when the panel closes. */\n onClose?: () => void;\n /**\n * Opens the panel when the field takes focus, and moves focus into it.\n * Off by default, since typing a value is the quick way in and the\n * launcher, a click on the swatch or Alt+ArrowDown open it.\n */\n openOnFocus?: boolean;\n /** Closes the panel once a swatch is chosen. */\n closeOnSwatchClick?: boolean;\n /**\n * Where the panel opens against the field. Left out, it opens below and\n * lines up with the field's start edge, which is its right edge when the\n * picker reads right to left. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges either way.\n * @defaultValue 'bottom-left'\n */\n position?: PickerPosition;\n /**\n * Renders the panel through a portal, into the `portalContainer` a\n * `ConfigProvider` sets, else the overlay it's in that takes its popups,\n * such as a `Modal`, else `document.body`.\n */\n appendToBody?: boolean;\n /** Bulma color modifier for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** The field's size. */\n size?: 'small' | 'medium' | 'large';\n /** Renders the field with rounded ends. */\n isRounded?: boolean;\n /** Disables the field and its panel. A disabled `Fieldset` does too. */\n disabled?: boolean;\n /** Makes the field read-only, with no panel. */\n readOnly?: boolean;\n /** Text shown while the field is empty. */\n placeholder?: string;\n /**\n * Shows the launcher on the field's end that toggles the panel. Hidden by\n * default while a `Control` it sits in shows its `isLoading` spinner,\n * which shares that edge.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** The launcher's glyph. */\n triggerIconName?: string;\n /** The strings it says, each with an English default. */\n labels?: ColorPickerLabels;\n}\n\n/**\n * The raw ColorInput: a text field with a swatch and a launcher that opens a color picker in a popover, without Field/Control wrapping.\n *\n * Use `ColorInput` for the convenience wrapper.\n *\n * @function\n * @param {ColorInputBaseProps} props - Props for ColorInputBase.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the text `<input>`.\n * @returns {JSX.Element} The rendered field.\n */\nexport const ColorInputBase = forwardRef<HTMLInputElement, ColorInputBaseProps>(\n (props, ref) => {\n const {\n value: controlledValue,\n defaultValue,\n onChange,\n onChangeEnd,\n format = 'hsl',\n alpha = false,\n swatches,\n eyeDropper = false,\n onOpen,\n onClose,\n openOnFocus = false,\n closeOnSwatchClick = false,\n position,\n appendToBody = false,\n color,\n size,\n isRounded,\n disabled: disabledProp,\n readOnly,\n placeholder,\n triggerIcon: triggerIconProp,\n triggerIconName = 'chevron-down',\n labels,\n className,\n id: idProp,\n onFocus,\n onBlur,\n onKeyDown,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n const id = useFieldLabelTarget(idProp, true);\n const localeScope = usePickerLocaleScope(undefined, props.dir);\n const controlLoading = useControlLoading();\n const triggerIcon = triggerIconProp ?? !controlLoading;\n const t = mergeColorLabels(labels);\n // The field takes the background and text helpers, since Bulma's `.input`\n // sets its own background and font. The container keeps the rest, and the\n // text helpers too where a popover inside it takes them.\n const {\n backgroundClasses,\n textClasses,\n otherClasses,\n rest: cleanRest,\n } = useFieldHelperClasses(rest);\n\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? '');\n const value = isControlled ? controlledValue : internalValue;\n // What's been typed and not yet committed, or null while the field\n // shows the value.\n const [draft, setDraft] = useState<string | null>(null);\n // The last color it held, which the panel shows while the field is\n // empty, so clearing the field doesn't send the picker back to black.\n const [remembered, setRemembered] = useState(value);\n if (value && value !== remembered) setRemembered(value);\n\n const [open, setOpenState] = useState(false);\n const canOpen = !disabled && !readOnly;\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n // Focus a closing panel hands back to the field opens nothing.\n const returningRef = useRef(false);\n const reactId = useId();\n const popoverId = id ? `${id}-popover` : `colorinput-${reactId}`;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (next === open) return;\n if (!next) returningRef.current = true;\n setOpenState(next);\n if (next) onOpen?.();\n else onClose?.();\n },\n [open, onOpen, onClose]\n );\n\n // Cleared once the close has handed focus back, or hasn't.\n useEffect(() => {\n if (!open) returningRef.current = false;\n }, [open]);\n\n const setValue = (next: string, end = true) => {\n if (!isControlled) setInternalValue(next);\n if (next !== value) onChange?.(next);\n if (end) onChangeEnd?.(next);\n };\n\n // The picker in the panel, controlled by this field's value.\n const picker = useColorPicker({\n value: value || remembered || formatColor(BLACK, format, alpha),\n defaultValue: undefined,\n onChange: next => setValue(next, false),\n onChangeEnd,\n format,\n alpha,\n disabled,\n swatches,\n eyeDropper,\n labels,\n // Empty, the panel shows the last color the field held, or black, and\n // choosing that same color still fills the field.\n empty: value === '',\n });\n\n const commit = () => {\n if (draft === null) return;\n const typed = draft.trim();\n setDraft(null);\n if (typed === '') {\n if (value !== '') setValue('');\n return;\n }\n const parsed = parseColor(typed);\n if (!parsed) return;\n // A gray typed as hex, rgb() or a name keeps the panel's hue, as the\n // picker's own field does; one typed as hsl() names its own.\n const kept = keepingChannels(parsed, picker.color, typed);\n setValue(formatColor(alpha ? kept : { ...kept, a: 1 }, format, alpha));\n };\n const invalid = draft !== null && draft.trim() !== '' && !parseColor(draft);\n // The value as the field writes it: in `format`, however it was given.\n const parsedValue = parseColor(value);\n const valueText = parsedValue\n ? formatColor(\n alpha ? parsedValue : { ...parsedValue, a: 1 },\n format,\n alpha\n )\n : value;\n // What the swatch shows: a readable draft as it's typed, else the value.\n const shown = draft !== null && !invalid ? draft.trim() : value;\n\n const inputClass = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': !!isRounded,\n // The danger color's own class is this key too, and this one comes\n // later, so it has to set the class for `danger` as well or it erases it.\n 'is-danger': color === 'danger' || (invalid && !color),\n });\n const containerClass = usePrefixedClassNames('colorinput', {\n 'has-trigger': triggerIcon,\n });\n const swatchClass = usePrefixedClassNames('colorinput-swatch');\n const triggerClass = usePrefixedClassNames('colorinput-trigger');\n const panelClass = usePrefixedClassNames('color-picker');\n const eyeDropperClass = usePrefixedClassNames('colorinput-eyedropper');\n\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref]\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (isPopoverToggleKey(event) && event.key === 'ArrowDown') {\n event.preventDefault();\n if (canOpen) setOpen(true);\n } else if (draft !== null && event.key === 'Enter') {\n // Commits rather than submitting a form; an unreadable value stays\n // to be fixed.\n event.preventDefault();\n if (!invalid) commit();\n } else if (draft !== null && event.key === 'Escape') {\n // Puts the value back, and keeps a Modal around it open.\n event.preventDefault();\n event.stopPropagation();\n setDraft(null);\n }\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n onFocus?.(event);\n const returning = returningRef.current;\n returningRef.current = false;\n if (openOnFocus && canOpen && !returning) setOpen(true);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n onBlur?.(event);\n commit();\n };\n\n const popupAttrs = {\n 'aria-haspopup': 'dialog',\n 'aria-controls': popoverId,\n 'aria-expanded': open,\n } as const;\n\n return (\n <div\n ref={containerRef}\n className={classNames(\n containerClass,\n otherClasses,\n textClasses,\n className\n )}\n {...localeScope.rootAttrs}\n >\n <input\n {...cleanRest}\n ref={combinedRef}\n type=\"text\"\n role=\"combobox\"\n {...popupAttrs}\n autoComplete=\"off\"\n spellCheck={false}\n autoCapitalize=\"off\"\n className={classNames(inputClass, textClasses, backgroundClasses)}\n value={draft ?? valueText}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n aria-invalid={invalid || cleanRest['aria-invalid'] || undefined}\n id={id}\n onChange={event => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n />\n {/* For the pointer: the launcher does the same from the keyboard. */}\n <button\n type=\"button\"\n className={swatchClass}\n tabIndex={-1}\n aria-hidden=\"true\"\n disabled={!canOpen}\n onMouseDown={event => event.preventDefault()}\n onClick={() => setOpen(true)}\n >\n <ColorSwatch color={shown || 'transparent'} aria-hidden=\"true\" />\n </button>\n {triggerIcon && (\n <button\n type=\"button\"\n className={triggerClass}\n {...popupAttrs}\n aria-label={t.chooseColor}\n disabled={!canOpen}\n onClick={() => setOpen(!open)}\n >\n <Icon name={triggerIconName} size={size} />\n </button>\n )}\n <PickerPopover\n localeScope={localeScope.panel}\n isOpen={open}\n onClose={() => setOpen(false)}\n anchorRef={containerRef}\n position={position}\n appendToBody={appendToBody}\n ariaLabel={t.chooseColor}\n id={popoverId}\n restoreFocusRef={inputRef}\n >\n <ColorPickerContext.Provider value={picker}>\n <div className={panelClass}>\n <ColorPickerArea />\n <ColorPickerHueSlider />\n {alpha && <ColorPickerAlphaSlider />}\n {swatches && (\n <ColorPickerSwatches\n // A click on a swatch, or Enter or Space on one, closes\n // the panel when asked to; the arrows only choose.\n onClick={event => {\n const target = event.target as Element;\n if (\n closeOnSwatchClick &&\n target.closest('[role=\"radio\"]')\n ) {\n setOpen(false);\n }\n }}\n />\n )}\n <EyeDropperButton className={eyeDropperClass} />\n </div>\n </ColorPickerContext.Provider>\n </PickerPopover>\n </div>\n );\n }\n);\n\nColorInputBase.displayName = 'ColorInputBase';\n\nexport default ColorInputBase;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}