@allxsmith/bestax-bulma 5.54.1 → 5.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Command.js +22 -22
  4. package/dist/esm/components/Command.js.map +1 -1
  5. package/dist/esm/components/DataTable.js +215 -0
  6. package/dist/esm/components/DataTable.js.map +1 -0
  7. package/dist/esm/components/useDataTable.js +509 -0
  8. package/dist/esm/components/useDataTable.js.map +1 -0
  9. package/dist/esm/elements/ColorSwatch.js +49 -0
  10. package/dist/esm/elements/ColorSwatch.js.map +1 -0
  11. package/dist/esm/elements/RingProgress.js +3 -3
  12. package/dist/esm/elements/Td.js +4 -2
  13. package/dist/esm/elements/Td.js.map +1 -1
  14. package/dist/esm/elements/Th.js +13 -5
  15. package/dist/esm/elements/Th.js.map +1 -1
  16. package/dist/esm/elements/Tr.js.map +1 -1
  17. package/dist/esm/form/ColorInput.js +68 -0
  18. package/dist/esm/form/ColorInput.js.map +1 -0
  19. package/dist/esm/form/ColorInputBase.js +198 -0
  20. package/dist/esm/form/ColorInputBase.js.map +1 -0
  21. package/dist/esm/form/ColorPicker.js +524 -0
  22. package/dist/esm/form/ColorPicker.js.map +1 -0
  23. package/dist/esm/form/Combobox.js +18 -18
  24. package/dist/esm/form/Combobox.js.map +1 -1
  25. package/dist/esm/form/Dropzone.js +524 -0
  26. package/dist/esm/form/Dropzone.js.map +1 -0
  27. package/dist/esm/form/_colorInternals/EyeDropperButton.js +40 -0
  28. package/dist/esm/form/_colorInternals/EyeDropperButton.js.map +1 -0
  29. package/dist/esm/form/_colorInternals/colorMath.js +292 -0
  30. package/dist/esm/form/_colorInternals/colorMath.js.map +1 -0
  31. package/dist/esm/form/_colorInternals/pickerState.js +160 -0
  32. package/dist/esm/form/_colorInternals/pickerState.js.map +1 -0
  33. package/dist/esm/helpers/statusRegion.js +3 -3
  34. package/dist/esm/helpers/statusRegion.js.map +1 -1
  35. package/dist/esm/helpers/useFocusTrap.js +2 -2
  36. package/dist/extras.css +1 -1
  37. package/dist/extras.css.map +1 -1
  38. package/dist/index.cjs +3054 -586
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.esm.js +7 -0
  41. package/dist/index.esm.js.map +1 -1
  42. package/dist/types/components/DataTable.d.ts +120 -0
  43. package/dist/types/components/useDataTable.d.ts +481 -0
  44. package/dist/types/elements/ColorSwatch.d.ts +54 -0
  45. package/dist/types/elements/Td.d.ts +9 -1
  46. package/dist/types/elements/Th.d.ts +14 -2
  47. package/dist/types/elements/Tr.d.ts +10 -1
  48. package/dist/types/form/ColorInput.d.ts +76 -0
  49. package/dist/types/form/ColorInputBase.d.ts +108 -0
  50. package/dist/types/form/ColorPicker.d.ts +271 -0
  51. package/dist/types/form/Dropzone.d.ts +138 -0
  52. package/dist/types/form/_colorInternals/EyeDropperButton.d.ts +8 -0
  53. package/dist/types/form/_colorInternals/colorMath.d.ts +63 -0
  54. package/dist/types/form/_colorInternals/pickerState.d.ts +68 -0
  55. package/dist/types/index.d.ts +8 -0
  56. package/dist/types-cjs/components/DataTable.d.ts +120 -0
  57. package/dist/types-cjs/components/useDataTable.d.ts +481 -0
  58. package/dist/types-cjs/elements/ColorSwatch.d.ts +54 -0
  59. package/dist/types-cjs/elements/Td.d.ts +9 -1
  60. package/dist/types-cjs/elements/Th.d.ts +14 -2
  61. package/dist/types-cjs/elements/Tr.d.ts +10 -1
  62. package/dist/types-cjs/form/ColorInput.d.ts +76 -0
  63. package/dist/types-cjs/form/ColorInputBase.d.ts +108 -0
  64. package/dist/types-cjs/form/ColorPicker.d.ts +271 -0
  65. package/dist/types-cjs/form/Dropzone.d.ts +138 -0
  66. package/dist/types-cjs/form/_colorInternals/EyeDropperButton.d.ts +8 -0
  67. package/dist/types-cjs/form/_colorInternals/colorMath.d.ts +63 -0
  68. package/dist/types-cjs/form/_colorInternals/pickerState.d.ts +68 -0
  69. package/dist/types-cjs/index.d.ts +8 -0
  70. package/dist/versions/bestax-no-dark-mode.css +1 -1
  71. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  72. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  73. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  74. package/dist/versions/bestax-no-helpers.css +1 -1
  75. package/dist/versions/bestax-no-helpers.css.map +1 -1
  76. package/dist/versions/bestax-prefixed.css +1 -1
  77. package/dist/versions/bestax-prefixed.css.map +1 -1
  78. package/package.json +1 -1
  79. package/src/scss/components/_datatable.scss +152 -0
  80. package/src/scss/components/_index.scss +1 -0
  81. package/src/scss/elements/_colorswatch.scss +100 -0
  82. package/src/scss/elements/_index.scss +1 -0
  83. package/src/scss/form/_checkbox.scss +53 -0
  84. package/src/scss/form/_colorinput.scss +109 -0
  85. package/src/scss/form/_colorpicker.scss +354 -0
  86. package/src/scss/form/_dropzone.scss +233 -0
  87. package/src/scss/form/_index.scss +3 -0
