colibri-ui 0.8.95 → 0.8.97

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 (90) hide show
  1. package/ColorPicker/ColorPicker.d.ts +3 -0
  2. package/ColorPicker/ColorPicker.js +116 -0
  3. package/ColorPicker/ColorPicker.module.css +22 -0
  4. package/ColorPicker/assets/none.png +0 -0
  5. package/ColorPicker/components/ColorPreview/ColorPreview.module.css +23 -0
  6. package/ColorPicker/components/ColorPreview/index.d.ts +10 -0
  7. package/ColorPicker/components/ColorPreview/index.js +29 -0
  8. package/ColorPicker/components/CustomColorModal/CustomColorModal.module.css +18 -0
  9. package/ColorPicker/components/CustomColorModal/index.d.ts +15 -0
  10. package/ColorPicker/components/CustomColorModal/index.js +107 -0
  11. package/ColorPicker/components/HueSlider/HueSlider.module.css +31 -0
  12. package/ColorPicker/components/HueSlider/index.d.ts +10 -0
  13. package/ColorPicker/components/HueSlider/index.js +73 -0
  14. package/ColorPicker/components/Palette/Palette.module.css +12 -0
  15. package/ColorPicker/components/Palette/index.d.ts +19 -0
  16. package/ColorPicker/components/Palette/index.js +99 -0
  17. package/ColorPicker/components/SaturationPanel/SaturationPanel.module.css +26 -0
  18. package/ColorPicker/components/SaturationPanel/index.d.ts +13 -0
  19. package/ColorPicker/components/SaturationPanel/index.js +86 -0
  20. package/ColorPicker/components/Swatch/Swatch.module.css +36 -0
  21. package/ColorPicker/components/Swatch/index.d.ts +14 -0
  22. package/ColorPicker/components/Swatch/index.js +47 -0
  23. package/ColorPicker/hooks/useEyeDropper.d.ts +8 -0
  24. package/ColorPicker/hooks/useEyeDropper.js +38 -0
  25. package/ColorPicker/hooks/useHexDraft.d.ts +19 -0
  26. package/ColorPicker/hooks/useHexDraft.js +49 -0
  27. package/ColorPicker/hooks/usePointerDrag.d.ts +20 -0
  28. package/ColorPicker/hooks/usePointerDrag.js +55 -0
  29. package/ColorPicker/index.d.ts +3 -0
  30. package/ColorPicker/index.js +9 -0
  31. package/ColorPicker/index.props.d.ts +43 -0
  32. package/ColorPicker/package.json +9 -0
  33. package/ColorPicker/presets.d.ts +3 -0
  34. package/ColorPicker/presets.js +92 -0
  35. package/ColorPicker/utils/color.d.ts +25 -0
  36. package/ColorPicker/utils/color.js +162 -0
  37. package/Icons/Pipette.d.ts +3 -0
  38. package/Icons/Pipette.js +35 -0
  39. package/Icons/index.d.ts +1 -0
  40. package/Icons/index.js +2 -0
  41. package/Modal/Modal.module.css +10 -0
  42. package/Modal/index.js +4 -2
  43. package/Modal/index.props.d.ts +6 -0
  44. package/esm/ColorPicker/ColorPicker.d.ts +3 -0
  45. package/esm/ColorPicker/ColorPicker.js +108 -0
  46. package/esm/ColorPicker/ColorPicker.module.css +22 -0
  47. package/esm/ColorPicker/assets/none.png +0 -0
  48. package/esm/ColorPicker/components/ColorPreview/ColorPreview.module.css +23 -0
  49. package/esm/ColorPicker/components/ColorPreview/index.d.ts +10 -0
  50. package/esm/ColorPicker/components/ColorPreview/index.js +21 -0
  51. package/esm/ColorPicker/components/CustomColorModal/CustomColorModal.module.css +18 -0
  52. package/esm/ColorPicker/components/CustomColorModal/index.d.ts +15 -0
  53. package/esm/ColorPicker/components/CustomColorModal/index.js +100 -0
  54. package/esm/ColorPicker/components/HueSlider/HueSlider.module.css +31 -0
  55. package/esm/ColorPicker/components/HueSlider/index.d.ts +10 -0
  56. package/esm/ColorPicker/components/HueSlider/index.js +66 -0
  57. package/esm/ColorPicker/components/Palette/Palette.module.css +12 -0
  58. package/esm/ColorPicker/components/Palette/index.d.ts +19 -0
  59. package/esm/ColorPicker/components/Palette/index.js +92 -0
  60. package/esm/ColorPicker/components/SaturationPanel/SaturationPanel.module.css +26 -0
  61. package/esm/ColorPicker/components/SaturationPanel/index.d.ts +13 -0
  62. package/esm/ColorPicker/components/SaturationPanel/index.js +79 -0
  63. package/esm/ColorPicker/components/Swatch/Swatch.module.css +36 -0
  64. package/esm/ColorPicker/components/Swatch/index.d.ts +14 -0
  65. package/esm/ColorPicker/components/Swatch/index.js +38 -0
  66. package/esm/ColorPicker/hooks/useEyeDropper.d.ts +8 -0
  67. package/esm/ColorPicker/hooks/useEyeDropper.js +36 -0
  68. package/esm/ColorPicker/hooks/useHexDraft.d.ts +19 -0
  69. package/esm/ColorPicker/hooks/useHexDraft.js +47 -0
  70. package/esm/ColorPicker/hooks/usePointerDrag.d.ts +20 -0
  71. package/esm/ColorPicker/hooks/usePointerDrag.js +53 -0
  72. package/esm/ColorPicker/index.d.ts +3 -0
  73. package/esm/ColorPicker/index.js +2 -0
  74. package/esm/ColorPicker/index.props.d.ts +43 -0
  75. package/esm/ColorPicker/presets.d.ts +3 -0
  76. package/esm/ColorPicker/presets.js +89 -0
  77. package/esm/ColorPicker/utils/color.d.ts +25 -0
  78. package/esm/ColorPicker/utils/color.js +152 -0
  79. package/esm/Icons/Pipette.d.ts +3 -0
  80. package/esm/Icons/Pipette.js +29 -0
  81. package/esm/Icons/index.d.ts +1 -0
  82. package/esm/Icons/index.js +1 -0
  83. package/esm/Modal/Modal.module.css +10 -0
  84. package/esm/Modal/index.js +4 -2
  85. package/esm/Modal/index.props.d.ts +6 -0
  86. package/esm/index.d.ts +2 -0
  87. package/esm/index.js +3 -0
  88. package/index.d.ts +2 -0
  89. package/index.js +7 -0
  90. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var usePointerDrag = require('../../hooks/usePointerDrag.js');
