@allxsmith/bestax-bulma 5.55.0 → 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.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/useDataTable.js +27 -0
- package/dist/esm/components/useDataTable.js.map +1 -1
- package/dist/esm/form/ColorInput.js +68 -0
- package/dist/esm/form/ColorInput.js.map +1 -0
- package/dist/esm/form/ColorInputBase.js +198 -0
- package/dist/esm/form/ColorInputBase.js.map +1 -0
- package/dist/esm/form/ColorPicker.js +4 -20
- package/dist/esm/form/ColorPicker.js.map +1 -1
- package/dist/esm/form/_colorInternals/EyeDropperButton.js +40 -0
- package/dist/esm/form/_colorInternals/EyeDropperButton.js.map +1 -0
- package/dist/esm/form/_colorInternals/pickerState.js +4 -4
- package/dist/esm/form/_colorInternals/pickerState.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +300 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/DataTable.d.ts +1 -1
- package/dist/types/components/useDataTable.d.ts +36 -0
- package/dist/types/form/ColorInput.d.ts +76 -0
- package/dist/types/form/ColorInputBase.d.ts +108 -0
- package/dist/types/form/ColorPicker.d.ts +5 -0
- package/dist/types/form/_colorInternals/EyeDropperButton.d.ts +8 -0
- package/dist/types/form/_colorInternals/pickerState.d.ts +7 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types-cjs/components/DataTable.d.ts +1 -1
- package/dist/types-cjs/components/useDataTable.d.ts +36 -0
- package/dist/types-cjs/form/ColorInput.d.ts +76 -0
- package/dist/types-cjs/form/ColorInputBase.d.ts +108 -0
- package/dist/types-cjs/form/ColorPicker.d.ts +5 -0
- package/dist/types-cjs/form/_colorInternals/EyeDropperButton.d.ts +8 -0
- package/dist/types-cjs/form/_colorInternals/pickerState.d.ts +7 -1
- package/dist/types-cjs/index.d.ts +4 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/form/_colorinput.scss +109 -0
- package/src/scss/form/_index.scss +1 -0
|
@@ -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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"}
|
|
@@ -4,12 +4,12 @@ import { forwardRef, useRef, useState, useMemo, useCallback, useEffect } from 'r
|
|
|
4
4
|
import { usePrefixedClassNames, classNames, prefixedClassNames } from '../helpers/classNames.js';
|
|
5
5
|
import { useClassPrefix } from '../helpers/Config.js';
|
|
6
6
|
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
7
|
-
import { useIsHydrated } from '../helpers/useIsHydrated.js';
|
|
8
7
|
import { useClientLayoutEffect } from '../helpers/useClientLayoutEffect.js';
|
|
9
8
|
import { withSubComponents } from '../helpers/withSubComponents.js';
|
|
10
9
|
import { ColorSwatch } from '../elements/ColorSwatch.js';
|
|
11
10
|
import { parseColor, formatColor, sameColor, prefersDarkInk, hsvaToRgba } from './_colorInternals/colorMath.js';
|
|
12
|
-
import { usePicker, standalone, useColorPicker, ColorPickerContext, keepingChannels
|
|
11
|
+
import { usePicker, standalone, useColorPicker, ColorPickerContext, keepingChannels } from './_colorInternals/pickerState.js';
|
|
12
|
+
import { EyeDropperButton } from './_colorInternals/EyeDropperButton.js';
|
|
13
13
|
import { Field } from './Field.js';
|
|
14
14
|
import { Control } from './Control.js';
|
|
15
15
|
import { useFieldsetDisabled, useInsideField, useInsideControl, rendersOwnField, rendersOwnControl } from './FormContext.js';
|
|
@@ -406,7 +406,7 @@ const CheckIcon = ({ haloClass }) => (jsx("svg", { viewBox: "0 0 16 16", width:
|
|
|
406
406
|
const ColorPickerInput = forwardRef(({ className, ...props }, ref) => {
|
|
407
407
|
const picker = usePicker('Input');
|
|
408
408
|
const live = picker ?? standalone;
|
|
409
|
-
const { color, text, change, disabled, labels
|
|
409
|
+
const { color, text, change, disabled, labels } = live;
|
|
410
410
|
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
411
411
|
const rowClass = usePrefixedClassNames('color-picker-value');
|
|
412
412
|
const previewClass = usePrefixedClassNames('color-picker-preview');
|
|
@@ -418,11 +418,6 @@ const ColorPickerInput = forwardRef(({ className, ...props }, ref) => {
|
|
|
418
418
|
'is-small': true,
|
|
419
419
|
'is-danger': invalid,
|
|
420
420
|
});
|
|
421
|
-
const buttonClass = usePrefixedClassNames('button', { 'is-small': true });
|
|
422
|
-
const hydrated = useIsHydrated();
|
|
423
|
-
const EyeDropper = hydrated
|
|
424
|
-
? window.EyeDropper
|
|
425
|
-
: undefined;
|
|
426
421
|
const commit = () => {
|
|
427
422
|
if (draft === null)
|
|
428
423
|
return;
|
|
@@ -448,22 +443,11 @@ const ColorPickerInput = forwardRef(({ className, ...props }, ref) => {
|
|
|
448
443
|
setDraft(null);
|
|
449
444
|
}
|
|
450
445
|
};
|
|
451
|
-
// Escape, or a click away, cancels it, which rejects.
|
|
452
|
-
const pickFromScreen = (Dropper) => new Dropper().open().then(({ sRGBHex }) => {
|
|
453
|
-
const parsed = parseColor(sRGBHex);
|
|
454
|
-
// The screen gives a solid color as hex; the alpha stays as it was,
|
|
455
|
-
// and a gray keeps the hue the picker had.
|
|
456
|
-
if (parsed) {
|
|
457
|
-
change(keepingChannels({ ...parsed, a: color.a }, color, sRGBHex), true);
|
|
458
|
-
}
|
|
459
|
-
}, noop);
|
|
460
446
|
if (!picker)
|
|
461
447
|
return null;
|
|
462
|
-
return (jsxs("div", { ref: ref, className: classNames(rowClass, bulmaHelperClasses, className), ...rest, children: [jsx(ColorSwatch, { color: text, className: previewClass, "aria-hidden": "true" }), jsx("input", { type: "text", className: inputClass, value: draft ?? text, disabled: disabled, "aria-label": labels.value, "aria-invalid": invalid || undefined, spellCheck: false, autoComplete: "off", autoCapitalize: "off", onChange: event => setDraft(event.target.value), onKeyDown: onKeyDown, onBlur: commit }),
|
|
448
|
+
return (jsxs("div", { ref: ref, className: classNames(rowClass, bulmaHelperClasses, className), ...rest, children: [jsx(ColorSwatch, { color: text, className: previewClass, "aria-hidden": "true" }), jsx("input", { type: "text", className: inputClass, value: draft ?? text, disabled: disabled, "aria-label": labels.value, "aria-invalid": invalid || undefined, spellCheck: false, autoComplete: "off", autoCapitalize: "off", onChange: event => setDraft(event.target.value), onKeyDown: onKeyDown, onBlur: commit }), jsx(EyeDropperButton, {})] }));
|
|
463
449
|
});
|
|
464
450
|
ColorPickerInput.displayName = 'ColorPicker.Input';
|
|
465
|
-
/** A pipette. */
|
|
466
|
-
const EyeDropperIcon = () => (jsx("svg", { viewBox: "0 0 16 16", width: "1em", height: "1em", "aria-hidden": "true", children: jsx("path", { d: "M10.5 2.5l3 3M9 4l3 3-6.5 6.5H3v-3z", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinejoin: "round" }) }));
|
|
467
451
|
/**
|
|
468
452
|
* The `ColorPicker` component is a panel for choosing a color: a saturation and brightness square, a hue slider, and the value as text, with alpha and swatches when asked for.
|
|
469
453
|
*
|