@@ -0,0 +1,49 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useEffect } from 'react';
4
+ import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
+ import { warnOnce } from '../helpers/devWarnings.js';
7
+
8
+ const validColorSwatchSizes = ['small', 'medium', 'large'];
9
+ /**
10
+ * The `ColorSwatch` component shows a color as a small chip, named by its label or by the color itself.
11
+ *
12
+ * It's an image to assistive tech, so the color is always there in words.
13
+ * In forced colors it keeps its color, edged in the system's text color.
14
+ *
15
+ * @function
16
+ * @param {ColorSwatchProps} props - Props for the ColorSwatch component.
17
+ * @param {React.Ref<HTMLSpanElement>} ref - Forwarded ref to the `<span>`.
18
+ * @returns {JSX.Element} The rendered swatch.
19
+ *
20
+ * @example
21
+ * <ColorSwatch color="#1e6b99" label="Brand blue" />
22
+ */
23
+ const ColorSwatch = forwardRef(({ className, textColor, color, label, size, isRounded, children, style, ...props }, ref) => {
24
+ const { bulmaHelperClasses, rest } = useBulmaClasses({
25
+ color: textColor,
26
+ ...props,
27
+ });
28
+ const unnamed = /^\s*var\(/i.test(color) &&
29
+ !label &&
30
+ !rest['aria-label'] &&
31
+ !rest['aria-labelledby'] &&
32
+ !rest['aria-hidden'];
33
+ useEffect(() => {
34
+ if (unnamed) {
35
+ warnOnce('ColorSwatch:unnamed-var', '[bestax-bulma] <ColorSwatch> shows a CSS variable with no label, ' +
36
+ 'so a screen reader reads the var() as its name. Pass label, ' +
37
+ 'such as "Primary".');
38
+ }
39
+ }, [unnamed]);
40
+ const swatchClass = usePrefixedClassNames('color-swatch', {
41
+ [`is-${size}`]: !!size && validColorSwatchSizes.includes(size),
42
+ 'is-rounded': !!isRounded,
43
+ });
44
+ return (jsx("span", { ref: ref, className: classNames(swatchClass, bulmaHelperClasses, className), style: { ...style, ['--color-swatch-color']: color }, ...rest, role: "img", "aria-label": rest['aria-label'] || label || color, children: children !== undefined && children !== null && (jsx("span", { "aria-hidden": "true", children: children })) }));
45
+ });
46
+ ColorSwatch.displayName = 'ColorSwatch';
47
+
48
+ export { ColorSwatch };
49
+ //# sourceMappingURL=ColorSwatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorSwatch.js","sources":["../../../src/elements/ColorSwatch.tsx"],"sourcesContent":["import React, { forwardRef, useEffect } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\n\nconst validColorSwatchSizes = ['small', 'medium', 'large'] as const;\n\n/**\n * Props for the ColorSwatch component. The helper props, the other\n * attributes and the `ref` land on its `<span>`.\n *\n * @extraProp {React.Ref<HTMLSpanElement>} [ref] - Ref forwarded to the `<span>`.\n * @extraProp {string} [aria-label] - Names the swatch in place of `label`.\n * @extraProp {boolean} [aria-hidden] - Hides the swatch from assistive tech, for one beside text that already names the color.\n */\nexport interface ColorSwatchProps\n extends\n Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'role'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * The color it shows: any CSS color, such as `#1e6b99`,\n * `hsl(202, 67%, 36%)` or `var(--bulma-primary)`. A see-through color\n * shows a checkerboard behind it.\n */\n color: string;\n /**\n * What the color is called, such as \"Brand blue\", read as the swatch's\n * name in place of `color` as written. A `var()` reads as nothing useful,\n * so a development build warns when one has no name.\n */\n label?: string;\n /** The swatch's size. */\n size?: (typeof validColorSwatchSizes)[number];\n /** Draws a circle in place of a rounded square. */\n isRounded?: boolean;\n /**\n * Drawn on the swatch, such as an icon. It's hidden from assistive tech,\n * since the swatch is an image named by its label.\n */\n children?: React.ReactNode;\n /** Text color helper, the color of anything drawn on the swatch. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n}\n\n/**\n * The `ColorSwatch` component shows a color as a small chip, named by its label or by the color itself.\n *\n * It's an image to assistive tech, so the color is always there in words.\n * In forced colors it keeps its color, edged in the system's text color.\n *\n * @function\n * @param {ColorSwatchProps} props - Props for the ColorSwatch component.\n * @param {React.Ref<HTMLSpanElement>} ref - Forwarded ref to the `<span>`.\n * @returns {JSX.Element} The rendered swatch.\n *\n * @example\n * <ColorSwatch color=\"#1e6b99\" label=\"Brand blue\" />\n */\nexport const ColorSwatch = forwardRef<HTMLSpanElement, ColorSwatchProps>(\n (\n {\n className,\n textColor,\n color,\n label,\n size,\n isRounded,\n children,\n style,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n const unnamed =\n /^\\s*var\\(/i.test(color) &&\n !label &&\n !rest['aria-label'] &&\n !rest['aria-labelledby'] &&\n !rest['aria-hidden'];\n useEffect(() => {\n if (unnamed) {\n warnOnce(\n 'ColorSwatch:unnamed-var',\n '[bestax-bulma] <ColorSwatch> shows a CSS variable with no label, ' +\n 'so a screen reader reads the var() as its name. Pass label, ' +\n 'such as \"Primary\".'\n );\n }\n }, [unnamed]);\n\n const swatchClass = usePrefixedClassNames('color-swatch', {\n [`is-${size}`]:\n !!size && (validColorSwatchSizes as readonly string[]).includes(size),\n 'is-rounded': !!isRounded,\n });\n\n return (\n <span\n ref={ref}\n className={classNames(swatchClass, bulmaHelperClasses, className)}\n style={{ ...style, ['--color-swatch-color' as string]: color }}\n {...rest}\n role=\"img\"\n aria-label={rest['aria-label'] || label || color}\n >\n {children !== undefined && children !== null && (\n <span aria-hidden=\"true\">{children}</span>\n )}\n </span>\n );\n }\n);\n\nColorSwatch.displayName = 'ColorSwatch';\n\nexport default ColorSwatch;\n"],"names":["_jsx"],"mappings":";;;;;;;AASA,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAU;AAyCnE;;;;;;;;;;;;;AAaG;AACI,MAAM,WAAW,GAAG,UAAU,CACnC,CACE,EACE,SAAS,EACT,SAAS,EACT,KAAK,EACL,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACT,EACD,GAAG,KACD;AACF,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;AAEF,IAAA,MAAM,OAAO,GACX,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;AACxB,QAAA,CAAC,KAAK;QACN,CAAC,IAAI,CAAC,YAAY,CAAC;QACnB,CAAC,IAAI,CAAC,iBAAiB,CAAC;AACxB,QAAA,CAAC,IAAI,CAAC,aAAa,CAAC;IACtB,SAAS,CAAC,MAAK;QACb,IAAI,OAAO,EAAE;YACX,QAAQ,CACN,yBAAyB,EACzB,mEAAmE;gBACjE,8DAA8D;AAC9D,gBAAA,oBAAoB,CACvB;QACH;AACF,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAEb,IAAA,MAAM,WAAW,GAAG,qBAAqB,CAAC,cAAc,EAAE;AACxD,QAAA,CAAC,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,GACX,CAAC,CAAC,IAAI,IAAK,qBAA2C,CAAC,QAAQ,CAAC,IAAI,CAAC;QACvE,YAAY,EAAE,CAAC,CAAC,SAAS;AAC1B,KAAA,CAAC;AAEF,IAAA,QACEA,GAAA,CAAA,MAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,kBAAkB,EAAE,SAAS,CAAC,EACjE,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,sBAAgC,GAAG,KAAK,EAAE,EAAA,GAC1D,IAAI,EACR,IAAI,EAAC,KAAK,EAAA,YAAA,EACE,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,IAAI,KAAK,EAAA,QAAA,EAE/C,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,KAC1CA,GAAA,CAAA,MAAA,EAAA,EAAA,aAAA,EAAkB,MAAM,EAAA,QAAA,EAAE,QAAQ,EAAA,CAAQ,CAC3C,EAAA,CACI;AAEX,CAAC;AAGH,WAAW,CAAC,WAAW,GAAG,aAAa;;"}
@@ -20,7 +20,7 @@ const validRingProgressColors = [
20
20
  'white',
21
21
  ];
22
22
  const validRingProgressSizes = ['small', 'medium', 'large'];
23
- const clamp$2 = (value, low, high) => Math.min(Math.max(value, low), high);
23
+ const clamp$4 = (value, low, high) => Math.min(Math.max(value, low), high);
24
24
  /**
25
25
  * The `RingProgress` component draws a value as a ring that fills as it grows, with anything you pass shown in the middle.
26
26
  *
@@ -58,7 +58,7 @@ const RingProgress = forwardRef(({ className, textColor, bgColor, value, max = 1
58
58
  }
59
59
  }, [named, mixed]);
60
60
  const total = max > 0 ? max : 100;
61
- const share = (part) => (clamp$2(part, 0, total) / total) * 100;
61
+ const share = (part) => (clamp$4(part, 0, total) / total) * 100;
62
62
  // Each arc starts where the one before ended, and the last stops at the
63
63
  // top, so a total over max fills the ring and no more.
64
64
  const arcs = [];
@@ -104,7 +104,7 @@ const RingProgress = forwardRef(({ className, textColor, bgColor, value, max = 1
104
104
  }
105
105
  : {
106
106
  role: isMeter ? 'meter' : 'progressbar',
107
- 'aria-valuenow': clamp$2(value ?? 0, 0, total),
107
+ 'aria-valuenow': clamp$4(value ?? 0, 0, total),
108
108
  'aria-valuemin': 0,
109
109
  'aria-valuemax': total,
110
110
  'aria-label': label || rest['aria-label'],
@@ -39,17 +39,19 @@ const validTableColors = [
39
39
  /**
40
40
  * Td component for rendering a styled Bulma table cell.
41
41
  *
42
- * Supports alignment, Bulma color modifiers, and helper classes for additional styling.
42
+ * Supports alignment, narrow and vertically centered cells, Bulma color modifiers, and helper classes for additional styling.
43
43
  *
44
44
  * @function
45
45
  * @param {TdProps} props - Props for the Td component.
46
46
  * @returns {JSX.Element} The rendered table cell element.
47
47
  * @see {@link https://bulma.io/documentation/elements/table/#table-body | Bulma Table documentation}
48
48
  */
49
- const Td = ({ className, isAligned, color, children, ...props }) => {
49
+ const Td = ({ className, isAligned, isNarrow, isVcentered, color, children, ...props }) => {
50
50
  const bulmaClasses = usePrefixedClassNames('', {
51
51
  [`has-text-${isAligned}`]: isAligned && validTableAlignments.includes(isAligned),
52
52
  [`is-${color}`]: color && validTableColors.includes(color),
53
+ 'is-narrow': isNarrow,
54
+ 'is-vcentered': isVcentered,
53
55
  });
54
56
  /**
55
57
  * Generates Bulma helper classes and separates out remaining props.
@@ -1 +1 @@
1
- {"version":3,"file":"Td.js","sources":["../../../src/elements/Td.tsx"],"sourcesContent":["/**\n * @group Table\n */\nimport React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { TableAlignment, validTableAlignments } from './tableAlignment';\n\n/**\n * The values the table `color` prop accepts, as a readonly tuple.\n *\n * `TableColor` is typed from it, and `Tr`, `Th` and `Td` all take a\n * `TableColor`, so the tuple and those props list the same values. Map over\n * it to build a color picker, or check a value that arrives at runtime before\n * passing it in: the components add no color class for a value outside the\n * tuple.\n *\n * @example\n * import { Tr, Td, validTableColors } from '@allxsmith/bestax-bulma';\n *\n * <Tr>\n * {validTableColors.map(color => (\n * <Td key={color} color={color}>\n * {color}\n * </Td>\n * ))}\n * </Tr>;\n */\nexport const validTableColors = [\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 * The color values `Tr`, `Th` and `Td` accept, typed from `validTableColors`.\n */\nexport type TableColor = (typeof validTableColors)[number];\n\n/**\n * Props for the Td component.\n */\nexport interface TdProps\n extends\n Omit<React.TdHTMLAttributes<HTMLTableCellElement>, 'color'>,\n Omit<BulmaClassesProps, 'backgroundColor' | 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text alignment for the table cell ('left', 'right', 'centered'). */\n isAligned?: TableAlignment;\n /** Bulma color modifier for the table cell. */\n color?: TableColor;\n /** Table cell content. */\n children?: React.ReactNode;\n}\n\n/**\n * Td component for rendering a styled Bulma table cell.\n *\n * Supports alignment, Bulma color modifiers, and helper classes for additional styling.\n *\n * @function\n * @param {TdProps} props - Props for the Td component.\n * @returns {JSX.Element} The rendered table cell element.\n * @see {@link https://bulma.io/documentation/elements/table/#table-body | Bulma Table documentation}\n */\nexport const Td: React.FC<TdProps> = ({\n className,\n isAligned,\n color,\n children,\n ...props\n}) => {\n const bulmaClasses = usePrefixedClassNames('', {\n [`has-text-${isAligned}`]:\n isAligned && validTableAlignments.includes(isAligned),\n [`is-${color}`]: color && validTableColors.includes(color),\n });\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const tdClasses = classNames(bulmaClasses, className, bulmaHelperClasses);\n\n return (\n <td className={tdClasses || undefined} {...rest}>\n {children}\n </td>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;AAQA;;;;;;;;;;;;;;;;;;;AAmBG;AACI,MAAM,gBAAgB,GAAG;IAC9B,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;;AAyBT;;;;;;;;;AASG;AACI,MAAM,EAAE,GAAsB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,EAAE,EAAE;AAC7C,QAAA,CAAC,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,GACtB,SAAS,IAAI,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC;AACvD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3D,KAAA,CAAC;AAEF;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IAElE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,kBAAkB,CAAC;AAEzE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,SAAS,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAC5C,QAAQ,EAAA,CACN;AAET;;"}
1
+ {"version":3,"file":"Td.js","sources":["../../../src/elements/Td.tsx"],"sourcesContent":["/**\n * @group Table\n */\nimport React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { TableAlignment, validTableAlignments } from './tableAlignment';\n\n/**\n * The values the table `color` prop accepts, as a readonly tuple.\n *\n * `TableColor` is typed from it, and `Tr`, `Th` and `Td` all take a\n * `TableColor`, so the tuple and those props list the same values. Map over\n * it to build a color picker, or check a value that arrives at runtime before\n * passing it in: the components add no color class for a value outside the\n * tuple.\n *\n * @example\n * import { Tr, Td, validTableColors } from '@allxsmith/bestax-bulma';\n *\n * <Tr>\n * {validTableColors.map(color => (\n * <Td key={color} color={color}>\n * {color}\n * </Td>\n * ))}\n * </Tr>;\n */\nexport const validTableColors = [\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 * The color values `Tr`, `Th` and `Td` accept, typed from `validTableColors`.\n */\nexport type TableColor = (typeof validTableColors)[number];\n\n/**\n * Props for the Td component.\n */\nexport interface TdProps\n extends\n Omit<React.TdHTMLAttributes<HTMLTableCellElement>, 'color'>,\n Omit<BulmaClassesProps, 'backgroundColor' | 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text alignment for the table cell ('left', 'right', 'centered'). */\n isAligned?: TableAlignment;\n /**\n * Shrinks the cell to its content and keeps that on one line (Bulma's\n * `is-narrow`), as for a column of checkboxes or actions. Not the table's\n * own `isNarrow`, which tightens every cell's padding.\n */\n isNarrow?: boolean;\n /** Centers the content vertically (Bulma's `is-vcentered`). Cells sit at the top otherwise. */\n isVcentered?: boolean;\n /** Bulma color modifier for the table cell. */\n color?: TableColor;\n /** Table cell content. */\n children?: React.ReactNode;\n}\n\n/**\n * Td component for rendering a styled Bulma table cell.\n *\n * Supports alignment, narrow and vertically centered cells, Bulma color modifiers, and helper classes for additional styling.\n *\n * @function\n * @param {TdProps} props - Props for the Td component.\n * @returns {JSX.Element} The rendered table cell element.\n * @see {@link https://bulma.io/documentation/elements/table/#table-body | Bulma Table documentation}\n */\nexport const Td: React.FC<TdProps> = ({\n className,\n isAligned,\n isNarrow,\n isVcentered,\n color,\n children,\n ...props\n}) => {\n const bulmaClasses = usePrefixedClassNames('', {\n [`has-text-${isAligned}`]:\n isAligned && validTableAlignments.includes(isAligned),\n [`is-${color}`]: color && validTableColors.includes(color),\n 'is-narrow': isNarrow,\n 'is-vcentered': isVcentered,\n });\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const tdClasses = classNames(bulmaClasses, className, bulmaHelperClasses);\n\n return (\n <td className={tdClasses || undefined} {...rest}>\n {children}\n </td>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;AAQA;;;;;;;;;;;;;;;;;;;AAmBG;AACI,MAAM,gBAAgB,GAAG;IAC9B,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;;AAiCT;;;;;;;;;AASG;MACU,EAAE,GAAsB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,EACX,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,EAAE,EAAE;AAC7C,QAAA,CAAC,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,GACtB,SAAS,IAAI,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC;AACvD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC1D,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,cAAc,EAAE,WAAW;AAC5B,KAAA,CAAC;AAEF;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IAElE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,kBAAkB,CAAC;AAEzE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,SAAS,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAC5C,QAAQ,EAAA,CACN;AAET;;"}
@@ -8,26 +8,34 @@ import { validTableAlignments } from './tableAlignment.js';
8
8
  /**
9
9
  * Th component for rendering a styled Bulma table header cell.
10
10
  *
11
- * Supports alignment, width, and color modifiers.
11
+ * Supports alignment, width, narrow and vertically centered cells, and color modifiers.
12
12
  *
13
13
  * @function
14
14
  * @param {ThProps} props - Props for the Th component.
15
15
  * @returns {JSX.Element} The rendered table header cell element.
16
16
  * @see {@link https://bulma.io/documentation/elements/table/#table-head | Bulma Table documentation}
17
17
  */
18
- const Th = ({ className, isAligned, width, color, children, ...props }) => {
18
+ const Th = ({ className, isAligned, isNarrow, isVcentered, width, color, style, children, ...props }) => {
19
19
  const bulmaClasses = usePrefixedClassNames('', {
20
20
  [`has-text-${isAligned}`]: isAligned && validTableAlignments.includes(isAligned),
21
21
  [`is-${color}`]: color && validTableColors.includes(color),
22
+ 'is-narrow': isNarrow,
23
+ 'is-vcentered': isVcentered,
22
24
  });
23
25
  /**
24
26
  * Generates Bulma helper classes and separates out remaining props.
25
27
  */
26
28
  const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });
27
29
  const thClasses = classNames(bulmaClasses, className, bulmaHelperClasses);
28
- return (jsx("th", { className: thClasses || undefined, style: width
29
- ? { width: typeof width === 'number' ? `${width}px` : width }
30
- : undefined, ...rest, children: children }));
30
+ return (jsx("th", { className: thClasses || undefined, style:
31
+ // A `width` key the style leaves undefined isn't a width, so the
32
+ // prop's stays.
33
+ width && style?.width === undefined
34
+ ? {
35
+ ...style,
36
+ width: typeof width === 'number' ? `${width}px` : width,
37
+ }
38
+ : style, ...rest, children: children }));
31
39
  };
32
40
 
33
41
  export { Th };
@@ -1 +1 @@
1
- {"version":3,"file":"Th.js","sources":["../../../src/elements/Th.tsx"],"sourcesContent":["/**\n * @group Table\n */\nimport React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { TableColor, validTableColors } from './Td';\nimport { TableAlignment, validTableAlignments } from './tableAlignment';\n\n/**\n * Props for the Th component.\n */\nexport interface ThProps\n extends\n Omit<React.ThHTMLAttributes<HTMLTableCellElement>, 'color'>,\n Omit<BulmaClassesProps, 'backgroundColor' | 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text alignment for the header cell ('left', 'right', 'centered'). */\n isAligned?: TableAlignment;\n /** Width of the header cell (e.g., '100px' or 100). */\n width?: string | number;\n /** Bulma color modifier for the header cell. */\n color?: TableColor;\n /** Table header cell content. */\n children?: React.ReactNode;\n}\n\n/**\n * Th component for rendering a styled Bulma table header cell.\n *\n * Supports alignment, width, and color modifiers.\n *\n * @function\n * @param {ThProps} props - Props for the Th component.\n * @returns {JSX.Element} The rendered table header cell element.\n * @see {@link https://bulma.io/documentation/elements/table/#table-head | Bulma Table documentation}\n */\nexport const Th: React.FC<ThProps> = ({\n className,\n isAligned,\n width,\n color,\n children,\n ...props\n}) => {\n const bulmaClasses = usePrefixedClassNames('', {\n [`has-text-${isAligned}`]:\n isAligned && validTableAlignments.includes(isAligned),\n [`is-${color}`]: color && validTableColors.includes(color),\n });\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const thClasses = classNames(bulmaClasses, className, bulmaHelperClasses);\n\n return (\n <th\n className={thClasses || undefined}\n style={\n width\n ? { width: typeof width === 'number' ? `${width}px` : width }\n : undefined\n }\n {...rest}\n >\n {children}\n </th>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;AA4BA;;;;;;;;;AASG;MACU,EAAE,GAAsB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,KAAK,EACL,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,EAAE,EAAE;AAC7C,QAAA,CAAC,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,GACtB,SAAS,IAAI,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC;AACvD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3D,KAAA,CAAC;AAEF;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IAElE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,kBAAkB,CAAC;IAEzE,QACEA,GAAA,CAAA,IAAA,EAAA,EACE,SAAS,EAAE,SAAS,IAAI,SAAS,EACjC,KAAK,EACH;AACE,cAAE,EAAE,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,GAAG,GAAG,KAAK,CAAA,EAAA,CAAI,GAAG,KAAK;cACzD,SAAS,EAAA,GAEX,IAAI,YAEP,QAAQ,EAAA,CACN;AAET;;"}
1
+ {"version":3,"file":"Th.js","sources":["../../../src/elements/Th.tsx"],"sourcesContent":["/**\n * @group Table\n */\nimport React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { TableColor, validTableColors } from './Td';\nimport { TableAlignment, validTableAlignments } from './tableAlignment';\n\n/**\n * Props for the Th component.\n */\nexport interface ThProps\n extends\n Omit<React.ThHTMLAttributes<HTMLTableCellElement>, 'color'>,\n Omit<BulmaClassesProps, 'backgroundColor' | 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Text alignment for the header cell ('left', 'right', 'centered'). */\n isAligned?: TableAlignment;\n /**\n * Shrinks the cell to its content and keeps that on one line (Bulma's\n * `is-narrow`), as for a column of checkboxes or actions. Not the table's\n * own `isNarrow`, which tightens every cell's padding.\n */\n isNarrow?: boolean;\n /** Centers the content vertically (Bulma's `is-vcentered`). Cells sit at the top otherwise. */\n isVcentered?: boolean;\n /**\n * Width of the header cell (e.g., '100px' or 100), written into its\n * `style`. A `style` passed as well keeps it, and a `width` that `style`\n * sets wins.\n */\n width?: string | number;\n /** Bulma color modifier for the header cell. */\n color?: TableColor;\n /** Table header cell content. */\n children?: React.ReactNode;\n}\n\n/**\n * Th component for rendering a styled Bulma table header cell.\n *\n * Supports alignment, width, narrow and vertically centered cells, and color modifiers.\n *\n * @function\n * @param {ThProps} props - Props for the Th component.\n * @returns {JSX.Element} The rendered table header cell element.\n * @see {@link https://bulma.io/documentation/elements/table/#table-head | Bulma Table documentation}\n */\nexport const Th: React.FC<ThProps> = ({\n className,\n isAligned,\n isNarrow,\n isVcentered,\n width,\n color,\n style,\n children,\n ...props\n}) => {\n const bulmaClasses = usePrefixedClassNames('', {\n [`has-text-${isAligned}`]:\n isAligned && validTableAlignments.includes(isAligned),\n [`is-${color}`]: color && validTableColors.includes(color),\n 'is-narrow': isNarrow,\n 'is-vcentered': isVcentered,\n });\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const thClasses = classNames(bulmaClasses, className, bulmaHelperClasses);\n\n return (\n <th\n className={thClasses || undefined}\n style={\n // A `width` key the style leaves undefined isn't a width, so the\n // prop's stays.\n width && style?.width === undefined\n ? {\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }\n : style\n }\n {...rest}\n >\n {children}\n </th>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;AAwCA;;;;;;;;;AASG;AACI,MAAM,EAAE,GAAsB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,EACX,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,EAAE,EAAE;AAC7C,QAAA,CAAC,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,GACtB,SAAS,IAAI,oBAAoB,CAAC,QAAQ,CAAC,SAAS,CAAC;AACvD,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC1D,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,cAAc,EAAE,WAAW;AAC5B,KAAA,CAAC;AAEF;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IAElE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,kBAAkB,CAAC;IAEzE,QACEA,YACE,SAAS,EAAE,SAAS,IAAI,SAAS,EACjC,KAAK;;;AAGH,QAAA,KAAK,IAAI,KAAK,EAAE,KAAK,KAAK;AACxB,cAAE;AACE,gBAAA,GAAG,KAAK;AACR,gBAAA,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,GAAG,CAAA,EAAG,KAAK,CAAA,EAAA,CAAI,GAAG,KAAK;AACxD;cACD,KAAK,EAAA,GAEP,IAAI,YAEP,QAAQ,EAAA,CACN;AAET;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tr.js","sources":["../../../src/elements/Tr.tsx"],"sourcesContent":["/**\n * @group Table\n */\nimport React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { TableColor, validTableColors } from './Td'; // Import TableColor from Td\n\n/**\n * Props for the Tr component.\n */\nexport interface TrProps\n extends\n Omit<React.HTMLAttributes<HTMLTableRowElement>, 'color'>,\n Omit<BulmaClassesProps, 'backgroundColor' | 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /** Whether the row is selected (adds Bulma's is-selected class). */\n isSelected?: boolean;\n /** Bulma color modifier for the table row. */\n color?: TableColor;\n /** Table row content (cells). */\n children?: React.ReactNode;\n}\n\n/**\n * Tr component for rendering a styled Bulma table row.\n *\n * Supports the is-selected modifier and color modifiers.\n *\n * @function\n * @param {TrProps} props - Props for the Tr component.\n * @returns {JSX.Element} The rendered table row element.\n * @see {@link https://bulma.io/documentation/elements/table/#table-row | Bulma Table documentation}\n */\nexport const Tr: React.FC<TrProps> = ({\n className,\n isSelected,\n color,\n children,\n ...props\n}) => {\n const bulmaClasses = usePrefixedClassNames('', {\n 'is-selected': isSelected,\n [`is-${color}`]: color && validTableColors.includes(color),\n });\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const trClasses = classNames(bulmaClasses, className, bulmaHelperClasses);\n\n return (\n <tr className={trClasses || undefined} {...rest}>\n {children}\n </tr>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;AAyBA;;;;;;;;;AASG;AACI,MAAM,EAAE,GAAsB,CAAC,EACpC,SAAS,EACT,UAAU,EACV,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,EAAE,EAAE;AAC7C,QAAA,aAAa,EAAE,UAAU;AACzB,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3D,KAAA,CAAC;AAEF;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IAElE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,kBAAkB,CAAC;AAEzE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,SAAS,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAC5C,QAAQ,EAAA,CACN;AAET;;"}
1
+ {"version":3,"file":"Tr.js","sources":["../../../src/elements/Tr.tsx"],"sourcesContent":["/**\n * @group Table\n */\nimport React from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { TableColor, validTableColors } from './Td'; // Import TableColor from Td\n\n/**\n * Props for the Tr component.\n */\nexport interface TrProps\n extends\n Omit<React.HTMLAttributes<HTMLTableRowElement>, 'color'>,\n Omit<BulmaClassesProps, 'backgroundColor' | 'color'> {\n /** Additional CSS classes to apply. */\n className?: string;\n /**\n * Whether the row is selected (adds Bulma's is-selected class). It's a look\n * only: it says nothing to assistive tech, so pair it with a checkbox named\n * for the row when the selection matters. A bestax `Checkbox` placed\n * straight in one of the row's cells takes the row's text color, so a\n * checked box shows on the row's fill. One in a menu or a table nested in a\n * cell, or in a cell with a `color` of its own, keeps its own colors, since\n * it sits on that surface instead, and so does every one in a row with a\n * `color`, whose cells paint that color over the fill.\n */\n isSelected?: boolean;\n /** Bulma color modifier for the table row. */\n color?: TableColor;\n /** Table row content (cells). */\n children?: React.ReactNode;\n}\n\n/**\n * Tr component for rendering a styled Bulma table row.\n *\n * Supports the is-selected modifier and color modifiers.\n *\n * @function\n * @param {TrProps} props - Props for the Tr component.\n * @returns {JSX.Element} The rendered table row element.\n * @see {@link https://bulma.io/documentation/elements/table/#table-row | Bulma Table documentation}\n */\nexport const Tr: React.FC<TrProps> = ({\n className,\n isSelected,\n color,\n children,\n ...props\n}) => {\n const bulmaClasses = usePrefixedClassNames('', {\n 'is-selected': isSelected,\n [`is-${color}`]: color && validTableColors.includes(color),\n });\n\n /**\n * Generates Bulma helper classes and separates out remaining props.\n */\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n\n const trClasses = classNames(bulmaClasses, className, bulmaHelperClasses);\n\n return (\n <tr className={trClasses || undefined} {...rest}>\n {children}\n </tr>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;AAkCA;;;;;;;;;AASG;AACI,MAAM,EAAE,GAAsB,CAAC,EACpC,SAAS,EACT,UAAU,EACV,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,EAAE,EAAE;AAC7C,QAAA,aAAa,EAAE,UAAU;AACzB,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3D,KAAA,CAAC;AAEF;;AAEG;AACH,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;IAElE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,kBAAkB,CAAC;AAEzE,IAAA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAE,SAAS,IAAI,SAAS,EAAA,GAAM,IAAI,EAAA,QAAA,EAC5C,QAAQ,EAAA,CACN;AAET;;"}
@@ -0,0 +1,68 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { forwardRef } from 'react';
4
+ import { usePrefixedClassNames } from '../helpers/classNames.js';
5
+ import { Field } from './Field.js';
6
+ import { Control } from './Control.js';
7
+ import { ColorInputBase } from './ColorInputBase.js';
8
+ import { useInsideField, useInsideControl, rendersOwnField, rendersOwnControl } from './FormContext.js';
9
+ import { useAutoLabelId } from './useAutoLabelId.js';
10
+
11
+ /**
12
+ * The `ColorInput` component is a form field for a color: type it, or open a color picker from its launcher or its swatch.
13
+ *
14
+ * The value is a CSS color string, HSL by default, or empty. The panel is
15
+ * the `ColorPicker`'s square, hue slider and, when asked for, alpha slider,
16
+ * swatches and eye dropper, in the same popover the date pickers use.
17
+ *
18
+ * @function
19
+ * @param {ColorInputProps} props - Props for the ColorInput.
20
+ * @returns {JSX.Element}
21
+ *
22
+ * @example
23
+ * <ColorInput label="Brand color" defaultValue="hsl(202, 67%, 36%)" swatches="bulma" />
24
+ */
25
+ const ColorInput = forwardRef((props, ref) => {
26
+ const { label, labelSize, labelProps, horizontal, isLoading, isExpanded, controlSize, message, messageColor, fieldClassName, controlClassName, ...baseProps } = props;
27
+ const insideField = useInsideField();
28
+ const insideControl = useInsideControl();
29
+ const ownField = rendersOwnField('ColorInput', {
30
+ insideField,
31
+ insideControl,
32
+ label,
33
+ message,
34
+ horizontal,
35
+ fieldClassName,
36
+ });
37
+ const ownControl = rendersOwnControl('ColorInput', {
38
+ insideControl,
39
+ isLoading,
40
+ isExpanded,
41
+ controlSize,
42
+ controlClassName,
43
+ });
44
+ const { controlId, fieldLabelProps } = useAutoLabelId({
45
+ label,
46
+ id: baseProps.id,
47
+ labelProps,
48
+ rendersLabel: ownField,
49
+ });
50
+ const helpClass = usePrefixedClassNames('help', {
51
+ [`is-${messageColor}`]: !!messageColor,
52
+ });
53
+ // The base hides its launcher while the Control it sits in is loading,
54
+ // whether that is the one rendered below or an enclosing one.
55
+ let content = (jsx(ColorInputBase, { ref: ref, ...baseProps, id: controlId }));
56
+ if (ownControl) {
57
+ content = (jsx(Control, { isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
58
+ }
59
+ const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
60
+ if (ownField) {
61
+ return (jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [content, messageEl] }));
62
+ }
63
+ return (jsxs(Fragment, { children: [content, messageEl] }));
64
+ });
65
+ ColorInput.displayName = 'ColorInput';
66
+
67
+ export { ColorInput };
68
+ //# sourceMappingURL=ColorInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorInput.js","sources":["../../../src/form/ColorInput.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { usePrefixedClassNames } from '../helpers/classNames';\nimport { Field, FieldProps } from './Field';\nimport { Control, ControlBaseProps } from './Control';\nimport { ColorInputBase, ColorInputBaseProps } from './ColorInputBase';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the ColorInput convenience wrapper. Extends\n * `ColorInputBaseProps` with Field-level (label, horizontal, message) and\n * Control-level (loading, expanded) props. Inside an existing `Control` it\n * renders no `Control` of its own, so its Control-level props do nothing\n * there and warn in development; set them on that `Control` instead. Inside\n * an outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n *\n * @helperProps Helper props go on the `.colorinput` `<div>`, with\n * `className`. The other attributes go on the text `<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 ColorInputProps extends ColorInputBaseProps {\n /** Field label (component auto-wraps in a `Field` if not already inside). Automatically associated with the text field via `htmlFor`, using your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: FieldProps['labelSize'];\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: FieldProps['labelProps'];\n /** Render the field with horizontal layout. */\n horizontal?: boolean;\n /**\n * Shows a loading spinner on the `Control` it renders, and hides the\n * launcher (`triggerIcon`) while it does. Inside your own `Control` it\n * renders none, so this draws nothing and warns in development; set\n * `isLoading` on that `Control`.\n */\n isLoading?: boolean;\n /**\n * Shows the launcher on the field's end that toggles the panel. Hidden by\n * default while a spinner shows at the same edge: this component's\n * `isLoading` when it renders its own `Control`, or the enclosing\n * `Control`'s `isLoading` inside one.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** Expand the control to fill its container. */\n isExpanded?: boolean;\n /** Size of the wrapping Control. */\n controlSize?: ControlBaseProps['size'];\n /** Help/validation text below the field. */\n message?: React.ReactNode;\n /** Color modifier for the help message. */\n messageColor?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Additional CSS classes for the Field wrapper. */\n fieldClassName?: string;\n /** Additional CSS classes for the Control wrapper. */\n controlClassName?: string;\n}\n\n/**\n * The `ColorInput` component is a form field for a color: type it, or open a color picker from its launcher or its swatch.\n *\n * The value is a CSS color string, HSL by default, or empty. The panel is\n * the `ColorPicker`'s square, hue slider and, when asked for, alpha slider,\n * swatches and eye dropper, in the same popover the date pickers use.\n *\n * @function\n * @param {ColorInputProps} props - Props for the ColorInput.\n * @returns {JSX.Element}\n *\n * @example\n * <ColorInput label=\"Brand color\" defaultValue=\"hsl(202, 67%, 36%)\" swatches=\"bulma\" />\n */\nexport const ColorInput = forwardRef<HTMLInputElement, ColorInputProps>(\n (props, ref) => {\n const {\n label,\n labelSize,\n labelProps,\n horizontal,\n isLoading,\n isExpanded,\n controlSize,\n message,\n messageColor,\n fieldClassName,\n controlClassName,\n ...baseProps\n } = props;\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('ColorInput', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const ownControl = rendersOwnControl('ColorInput', {\n insideControl,\n isLoading,\n isExpanded,\n controlSize,\n controlClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: baseProps.id,\n labelProps,\n rendersLabel: ownField,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // The base hides its launcher while the Control it sits in is loading,\n // whether that is the one rendered below or an enclosing one.\n let content: React.ReactNode = (\n <ColorInputBase ref={ref} {...baseProps} id={controlId} />\n );\n\n if (ownControl) {\n content = (\n <Control\n isLoading={isLoading}\n isExpanded={isExpanded}\n size={controlSize}\n className={controlClassName}\n >\n {content}\n </Control>\n );\n }\n\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nColorInput.displayName = 'ColorInput';\n\nexport default ColorInput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;AAsEA;;;;;;;;;;;;;AAaG;AACI,MAAM,UAAU,GAAG,UAAU,CAClC,CAAC,KAAK,EAAE,GAAG,KAAI;AACb,IAAA,MAAM,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,GAAG,SAAS,EACb,GAAG,KAAK;AACT,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;AACpC,IAAA,MAAM,aAAa,GAAG,gBAAgB,EAAE;AACxC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,YAAY,EAAE;QAC7C,WAAW;QACX,aAAa;QACb,KAAK;QACL,OAAO;QACP,UAAU;QACV,cAAc;AACf,KAAA,CAAC;AACF,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,YAAY,EAAE;QACjD,aAAa;QACb,SAAS;QACT,UAAU;QACV,WAAW;QACX,gBAAgB;AACjB,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,cAAc,CAAC;QACpD,KAAK;QACL,EAAE,EAAE,SAAS,CAAC,EAAE;QAChB,UAAU;AACV,QAAA,YAAY,EAAE,QAAQ;AACvB,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,YAAY,CAAA,CAAE,GAAG,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC;;;AAIF,IAAA,IAAI,OAAO,IACTA,GAAA,CAAC,cAAc,IAAC,GAAG,EAAE,GAAG,EAAA,GAAM,SAAS,EAAE,EAAE,EAAE,SAAS,EAAA,CAAI,CAC3D;IAED,IAAI,UAAU,EAAE;QACd,OAAO,IACLA,GAAA,CAAC,OAAO,EAAA,EACN,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAE1B,OAAO,EAAA,CACA,CACX;IACH;AAEA,IAAA,MAAM,SAAS,GAAG,OAAO,GAAGA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,SAAS,YAAG,OAAO,EAAA,CAAK,GAAG,IAAI;IAEzE,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEC,IAAA,CAAC,KAAK,EAAA,EACJ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAExB,OAAO,EACP,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,OAAO,EACP,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAGH,UAAU,CAAC,WAAW,GAAG,YAAY;;"}
@@ -0,0 +1,198 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useState, useRef, useId, useCallback, useEffect } from 'react';
4
+ import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
+ import { Icon } from '../elements/Icon.js';
7
+ import { ColorSwatch } from '../elements/ColorSwatch.js';
8
+ import { ColorPickerArea, ColorPickerHueSlider, ColorPickerAlphaSlider, ColorPickerSwatches } from './ColorPicker.js';
9
+ import { formatColor, parseColor } from './_colorInternals/colorMath.js';
10
+ import { mergeColorLabels, useColorPicker, BLACK, ColorPickerContext, keepingChannels } from './_colorInternals/pickerState.js';
11
+ import { EyeDropperButton } from './_colorInternals/EyeDropperButton.js';
12
+ import { PickerPopover } from './_pickerInternals/PickerPopover.js';
13
+ import { isPopoverToggleKey } from './_pickerInternals/pickerTypes.js';
14
+ import { usePickerLocaleScope } from './_pickerInternals/useLocaleDefaults.js';
15
+ import { useControlLoading } from './controlLoading.js';
16
+ import { useFieldsetDisabled, useFieldLabelTarget } from './FormContext.js';
17
+
18
+ /**
19
+ * The raw ColorInput: a text field with a swatch and a launcher that opens a color picker in a popover, without Field/Control wrapping.
20
+ *
21
+ * Use `ColorInput` for the convenience wrapper.
22
+ *
23
+ * @function
24
+ * @param {ColorInputBaseProps} props - Props for ColorInputBase.
25
+ * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the text `<input>`.
26
+ * @returns {JSX.Element} The rendered field.
27
+ */
28
+ const ColorInputBase = forwardRef((props, ref) => {
29
+ const { value: controlledValue, defaultValue, onChange, onChangeEnd, format = 'hsl', alpha = false, swatches, eyeDropper = false, onOpen, onClose, openOnFocus = false, closeOnSwatchClick = false, position = 'bottom-left', appendToBody = false, color, size, isRounded, disabled: disabledProp, readOnly, placeholder, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, className, id: idProp, onFocus, onBlur, onKeyDown, ...rest } = props;
30
+ const disabled = useFieldsetDisabled(disabledProp);
31
+ const id = useFieldLabelTarget(idProp, true);
32
+ const localeScope = usePickerLocaleScope(undefined, props.dir);
33
+ const controlLoading = useControlLoading();
34
+ const triggerIcon = triggerIconProp ?? !controlLoading;
35
+ const t = mergeColorLabels(labels);
36
+ const { bulmaHelperClasses, rest: cleanRest } = useBulmaClasses(rest);
37
+ const isControlled = controlledValue !== undefined;
38
+ const [internalValue, setInternalValue] = useState(defaultValue ?? '');
39
+ const value = isControlled ? controlledValue : internalValue;
40
+ // What's been typed and not yet committed, or null while the field
41
+ // shows the value.
42
+ const [draft, setDraft] = useState(null);
43
+ // The last color it held, which the panel shows while the field is
44
+ // empty, so clearing the field doesn't send the picker back to black.
45
+ const [remembered, setRemembered] = useState(value);
46
+ if (value && value !== remembered)
47
+ setRemembered(value);
48
+ const [open, setOpenState] = useState(false);
49
+ const canOpen = !disabled && !readOnly;
50
+ const inputRef = useRef(null);
51
+ const containerRef = useRef(null);
52
+ // Focus a closing panel hands back to the field opens nothing.
53
+ const returningRef = useRef(false);
54
+ const reactId = useId();
55
+ const popoverId = id ? `${id}-popover` : `colorinput-${reactId}`;
56
+ const setOpen = useCallback((next) => {
57
+ if (next === open)
58
+ return;
59
+ if (!next)
60
+ returningRef.current = true;
61
+ setOpenState(next);
62
+ if (next)
63
+ onOpen?.();
64
+ else
65
+ onClose?.();
66
+ }, [open, onOpen, onClose]);
67
+ // Cleared once the close has handed focus back, or hasn't.
68
+ useEffect(() => {
69
+ if (!open)
70
+ returningRef.current = false;
71
+ }, [open]);
72
+ const setValue = (next, end = true) => {
73
+ if (!isControlled)
74
+ setInternalValue(next);
75
+ if (next !== value)
76
+ onChange?.(next);
77
+ if (end)
78
+ onChangeEnd?.(next);
79
+ };
80
+ // The picker in the panel, controlled by this field's value.
81
+ const picker = useColorPicker({
82
+ value: value || remembered || formatColor(BLACK, format, alpha),
83
+ defaultValue: undefined,
84
+ onChange: next => setValue(next, false),
85
+ onChangeEnd,
86
+ format,
87
+ alpha,
88
+ disabled,
89
+ swatches,
90
+ eyeDropper,
91
+ labels,
92
+ // Empty, the panel shows the last color the field held, or black, and
93
+ // choosing that same color still fills the field.
94
+ empty: value === '',
95
+ });
96
+ const commit = () => {
97
+ if (draft === null)
98
+ return;
99
+ const typed = draft.trim();
100
+ setDraft(null);
101
+ if (typed === '') {
102
+ if (value !== '')
103
+ setValue('');
104
+ return;
105
+ }
106
+ const parsed = parseColor(typed);
107
+ if (!parsed)
108
+ return;
109
+ // A gray typed as hex, rgb() or a name keeps the panel's hue, as the
110
+ // picker's own field does; one typed as hsl() names its own.
111
+ const kept = keepingChannels(parsed, picker.color, typed);
112
+ setValue(formatColor(alpha ? kept : { ...kept, a: 1 }, format, alpha));
113
+ };
114
+ const invalid = draft !== null && draft.trim() !== '' && !parseColor(draft);
115
+ // The value as the field writes it: in `format`, however it was given.
116
+ const parsedValue = parseColor(value);
117
+ const valueText = parsedValue
118
+ ? formatColor(alpha ? parsedValue : { ...parsedValue, a: 1 }, format, alpha)
119
+ : value;
120
+ // What the swatch shows: a readable draft as it's typed, else the value.
121
+ const shown = draft !== null && !invalid ? draft.trim() : value;
122
+ const inputClass = usePrefixedClassNames('input', {
123
+ [`is-${color}`]: !!color,
124
+ [`is-${size}`]: !!size,
125
+ 'is-rounded': !!isRounded,
126
+ 'is-danger': invalid && !color,
127
+ });
128
+ const containerClass = usePrefixedClassNames('colorinput', {
129
+ 'has-trigger': triggerIcon,
130
+ });
131
+ const swatchClass = usePrefixedClassNames('colorinput-swatch');
132
+ const triggerClass = usePrefixedClassNames('colorinput-trigger');
133
+ const panelClass = usePrefixedClassNames('color-picker');
134
+ const eyeDropperClass = usePrefixedClassNames('colorinput-eyedropper');
135
+ const combinedRef = useCallback((node) => {
136
+ inputRef.current = node;
137
+ if (typeof ref === 'function')
138
+ ref(node);
139
+ else if (ref)
140
+ ref.current = node;
141
+ }, [ref]);
142
+ const handleKeyDown = (event) => {
143
+ onKeyDown?.(event);
144
+ if (event.defaultPrevented)
145
+ return;
146
+ if (isPopoverToggleKey(event) && event.key === 'ArrowDown') {
147
+ event.preventDefault();
148
+ if (canOpen)
149
+ setOpen(true);
150
+ }
151
+ else if (draft !== null && event.key === 'Enter') {
152
+ // Commits rather than submitting a form; an unreadable value stays
153
+ // to be fixed.
154
+ event.preventDefault();
155
+ if (!invalid)
156
+ commit();
157
+ }
158
+ else if (draft !== null && event.key === 'Escape') {
159
+ // Puts the value back, and keeps a Modal around it open.
160
+ event.preventDefault();
161
+ event.stopPropagation();
162
+ setDraft(null);
163
+ }
164
+ };
165
+ const handleFocus = (event) => {
166
+ onFocus?.(event);
167
+ const returning = returningRef.current;
168
+ returningRef.current = false;
169
+ if (openOnFocus && canOpen && !returning)
170
+ setOpen(true);
171
+ };
172
+ const handleBlur = (event) => {
173
+ onBlur?.(event);
174
+ commit();
175
+ };
176
+ const popupAttrs = {
177
+ 'aria-haspopup': 'dialog',
178
+ 'aria-controls': popoverId,
179
+ 'aria-expanded': open,
180
+ };
181
+ return (jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...localeScope.rootAttrs, children: [jsx("input", { ...cleanRest, ref: combinedRef, type: "text", role: "combobox", ...popupAttrs, autoComplete: "off", spellCheck: false, autoCapitalize: "off", className: inputClass, value: draft ?? valueText, placeholder: placeholder, disabled: disabled, readOnly: readOnly, "aria-invalid": invalid || cleanRest['aria-invalid'] || undefined, id: id, onChange: event => setDraft(event.target.value), onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur }), jsx("button", { type: "button", className: swatchClass, tabIndex: -1, "aria-hidden": "true", disabled: !canOpen, onMouseDown: event => event.preventDefault(), onClick: () => setOpen(true), children: jsx(ColorSwatch, { color: shown || 'transparent', "aria-hidden": "true" }) }), triggerIcon && (jsx("button", { type: "button", className: triggerClass, ...popupAttrs, "aria-label": t.chooseColor, disabled: !canOpen, onClick: () => setOpen(!open), children: jsx(Icon, { name: triggerIconName, size: size }) })), jsx(PickerPopover, { localeScope: localeScope.panel, isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseColor, id: popoverId, restoreFocusRef: inputRef, children: jsx(ColorPickerContext.Provider, { value: picker, children: jsxs("div", { className: panelClass, children: [jsx(ColorPickerArea, {}), jsx(ColorPickerHueSlider, {}), alpha && jsx(ColorPickerAlphaSlider, {}), swatches && (jsx(ColorPickerSwatches
182
+ // A click on a swatch, or Enter or Space on one, closes
183
+ // the panel when asked to; the arrows only choose.
184
+ , {
185
+ // A click on a swatch, or Enter or Space on one, closes
186
+ // the panel when asked to; the arrows only choose.
187
+ onClick: event => {
188
+ const target = event.target;
189
+ if (closeOnSwatchClick &&
190
+ target.closest('[role="radio"]')) {
191
+ setOpen(false);
192
+ }
193
+ } })), jsx(EyeDropperButton, { className: eyeDropperClass })] }) }) })] }));
194
+ });
195
+ ColorInputBase.displayName = 'ColorInputBase';
196
+
197
+ export { ColorInputBase };
198
+ //# sourceMappingURL=ColorInputBase.js.map
@@ -0,0 +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 { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\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`. The other attributes go on the text `<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 /** The panel's place relative to the field. */\n position?: PickerPosition;\n /**\n * Renders the panel through a portal, into the `portalContainer` a\n * `ConfigProvider` sets, `document.body` by default.\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 = 'bottom-left',\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 const { bulmaHelperClasses, rest: cleanRest } = useBulmaClasses(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(containerClass, bulmaHelperClasses, className)}\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={inputClass}\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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"}