5
+ var color = require('../../utils/color.js');
6
+ var styles = require('./SaturationPanel.module.css');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var React__default = /*#__PURE__*/_interopDefault(React);
11
+ var styles__default = /*#__PURE__*/_interopDefault(styles);
12
+
13
+ const STEP = 1;
14
+ const BIG_STEP = 10;
15
+ /**
16
+ * Saturation (horizontal) and brightness (vertical) area. Arrow keys change
17
+ * by 1, with Shift by 10.
18
+ */
19
+ const SaturationPanel = ({
20
+ value,
21
+ onChange,
22
+ "aria-label": ariaLabel
23
+ }) => {
24
+ const {
25
+ h,
26
+ s,
27
+ v
28
+ } = value;
29
+ const {
30
+ ref,
31
+ handlers
32
+ } = usePointerDrag.usePointerDrag(({
33
+ x,
34
+ y
35
+ }) => onChange({
36
+ h,
37
+ s: x * 100,
38
+ v: (1 - y) * 100
39
+ }));
40
+ const handleKeyDown = event => {
41
+ const step = event.shiftKey ? BIG_STEP : STEP;
42
+ const deltas = {
43
+ ArrowLeft: [-step, 0],
44
+ ArrowRight: [step, 0],
45
+ ArrowUp: [0, step],
46
+ ArrowDown: [0, -step]
47
+ };
48
+ const delta = deltas[event.key];
49
+ if (!delta) return;
50
+ event.preventDefault();
51
+ onChange({
52
+ h,
53
+ s: color.clamp(s + delta[0], 0, 100),
54
+ v: color.clamp(v + delta[1], 0, 100)
55
+ });
56
+ };
57
+ return /*#__PURE__*/React__default.default.createElement("div", Object.assign({
58
+ ref: ref
59
+ }, handlers, {
60
+ role: "slider",
61
+ tabIndex: 0,
62
+ "aria-label": ariaLabel,
63
+ "aria-valuemin": 0,
64
+ "aria-valuemax": 100,
65
+ "aria-valuenow": Math.round(s),
66
+ "aria-valuetext": `${Math.round(s)}%, ${Math.round(v)}%`,
67
+ onKeyDown: handleKeyDown,
68
+ className: styles__default.default.root,
69
+ style: {
70
+ backgroundColor: color.hsv2css({
71
+ h,
72
+ s: 100,
73
+ v: 100
74
+ })
75
+ }
76
+ }), /*#__PURE__*/React__default.default.createElement("div", {
77
+ className: styles__default.default.thumb,
78
+ style: {
79
+ left: `${s}%`,
80
+ top: `${100 - v}%`,
81
+ backgroundColor: color.hsv2css(value)
82
+ }
83
+ }));
84
+ };
85
+
86
+ exports.SaturationPanel = SaturationPanel;
@@ -0,0 +1,36 @@
1
+ .root {
2
+ align-items: center;
3
+ border-radius: var(--radius-full);
4
+ cursor: pointer;
5
+ display: inline-flex;
6
+ flex-shrink: 0;
7
+ height: var(--space-6);
8
+ justify-content: center;
9
+ padding: 0;
10
+ transition: transform 0.1s ease;
11
+ width: var(--space-6);
12
+ }
13
+ .root:hover {
14
+ transform: scale(1.1);
15
+ }
16
+ .root:focus-visible {
17
+ outline: var(--focus-ring-width) solid var(--color-focus-ring);
18
+ outline-offset: var(--focus-ring-width);
19
+ }
20
+
21
+ .check_light {
22
+ color: var(--color-neutral-0);
23
+ }
24
+
25
+ .check_dark {
26
+ color: var(--color-neutral-950);
27
+ }
28
+
29
+ .outlined {
30
+ box-shadow: inset 0 0 0 var(--border-width-hairline) var(--color-border-default);
31
+ }
32
+
33
+ .check {
34
+ height: var(--space-4);
35
+ width: var(--space-4);
36
+ }
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import type { ButtonHTMLAttributes } from "react";
3
+ interface SwatchProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "color" | "type"> {
4
+ /** `#rrggbb` */
5
+ color: string;
6
+ label: string;
7
+ selected: boolean;
8
+ }
9
+ /**
10
+ * Color circle button. The check mark adapts to the color, light colors get
11
+ * an outline.
12
+ */
13
+ export declare const Swatch: ({ color, label, selected, className, ...props }: SwatchProps) => React.JSX.Element;
14
+ export {};
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var tslib = require('tslib');
4
+ var React = require('react');
5
+ var clsx = require('clsx');
6
+ require('../../../Icons/index.js');
7
+ var color = require('../../utils/color.js');
8
+ var styles = require('./Swatch.module.css');
9
+ var Check = require('../../../Icons/Check.js');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var React__default = /*#__PURE__*/_interopDefault(React);
14
+ var clsx__default = /*#__PURE__*/_interopDefault(clsx);
15
+ var styles__default = /*#__PURE__*/_interopDefault(styles);
16
+
17
+ /**
18
+ * Color circle button. The check mark adapts to the color, light colors get
19
+ * an outline.
20
+ */
21
+ const Swatch = _a => {
22
+ var {
23
+ color: color$1,
24
+ label,
25
+ selected,
26
+ className
27
+ } = _a,
28
+ props = tslib.__rest(_a, ["color", "label", "selected", "className"]);
29
+ return /*#__PURE__*/React__default.default.createElement("button", Object.assign({}, props, {
30
+ type: "button",
31
+ role: "menuitemradio",
32
+ "aria-checked": selected,
33
+ "aria-label": label,
34
+ title: label,
35
+ className: clsx__default.default(styles__default.default.root, color.prefersLightText(color$1) ? styles__default.default.check_light : styles__default.default.check_dark, {
36
+ [styles__default.default.outlined]: color.isLightColor(color$1)
37
+ }, className),
38
+ style: {
39
+ backgroundColor: color$1
40
+ }
41
+ }), selected && /*#__PURE__*/React__default.default.createElement(Check.Check, {
42
+ className: styles__default.default.check,
43
+ "aria-hidden": "true"
44
+ }));
45
+ };
46
+
47
+ exports.Swatch = Swatch;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Native browser eye dropper (EyeDropper API). Chromium only: in Safari and
3
+ * Firefox `isSupported` is `false`.
4
+ */
5
+ export declare const useEyeDropper: () => {
6
+ isSupported: boolean;
7
+ pick: () => Promise<string | null>;
8
+ };
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var color = require('../utils/color.js');
5
+
6
+ const subscribe = () => () => {};
7
+ const getSnapshot = () => "EyeDropper" in window;
8
+ // No API on the server, so hydration does not mismatch.
9
+ const getServerSnapshot = () => false;
10
+ /**
11
+ * Native browser eye dropper (EyeDropper API). Chromium only: in Safari and
12
+ * Firefox `isSupported` is `false`.
13
+ */
14
+ const useEyeDropper = () => {
15
+ const isSupported = React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
16
+ /** `#rrggbb`, or `null` when the user cancels with Escape. */
17
+ const pick = React.useCallback(async () => {
18
+ const {
19
+ EyeDropper
20
+ } = window;
21
+ if (!EyeDropper) return null;
22
+ try {
23
+ // eslint-disable-next-line compat/compat -- guarded by the feature check above
24
+ const {
25
+ sRGBHex
26
+ } = await new EyeDropper().open();
27
+ return color.toHex(sRGBHex);
28
+ } catch (_a) {
29
+ return null;
30
+ }
31
+ }, []);
32
+ return {
33
+ isSupported,
34
+ pick
35
+ };
36
+ };
37
+
38
+ exports.useEyeDropper = useEyeDropper;
@@ -0,0 +1,19 @@
1
+ import type { ChangeEvent, KeyboardEvent } from "react";
2
+ /**
3
+ * HEX field logic for `Input`:
4
+ * - while focused, the field keeps a draft, so it can be cleared and retyped;
5
+ * - a full `#rrggbb` applies while typing;
6
+ * - a short `#abc` applies on blur or Enter (focus stays), so typing
7
+ * `#abcdef` does not flash `#aabbcc`;
8
+ * - invalid input reverts to the current value on blur.
9
+ */
10
+ export declare const useHexDraft: (value: string, onChange: (hex: string) => void) => {
11
+ invalid: boolean;
12
+ inputProps: {
13
+ value: string;
14
+ onFocus: () => void;
15
+ onChange: (event: ChangeEvent<HTMLInputElement>) => void;
16
+ onBlur: () => void;
17
+ onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
18
+ };
19
+ };
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var color = require('../utils/color.js');
5
+
6
+ const FULL_HEX_RE = /^#?[0-9a-f]{6}$/i;
7
+ /**
8
+ * HEX field logic for `Input`:
9
+ * - while focused, the field keeps a draft, so it can be cleared and retyped;
10
+ * - a full `#rrggbb` applies while typing;
11
+ * - a short `#abc` applies on blur or Enter (focus stays), so typing
12
+ * `#abcdef` does not flash `#aabbcc`;
13
+ * - invalid input reverts to the current value on blur.
14
+ */
15
+ const useHexDraft = (value, onChange) => {
16
+ // null: not editing, show `value`.
17
+ const [draft, setDraft] = React.useState(null);
18
+ const commit = text => {
19
+ const hex = color.normalizeHex(text);
20
+ if (hex && hex !== value) onChange(hex);
21
+ };
22
+ return {
23
+ invalid: draft !== null && color.normalizeHex(draft) === null,
24
+ inputProps: {
25
+ value: draft !== null && draft !== void 0 ? draft : value,
26
+ onFocus: () => setDraft(value),
27
+ onChange: event => {
28
+ const text = event.target.value;
29
+ setDraft(text);
30
+ if (FULL_HEX_RE.test(text.trim())) commit(text);
31
+ },
32
+ onBlur: () => {
33
+ if (draft !== null) commit(draft);
34
+ setDraft(null);
35
+ },
36
+ // Applies a short HEX and keeps focus in the field.
37
+ onKeyDown: event => {
38
+ if (event.key !== "Enter" || draft === null) return;
39
+ const hex = color.normalizeHex(draft);
40
+ if (hex) {
41
+ commit(draft);
42
+ setDraft(hex);
43
+ }
44
+ }
45
+ }
46
+ };
47
+ };
48
+
49
+ exports.useHexDraft = useHexDraft;
@@ -0,0 +1,20 @@
1
+ import type { PointerEvent as ReactPointerEvent } from "react";
2
+ /** Pointer position inside the element, 0–1 on each axis. */
3
+ export interface DragPosition {
4
+ x: number;
5
+ y: number;
6
+ }
7
+ /**
8
+ * Dragging inside an element with Pointer Events (mouse, touch, pen).
9
+ * Pointer capture keeps tracking outside the element without document
10
+ * listeners. The element needs `touch-action: none`.
11
+ */
12
+ export declare const usePointerDrag: <T extends HTMLElement>(onMove: (position: DragPosition) => void) => {
13
+ ref: import("react").RefObject<T | null>;
14
+ handlers: {
15
+ onPointerDown: (event: ReactPointerEvent<T>) => void;
16
+ onPointerMove: (event: ReactPointerEvent<T>) => void;
17
+ onPointerUp: (event: ReactPointerEvent<T>) => void;
18
+ onPointerCancel: (event: ReactPointerEvent<T>) => void;
19
+ };
20
+ };
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var color = require('../utils/color.js');
5
+
6
+ /**
7
+ * Dragging inside an element with Pointer Events (mouse, touch, pen).
8
+ * Pointer capture keeps tracking outside the element without document
9
+ * listeners. The element needs `touch-action: none`.
10
+ */
11
+ const usePointerDrag = onMove => {
12
+ const ref = React.useRef(null);
13
+ const onMoveRef = React.useRef(onMove);
14
+ React.useEffect(() => {
15
+ onMoveRef.current = onMove;
16
+ });
17
+ const move = React.useCallback(event => {
18
+ const element = ref.current;
19
+ if (!element) return;
20
+ const rect = element.getBoundingClientRect();
21
+ onMoveRef.current({
22
+ x: color.clamp((event.clientX - rect.left) / rect.width),
23
+ y: color.clamp((event.clientY - rect.top) / rect.height)
24
+ });
25
+ }, []);
26
+ const onPointerDown = React.useCallback(event => {
27
+ if (event.button !== 0 || !ref.current) return;
28
+ // preventDefault stops text selection but also focus, so focus manually.
29
+ event.preventDefault();
30
+ ref.current.setPointerCapture(event.pointerId);
31
+ ref.current.focus();
32
+ move(event);
33
+ }, [move]);
34
+ const onPointerMove = React.useCallback(event => {
35
+ var _a;
36
+ if ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.hasPointerCapture(event.pointerId)) move(event);
37
+ }, [move]);
38
+ const onPointerUp = React.useCallback(event => {
39
+ var _a;
40
+ if ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.hasPointerCapture(event.pointerId)) {
41
+ ref.current.releasePointerCapture(event.pointerId);
42
+ }
43
+ }, []);
44
+ return {
45
+ ref,
46
+ handlers: {
47
+ onPointerDown,
48
+ onPointerMove,
49
+ onPointerUp,
50
+ onPointerCancel: onPointerUp
51
+ }
52
+ };
53
+ };
54
+
55
+ exports.usePointerDrag = usePointerDrag;
@@ -0,0 +1,3 @@
1
+ export { ColorPicker } from "./ColorPicker";
2
+ export { COLOR_PICKER_PRESETS } from "./presets";
3
+ export type { ColorPickerLabels, ColorPickerPreset, ColorPickerProps, } from "./index.props";
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var ColorPicker = require('./ColorPicker.js');
4
+ var presets = require('./presets.js');
5
+
6
+
7
+
8
+ exports.ColorPicker = ColorPicker.ColorPicker;
9
+ exports.COLOR_PICKER_PRESETS = presets.COLOR_PICKER_PRESETS;
@@ -0,0 +1,43 @@
1
+ import type { ReactElement } from "react";
2
+ import type { Placement } from "@floating-ui/react";
3
+ export interface ColorPickerPreset {
4
+ /** HEX color, for example `#d81b60`. */
5
+ value: string;
6
+ /** Accessible name and tooltip of the swatch. */
7
+ label: string;
8
+ }
9
+ export interface ColorPickerLabels {
10
+ /** Accessible name of the default trigger. */
11
+ trigger: string;
12
+ /** Accessible name of the preset grid. */
13
+ palette: string;
14
+ /** "+" button that opens the custom color dialog. */
15
+ addCustom: string;
16
+ customTitle: string;
17
+ customDescription: string;
18
+ /** Sample text in the preview circle. */
19
+ preview: string;
20
+ hex: string;
21
+ eyeDropper: string;
22
+ saturation: string;
23
+ hue: string;
24
+ cancel: string;
25
+ save: string;
26
+ }
27
+ export interface ColorPickerProps {
28
+ /** Current color in HEX. A color missing from `presets` is shown as an extra swatch. */
29
+ value?: string;
30
+ /** Called with the chosen color as lowercase `#rrggbb`. */
31
+ onChange: (color: string) => void;
32
+ /** Preset colors. Defaults to `COLOR_PICKER_PRESETS`. */
33
+ presets?: ColorPickerPreset[];
34
+ /** Number of grid columns. */
35
+ columns?: number;
36
+ disabled?: boolean;
37
+ placement?: Placement;
38
+ zIndex?: number;
39
+ /** Texts and accessible names. Missing keys use English defaults. */
40
+ labels?: Partial<ColorPickerLabels>;
41
+ /** Custom trigger element. Defaults to a round button with the current color. */
42
+ children?: ReactElement;
43
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "sideEffects": [
3
+ "**/*.css",
4
+ "**/*.scss"
5
+ ],
6
+ "module": "../esm/ColorPicker/index.js",
7
+ "main": "./index.js",
8
+ "types": "./index.d.ts"
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { ColorPickerLabels, ColorPickerPreset } from "./index.props";
2
+ export declare const COLOR_PICKER_PRESETS: ColorPickerPreset[];
3
+ export declare const DEFAULT_LABELS: ColorPickerLabels;
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ const COLOR_PICKER_PRESETS = [{
4
+ value: "#ad1457",
5
+ label: "Radicchio"
6
+ }, {
7
+ value: "#f4511e",
8
+ label: "Tangerine"
9
+ }, {
10
+ value: "#e4c441",
11
+ label: "Citron"
12
+ }, {
13
+ value: "#0b8043",
14
+ label: "Basil"
15
+ }, {
16
+ value: "#3f51b5",
17
+ label: "Blueberry"
18
+ }, {
19
+ value: "#8e24aa",
20
+ label: "Grape"
21
+ }, {
22
+ value: "#d81b60",
23
+ label: "Cherry blossom"
24
+ }, {
25
+ value: "#ef6c00",
26
+ label: "Pumpkin"
27
+ }, {
28
+ value: "#c0ca33",
29
+ label: "Avocado"
30
+ }, {
31
+ value: "#009688",
32
+ label: "Eucalyptus"
33
+ }, {
34
+ value: "#7986cb",
35
+ label: "Lavender"
36
+ }, {
37
+ value: "#795548",
38
+ label: "Cocoa"
39
+ }, {
40
+ value: "#d50000",
41
+ label: "Tomato"
42
+ }, {
43
+ value: "#f09300",
44
+ label: "Mango"
45
+ }, {
46
+ value: "#7cb342",
47
+ label: "Pistachio"
48
+ }, {
49
+ value: "#039be5",
50
+ label: "Peacock"
51
+ }, {
52
+ value: "#b39ddb",
53
+ label: "Wisteria"
54
+ }, {
55
+ value: "#616161",
56
+ label: "Graphite"
57
+ }, {
58
+ value: "#e67c73",
59
+ label: "Flamingo"
60
+ }, {
61
+ value: "#f6bf26",
62
+ label: "Banana"
63
+ }, {
64
+ value: "#33b679",
65
+ label: "Sage"
66
+ }, {
67
+ value: "#4285f4",
68
+ label: "Cobalt"
69
+ }, {
70
+ value: "#9e69af",
71
+ label: "Amethyst"
72
+ }, {
73
+ value: "#a79b8e",
74
+ label: "Birch"
75
+ }];
76
+ const DEFAULT_LABELS = {
77
+ trigger: "Choose color",
78
+ palette: "Colors",
79
+ addCustom: "Add custom color",
80
+ customTitle: "Choose custom color",
81
+ customDescription: "Choose a background color. The text color will be adjusted automatically.",
82
+ preview: "A",
83
+ hex: "Hex",
84
+ eyeDropper: "Pick a color from the screen",
85
+ saturation: "Saturation and brightness",
86
+ hue: "Hue",
87
+ cancel: "Cancel",
88
+ save: "Save"
89
+ };
90
+
91
+ exports.COLOR_PICKER_PRESETS = COLOR_PICKER_PRESETS;
92
+ exports.DEFAULT_LABELS = DEFAULT_LABELS;
@@ -0,0 +1,25 @@
1
+ /** h: 0–360, s: 0–100, v: 0–100 */
2
+ export interface HSV {
3
+ h: number;
4
+ s: number;
5
+ v: number;
6
+ }
7
+ export declare const clamp: (value: number, min?: number, max?: number) => number;
8
+ /** HSV → `hsl(...)` for inline styles. */
9
+ export declare const hsv2css: ({ h, s, v }: HSV) => string;
10
+ /** `#ABC`, `abc`, `#aabbcc` → `#aabbcc`. Invalid input → `null`. */
11
+ export declare const normalizeHex: (input: string) => string | null;
12
+ export declare const hsv2hex: (hsv: HSV) => string;
13
+ export declare const hex2hsv: (hex: string) => HSV | null;
14
+ /** HEX or `rgb()`/`rgba()` → `#rrggbb`. Invalid input → `null`. */
15
+ export declare const toHex: (input: string) => string | null;
16
+ /**
17
+ * HEX → HSV that keeps hue and saturation from `prev` where the color has
18
+ * none: grey has no hue, black has neither. Without this, typing `#000000`
19
+ * would jump the hue slider to 0 (red).
20
+ */
21
+ export declare const toHsvPreservingHue: (hex: string, prev: HSV) => HSV | null;
22
+ /** Whether light text reads better than dark text on `background` (HEX). */
23
+ export declare const prefersLightText: (background: string) => boolean;
24
+ /** A light color that merges with a light surface and needs an outline. */
25
+ export declare const isLightColor: (hex: string, threshold?: number) => boolean;