@kopexa/color-picker 0.0.38 → 0.0.39
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/chunk-CRQDZQE6.mjs +30 -0
- package/dist/{chunk-GSZMYL3E.mjs → chunk-QFIB6TFB.mjs} +82 -17
- package/dist/color-picker-field.d.mts +12 -3
- package/dist/color-picker-field.d.ts +12 -3
- package/dist/color-picker-field.js +91 -18
- package/dist/color-picker-field.mjs +2 -2
- package/dist/index.js +91 -18
- package/dist/index.mjs +2 -2
- package/dist/messages.d.mts +8 -0
- package/dist/messages.d.ts +8 -0
- package/dist/messages.js +11 -3
- package/dist/messages.mjs +1 -1
- package/package.json +4 -4
- package/dist/chunk-JFALBXTO.mjs +0 -22
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/messages.ts
|
|
4
|
+
import { defineMessages } from "@kopexa/i18n";
|
|
5
|
+
var messages = defineMessages({
|
|
6
|
+
label: {
|
|
7
|
+
id: "color-picker.label",
|
|
8
|
+
defaultMessage: "Color",
|
|
9
|
+
description: "Generic label for a color field"
|
|
10
|
+
},
|
|
11
|
+
hexLabel: {
|
|
12
|
+
id: "color-picker.hex_label",
|
|
13
|
+
defaultMessage: "Hex",
|
|
14
|
+
description: "Label for the hex input inside the color picker popover"
|
|
15
|
+
},
|
|
16
|
+
pickColor: {
|
|
17
|
+
id: "color-picker.pick_color",
|
|
18
|
+
defaultMessage: "Pick a color",
|
|
19
|
+
description: "Prompt to pick a color"
|
|
20
|
+
},
|
|
21
|
+
clear: {
|
|
22
|
+
id: "color-picker.clear",
|
|
23
|
+
defaultMessage: "Clear",
|
|
24
|
+
description: "Button inside the color picker popover that resets the field to its unset state"
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
messages
|
|
30
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
messages
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CRQDZQE6.mjs";
|
|
5
5
|
|
|
6
6
|
// src/color-picker-field.tsx
|
|
7
7
|
import { useSafeIntl } from "@kopexa/i18n";
|
|
8
8
|
import { cn } from "@kopexa/shared-utils";
|
|
9
|
-
import { useState } from "react";
|
|
9
|
+
import { useEffect, useState } from "react";
|
|
10
10
|
import {
|
|
11
11
|
Button as AriaButton,
|
|
12
12
|
ColorArea,
|
|
@@ -38,35 +38,70 @@ var DEFAULT_PRESETS = [
|
|
|
38
38
|
"#6366f1",
|
|
39
39
|
"#a855f7"
|
|
40
40
|
];
|
|
41
|
+
var UNSET_FALLBACK = "#ffffff";
|
|
42
|
+
var safeParseColor = (hex) => {
|
|
43
|
+
try {
|
|
44
|
+
return parseColor(hex);
|
|
45
|
+
} catch {
|
|
46
|
+
return parseColor(UNSET_FALLBACK);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
41
49
|
function ColorPickerField({
|
|
42
50
|
value,
|
|
43
|
-
defaultValue
|
|
51
|
+
defaultValue,
|
|
44
52
|
onChange,
|
|
45
53
|
presets = DEFAULT_PRESETS,
|
|
46
54
|
hidePresets = false,
|
|
47
55
|
hideHexInput = false,
|
|
48
56
|
triggerClassName,
|
|
49
57
|
triggerContent,
|
|
50
|
-
isDisabled = false
|
|
58
|
+
isDisabled = false,
|
|
59
|
+
allowClear = true
|
|
51
60
|
}) {
|
|
52
61
|
const intl = useSafeIntl();
|
|
53
62
|
const t = {
|
|
54
|
-
hexLabel: intl.formatMessage(messages.hexLabel)
|
|
55
|
-
|
|
56
|
-
const safeParseColor = (hex) => {
|
|
57
|
-
try {
|
|
58
|
-
return parseColor(hex);
|
|
59
|
-
} catch {
|
|
60
|
-
return parseColor("#3b82f6");
|
|
61
|
-
}
|
|
63
|
+
hexLabel: intl.formatMessage(messages.hexLabel),
|
|
64
|
+
clear: intl.formatMessage(messages.clear)
|
|
62
65
|
};
|
|
66
|
+
const initialHex = value != null ? value : defaultValue;
|
|
63
67
|
const [color, setColor] = useState(
|
|
64
|
-
() => safeParseColor(
|
|
68
|
+
() => safeParseColor(initialHex != null ? initialHex : UNSET_FALLBACK)
|
|
65
69
|
);
|
|
70
|
+
const [hasColor, setHasColor] = useState(!!initialHex);
|
|
71
|
+
const [hexDraft, setHexDraft] = useState("");
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (value === void 0) return;
|
|
74
|
+
if (value) {
|
|
75
|
+
setColor(safeParseColor(value));
|
|
76
|
+
setHasColor(true);
|
|
77
|
+
} else {
|
|
78
|
+
setColor(parseColor(UNSET_FALLBACK));
|
|
79
|
+
setHasColor(false);
|
|
80
|
+
}
|
|
81
|
+
}, [value]);
|
|
66
82
|
const handleChange = (newColor) => {
|
|
67
83
|
setColor(newColor);
|
|
84
|
+
setHasColor(true);
|
|
68
85
|
onChange == null ? void 0 : onChange(newColor.toString("hex"));
|
|
69
86
|
};
|
|
87
|
+
const handleClear = () => {
|
|
88
|
+
setColor(parseColor(UNSET_FALLBACK));
|
|
89
|
+
setHasColor(false);
|
|
90
|
+
setHexDraft("");
|
|
91
|
+
onChange == null ? void 0 : onChange("");
|
|
92
|
+
};
|
|
93
|
+
const commitHexDraft = () => {
|
|
94
|
+
const trimmed = hexDraft.trim();
|
|
95
|
+
if (!trimmed) return;
|
|
96
|
+
try {
|
|
97
|
+
const parsed = parseColor(
|
|
98
|
+
trimmed.startsWith("#") ? trimmed : `#${trimmed}`
|
|
99
|
+
);
|
|
100
|
+
handleChange(parsed);
|
|
101
|
+
setHexDraft("");
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
};
|
|
70
105
|
const hexValue = color.toString("hex");
|
|
71
106
|
const triggerClasses = cn(
|
|
72
107
|
"flex h-10 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm",
|
|
@@ -76,9 +111,12 @@ function ColorPickerField({
|
|
|
76
111
|
triggerClassName
|
|
77
112
|
);
|
|
78
113
|
return /* @__PURE__ */ jsx(ColorPicker, { value: color, onChange: handleChange, children: /* @__PURE__ */ jsxs(DialogTrigger, { children: [
|
|
79
|
-
/* @__PURE__ */ jsx(AriaButton, { className: triggerClasses, isDisabled, children: triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
114
|
+
/* @__PURE__ */ jsx(AriaButton, { className: triggerClasses, isDisabled, children: triggerContent != null ? triggerContent : hasColor ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
80
115
|
/* @__PURE__ */ jsx(ColorSwatch, { className: "size-5 rounded border" }),
|
|
81
116
|
/* @__PURE__ */ jsx("span", { className: "font-mono", children: hexValue })
|
|
117
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
118
|
+
/* @__PURE__ */ jsx("div", { className: "size-5 rounded border border-dashed border-muted-foreground/40 bg-transparent" }),
|
|
119
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-muted-foreground", children: "\u2014" })
|
|
82
120
|
] }) }),
|
|
83
121
|
/* @__PURE__ */ jsx(
|
|
84
122
|
Popover,
|
|
@@ -99,11 +137,38 @@ function ColorPickerField({
|
|
|
99
137
|
),
|
|
100
138
|
/* @__PURE__ */ jsx(ColorSlider, { colorSpace: "hsb", channel: "hue", children: /* @__PURE__ */ jsx(SliderTrack, { className: "h-7 w-[192px] rounded-t-none rounded-b-md border border-t-0", children: /* @__PURE__ */ jsx(ColorThumb, { className: "top-1/2 size-5 rounded-full border-2 border-white shadow-md" }) }) })
|
|
101
139
|
] }),
|
|
102
|
-
!hideHexInput && /* @__PURE__ */ jsxs(ColorField, { colorSpace: "hsb", className: "flex flex-col gap-1", children: [
|
|
140
|
+
!hideHexInput && (hasColor ? /* @__PURE__ */ jsxs(ColorField, { colorSpace: "hsb", className: "flex flex-col gap-1", children: [
|
|
103
141
|
/* @__PURE__ */ jsx(Label, { className: "text-sm", children: t.hexLabel }),
|
|
104
142
|
/* @__PURE__ */ jsx(Input, { className: "h-9 w-[192px] rounded-md border border-input bg-background px-3 font-mono text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" })
|
|
105
|
-
] }),
|
|
106
|
-
|
|
143
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
144
|
+
/* @__PURE__ */ jsx(Label, { className: "text-sm text-muted-foreground/60", children: t.hexLabel }),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
"input",
|
|
147
|
+
{
|
|
148
|
+
type: "text",
|
|
149
|
+
value: hexDraft,
|
|
150
|
+
onChange: (e) => setHexDraft(e.target.value),
|
|
151
|
+
onBlur: commitHexDraft,
|
|
152
|
+
onKeyDown: (e) => {
|
|
153
|
+
if (e.key === "Enter") {
|
|
154
|
+
e.preventDefault();
|
|
155
|
+
commitHexDraft();
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
placeholder: "#FFFFFF",
|
|
159
|
+
className: "h-9 w-[192px] rounded-md border border-input bg-background px-3 font-mono text-sm placeholder:text-muted-foreground/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] })),
|
|
163
|
+
!hidePresets && presets.length > 0 && /* @__PURE__ */ jsx(ColorSwatchPicker, { className: "grid w-[192px] grid-cols-5 gap-1", children: presets.map((preset) => /* @__PURE__ */ jsx(ColorSwatchPickerItem, { color: preset, children: /* @__PURE__ */ jsx(ColorSwatch, { className: "size-8 rounded border" }) }, preset)) }),
|
|
164
|
+
allowClear && hasColor && /* @__PURE__ */ jsx(
|
|
165
|
+
AriaButton,
|
|
166
|
+
{
|
|
167
|
+
onPress: handleClear,
|
|
168
|
+
className: "w-[192px] rounded-md px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
169
|
+
children: t.clear
|
|
170
|
+
}
|
|
171
|
+
)
|
|
107
172
|
] })
|
|
108
173
|
}
|
|
109
174
|
)
|
|
@@ -3,11 +3,13 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
|
|
4
4
|
interface ColorPickerFieldProps {
|
|
5
5
|
/**
|
|
6
|
-
* The current color value (hex string like "#ff0000")
|
|
6
|
+
* The current color value (hex string like "#ff0000").
|
|
7
|
+
* If falsy, the trigger shows an "unset" state instead of a color.
|
|
7
8
|
*/
|
|
8
9
|
value?: string;
|
|
9
10
|
/**
|
|
10
|
-
* The default color value for uncontrolled usage
|
|
11
|
+
* The default color value for uncontrolled usage.
|
|
12
|
+
* If not provided, the field starts in an "unset" state.
|
|
11
13
|
*/
|
|
12
14
|
defaultValue?: string;
|
|
13
15
|
/**
|
|
@@ -44,11 +46,18 @@ interface ColorPickerFieldProps {
|
|
|
44
46
|
* Whether the field is disabled
|
|
45
47
|
*/
|
|
46
48
|
isDisabled?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Whether to show a "Clear" button in the popover that resets the field
|
|
51
|
+
* to its unset state. The button is only rendered when a color is actually
|
|
52
|
+
* set. Click emits `onChange("")`.
|
|
53
|
+
* @default true
|
|
54
|
+
*/
|
|
55
|
+
allowClear?: boolean;
|
|
47
56
|
}
|
|
48
57
|
/**
|
|
49
58
|
* A high-level color picker field.
|
|
50
59
|
* Uses react-aria-components directly to ensure proper context handling.
|
|
51
60
|
*/
|
|
52
|
-
declare function ColorPickerField({ value, defaultValue, onChange, presets, hidePresets, hideHexInput, triggerClassName, triggerContent, isDisabled, }: ColorPickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
61
|
+
declare function ColorPickerField({ value, defaultValue, onChange, presets, hidePresets, hideHexInput, triggerClassName, triggerContent, isDisabled, allowClear, }: ColorPickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
53
62
|
|
|
54
63
|
export { ColorPickerField, type ColorPickerFieldProps };
|
|
@@ -3,11 +3,13 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
|
|
4
4
|
interface ColorPickerFieldProps {
|
|
5
5
|
/**
|
|
6
|
-
* The current color value (hex string like "#ff0000")
|
|
6
|
+
* The current color value (hex string like "#ff0000").
|
|
7
|
+
* If falsy, the trigger shows an "unset" state instead of a color.
|
|
7
8
|
*/
|
|
8
9
|
value?: string;
|
|
9
10
|
/**
|
|
10
|
-
* The default color value for uncontrolled usage
|
|
11
|
+
* The default color value for uncontrolled usage.
|
|
12
|
+
* If not provided, the field starts in an "unset" state.
|
|
11
13
|
*/
|
|
12
14
|
defaultValue?: string;
|
|
13
15
|
/**
|
|
@@ -44,11 +46,18 @@ interface ColorPickerFieldProps {
|
|
|
44
46
|
* Whether the field is disabled
|
|
45
47
|
*/
|
|
46
48
|
isDisabled?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Whether to show a "Clear" button in the popover that resets the field
|
|
51
|
+
* to its unset state. The button is only rendered when a color is actually
|
|
52
|
+
* set. Click emits `onChange("")`.
|
|
53
|
+
* @default true
|
|
54
|
+
*/
|
|
55
|
+
allowClear?: boolean;
|
|
47
56
|
}
|
|
48
57
|
/**
|
|
49
58
|
* A high-level color picker field.
|
|
50
59
|
* Uses react-aria-components directly to ensure proper context handling.
|
|
51
60
|
*/
|
|
52
|
-
declare function ColorPickerField({ value, defaultValue, onChange, presets, hidePresets, hideHexInput, triggerClassName, triggerContent, isDisabled, }: ColorPickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
61
|
+
declare function ColorPickerField({ value, defaultValue, onChange, presets, hidePresets, hideHexInput, triggerClassName, triggerContent, isDisabled, allowClear, }: ColorPickerFieldProps): react_jsx_runtime.JSX.Element;
|
|
53
62
|
|
|
54
63
|
export { ColorPickerField, type ColorPickerFieldProps };
|
|
@@ -35,15 +35,23 @@ var import_i18n = require("@kopexa/i18n");
|
|
|
35
35
|
var messages = (0, import_i18n.defineMessages)({
|
|
36
36
|
label: {
|
|
37
37
|
id: "color-picker.label",
|
|
38
|
-
defaultMessage: "Color"
|
|
38
|
+
defaultMessage: "Color",
|
|
39
|
+
description: "Generic label for a color field"
|
|
39
40
|
},
|
|
40
41
|
hexLabel: {
|
|
41
42
|
id: "color-picker.hex_label",
|
|
42
|
-
defaultMessage: "Hex"
|
|
43
|
+
defaultMessage: "Hex",
|
|
44
|
+
description: "Label for the hex input inside the color picker popover"
|
|
43
45
|
},
|
|
44
46
|
pickColor: {
|
|
45
47
|
id: "color-picker.pick_color",
|
|
46
|
-
defaultMessage: "Pick a color"
|
|
48
|
+
defaultMessage: "Pick a color",
|
|
49
|
+
description: "Prompt to pick a color"
|
|
50
|
+
},
|
|
51
|
+
clear: {
|
|
52
|
+
id: "color-picker.clear",
|
|
53
|
+
defaultMessage: "Clear",
|
|
54
|
+
description: "Button inside the color picker popover that resets the field to its unset state"
|
|
47
55
|
}
|
|
48
56
|
});
|
|
49
57
|
|
|
@@ -61,35 +69,70 @@ var DEFAULT_PRESETS = [
|
|
|
61
69
|
"#6366f1",
|
|
62
70
|
"#a855f7"
|
|
63
71
|
];
|
|
72
|
+
var UNSET_FALLBACK = "#ffffff";
|
|
73
|
+
var safeParseColor = (hex) => {
|
|
74
|
+
try {
|
|
75
|
+
return (0, import_react_aria_components.parseColor)(hex);
|
|
76
|
+
} catch {
|
|
77
|
+
return (0, import_react_aria_components.parseColor)(UNSET_FALLBACK);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
64
80
|
function ColorPickerField({
|
|
65
81
|
value,
|
|
66
|
-
defaultValue
|
|
82
|
+
defaultValue,
|
|
67
83
|
onChange,
|
|
68
84
|
presets = DEFAULT_PRESETS,
|
|
69
85
|
hidePresets = false,
|
|
70
86
|
hideHexInput = false,
|
|
71
87
|
triggerClassName,
|
|
72
88
|
triggerContent,
|
|
73
|
-
isDisabled = false
|
|
89
|
+
isDisabled = false,
|
|
90
|
+
allowClear = true
|
|
74
91
|
}) {
|
|
75
92
|
const intl = (0, import_i18n2.useSafeIntl)();
|
|
76
93
|
const t = {
|
|
77
|
-
hexLabel: intl.formatMessage(messages.hexLabel)
|
|
78
|
-
|
|
79
|
-
const safeParseColor = (hex) => {
|
|
80
|
-
try {
|
|
81
|
-
return (0, import_react_aria_components.parseColor)(hex);
|
|
82
|
-
} catch {
|
|
83
|
-
return (0, import_react_aria_components.parseColor)("#3b82f6");
|
|
84
|
-
}
|
|
94
|
+
hexLabel: intl.formatMessage(messages.hexLabel),
|
|
95
|
+
clear: intl.formatMessage(messages.clear)
|
|
85
96
|
};
|
|
97
|
+
const initialHex = value != null ? value : defaultValue;
|
|
86
98
|
const [color, setColor] = (0, import_react.useState)(
|
|
87
|
-
() => safeParseColor(
|
|
99
|
+
() => safeParseColor(initialHex != null ? initialHex : UNSET_FALLBACK)
|
|
88
100
|
);
|
|
101
|
+
const [hasColor, setHasColor] = (0, import_react.useState)(!!initialHex);
|
|
102
|
+
const [hexDraft, setHexDraft] = (0, import_react.useState)("");
|
|
103
|
+
(0, import_react.useEffect)(() => {
|
|
104
|
+
if (value === void 0) return;
|
|
105
|
+
if (value) {
|
|
106
|
+
setColor(safeParseColor(value));
|
|
107
|
+
setHasColor(true);
|
|
108
|
+
} else {
|
|
109
|
+
setColor((0, import_react_aria_components.parseColor)(UNSET_FALLBACK));
|
|
110
|
+
setHasColor(false);
|
|
111
|
+
}
|
|
112
|
+
}, [value]);
|
|
89
113
|
const handleChange = (newColor) => {
|
|
90
114
|
setColor(newColor);
|
|
115
|
+
setHasColor(true);
|
|
91
116
|
onChange == null ? void 0 : onChange(newColor.toString("hex"));
|
|
92
117
|
};
|
|
118
|
+
const handleClear = () => {
|
|
119
|
+
setColor((0, import_react_aria_components.parseColor)(UNSET_FALLBACK));
|
|
120
|
+
setHasColor(false);
|
|
121
|
+
setHexDraft("");
|
|
122
|
+
onChange == null ? void 0 : onChange("");
|
|
123
|
+
};
|
|
124
|
+
const commitHexDraft = () => {
|
|
125
|
+
const trimmed = hexDraft.trim();
|
|
126
|
+
if (!trimmed) return;
|
|
127
|
+
try {
|
|
128
|
+
const parsed = (0, import_react_aria_components.parseColor)(
|
|
129
|
+
trimmed.startsWith("#") ? trimmed : `#${trimmed}`
|
|
130
|
+
);
|
|
131
|
+
handleChange(parsed);
|
|
132
|
+
setHexDraft("");
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
};
|
|
93
136
|
const hexValue = color.toString("hex");
|
|
94
137
|
const triggerClasses = (0, import_shared_utils.cn)(
|
|
95
138
|
"flex h-10 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm",
|
|
@@ -99,9 +142,12 @@ function ColorPickerField({
|
|
|
99
142
|
triggerClassName
|
|
100
143
|
);
|
|
101
144
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorPicker, { value: color, onChange: handleChange, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_aria_components.DialogTrigger, { children: [
|
|
102
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.Button, { className: triggerClasses, isDisabled, children: triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
145
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.Button, { className: triggerClasses, isDisabled, children: triggerContent != null ? triggerContent : hasColor ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
103
146
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorSwatch, { className: "size-5 rounded border" }),
|
|
104
147
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "font-mono", children: hexValue })
|
|
148
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
149
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "size-5 rounded border border-dashed border-muted-foreground/40 bg-transparent" }),
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "font-mono text-muted-foreground", children: "\u2014" })
|
|
105
151
|
] }) }),
|
|
106
152
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
107
153
|
import_react_aria_components.Popover,
|
|
@@ -122,11 +168,38 @@ function ColorPickerField({
|
|
|
122
168
|
),
|
|
123
169
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorSlider, { colorSpace: "hsb", channel: "hue", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.SliderTrack, { className: "h-7 w-[192px] rounded-t-none rounded-b-md border border-t-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorThumb, { className: "top-1/2 size-5 rounded-full border-2 border-white shadow-md" }) }) })
|
|
124
170
|
] }),
|
|
125
|
-
!hideHexInput && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_aria_components.ColorField, { colorSpace: "hsb", className: "flex flex-col gap-1", children: [
|
|
171
|
+
!hideHexInput && (hasColor ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_aria_components.ColorField, { colorSpace: "hsb", className: "flex flex-col gap-1", children: [
|
|
126
172
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.Label, { className: "text-sm", children: t.hexLabel }),
|
|
127
173
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.Input, { className: "h-9 w-[192px] rounded-md border border-input bg-background px-3 font-mono text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" })
|
|
128
|
-
] }),
|
|
129
|
-
|
|
174
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
175
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.Label, { className: "text-sm text-muted-foreground/60", children: t.hexLabel }),
|
|
176
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
177
|
+
"input",
|
|
178
|
+
{
|
|
179
|
+
type: "text",
|
|
180
|
+
value: hexDraft,
|
|
181
|
+
onChange: (e) => setHexDraft(e.target.value),
|
|
182
|
+
onBlur: commitHexDraft,
|
|
183
|
+
onKeyDown: (e) => {
|
|
184
|
+
if (e.key === "Enter") {
|
|
185
|
+
e.preventDefault();
|
|
186
|
+
commitHexDraft();
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
placeholder: "#FFFFFF",
|
|
190
|
+
className: "h-9 w-[192px] rounded-md border border-input bg-background px-3 font-mono text-sm placeholder:text-muted-foreground/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
] })),
|
|
194
|
+
!hidePresets && presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorSwatchPicker, { className: "grid w-[192px] grid-cols-5 gap-1", children: presets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorSwatchPickerItem, { color: preset, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_aria_components.ColorSwatch, { className: "size-8 rounded border" }) }, preset)) }),
|
|
195
|
+
allowClear && hasColor && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
196
|
+
import_react_aria_components.Button,
|
|
197
|
+
{
|
|
198
|
+
onPress: handleClear,
|
|
199
|
+
className: "w-[192px] rounded-md px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
200
|
+
children: t.clear
|
|
201
|
+
}
|
|
202
|
+
)
|
|
130
203
|
] })
|
|
131
204
|
}
|
|
132
205
|
)
|
package/dist/index.js
CHANGED
|
@@ -169,15 +169,23 @@ var import_i18n = require("@kopexa/i18n");
|
|
|
169
169
|
var messages = (0, import_i18n.defineMessages)({
|
|
170
170
|
label: {
|
|
171
171
|
id: "color-picker.label",
|
|
172
|
-
defaultMessage: "Color"
|
|
172
|
+
defaultMessage: "Color",
|
|
173
|
+
description: "Generic label for a color field"
|
|
173
174
|
},
|
|
174
175
|
hexLabel: {
|
|
175
176
|
id: "color-picker.hex_label",
|
|
176
|
-
defaultMessage: "Hex"
|
|
177
|
+
defaultMessage: "Hex",
|
|
178
|
+
description: "Label for the hex input inside the color picker popover"
|
|
177
179
|
},
|
|
178
180
|
pickColor: {
|
|
179
181
|
id: "color-picker.pick_color",
|
|
180
|
-
defaultMessage: "Pick a color"
|
|
182
|
+
defaultMessage: "Pick a color",
|
|
183
|
+
description: "Prompt to pick a color"
|
|
184
|
+
},
|
|
185
|
+
clear: {
|
|
186
|
+
id: "color-picker.clear",
|
|
187
|
+
defaultMessage: "Clear",
|
|
188
|
+
description: "Button inside the color picker popover that resets the field to its unset state"
|
|
181
189
|
}
|
|
182
190
|
});
|
|
183
191
|
|
|
@@ -195,35 +203,70 @@ var DEFAULT_PRESETS = [
|
|
|
195
203
|
"#6366f1",
|
|
196
204
|
"#a855f7"
|
|
197
205
|
];
|
|
206
|
+
var UNSET_FALLBACK = "#ffffff";
|
|
207
|
+
var safeParseColor = (hex) => {
|
|
208
|
+
try {
|
|
209
|
+
return (0, import_react_aria_components2.parseColor)(hex);
|
|
210
|
+
} catch {
|
|
211
|
+
return (0, import_react_aria_components2.parseColor)(UNSET_FALLBACK);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
198
214
|
function ColorPickerField({
|
|
199
215
|
value,
|
|
200
|
-
defaultValue
|
|
216
|
+
defaultValue,
|
|
201
217
|
onChange,
|
|
202
218
|
presets = DEFAULT_PRESETS,
|
|
203
219
|
hidePresets = false,
|
|
204
220
|
hideHexInput = false,
|
|
205
221
|
triggerClassName,
|
|
206
222
|
triggerContent,
|
|
207
|
-
isDisabled = false
|
|
223
|
+
isDisabled = false,
|
|
224
|
+
allowClear = true
|
|
208
225
|
}) {
|
|
209
226
|
const intl = (0, import_i18n2.useSafeIntl)();
|
|
210
227
|
const t = {
|
|
211
|
-
hexLabel: intl.formatMessage(messages.hexLabel)
|
|
212
|
-
|
|
213
|
-
const safeParseColor = (hex) => {
|
|
214
|
-
try {
|
|
215
|
-
return (0, import_react_aria_components2.parseColor)(hex);
|
|
216
|
-
} catch {
|
|
217
|
-
return (0, import_react_aria_components2.parseColor)("#3b82f6");
|
|
218
|
-
}
|
|
228
|
+
hexLabel: intl.formatMessage(messages.hexLabel),
|
|
229
|
+
clear: intl.formatMessage(messages.clear)
|
|
219
230
|
};
|
|
231
|
+
const initialHex = value != null ? value : defaultValue;
|
|
220
232
|
const [color, setColor] = (0, import_react.useState)(
|
|
221
|
-
() => safeParseColor(
|
|
233
|
+
() => safeParseColor(initialHex != null ? initialHex : UNSET_FALLBACK)
|
|
222
234
|
);
|
|
235
|
+
const [hasColor, setHasColor] = (0, import_react.useState)(!!initialHex);
|
|
236
|
+
const [hexDraft, setHexDraft] = (0, import_react.useState)("");
|
|
237
|
+
(0, import_react.useEffect)(() => {
|
|
238
|
+
if (value === void 0) return;
|
|
239
|
+
if (value) {
|
|
240
|
+
setColor(safeParseColor(value));
|
|
241
|
+
setHasColor(true);
|
|
242
|
+
} else {
|
|
243
|
+
setColor((0, import_react_aria_components2.parseColor)(UNSET_FALLBACK));
|
|
244
|
+
setHasColor(false);
|
|
245
|
+
}
|
|
246
|
+
}, [value]);
|
|
223
247
|
const handleChange = (newColor) => {
|
|
224
248
|
setColor(newColor);
|
|
249
|
+
setHasColor(true);
|
|
225
250
|
onChange == null ? void 0 : onChange(newColor.toString("hex"));
|
|
226
251
|
};
|
|
252
|
+
const handleClear = () => {
|
|
253
|
+
setColor((0, import_react_aria_components2.parseColor)(UNSET_FALLBACK));
|
|
254
|
+
setHasColor(false);
|
|
255
|
+
setHexDraft("");
|
|
256
|
+
onChange == null ? void 0 : onChange("");
|
|
257
|
+
};
|
|
258
|
+
const commitHexDraft = () => {
|
|
259
|
+
const trimmed = hexDraft.trim();
|
|
260
|
+
if (!trimmed) return;
|
|
261
|
+
try {
|
|
262
|
+
const parsed = (0, import_react_aria_components2.parseColor)(
|
|
263
|
+
trimmed.startsWith("#") ? trimmed : `#${trimmed}`
|
|
264
|
+
);
|
|
265
|
+
handleChange(parsed);
|
|
266
|
+
setHexDraft("");
|
|
267
|
+
} catch {
|
|
268
|
+
}
|
|
269
|
+
};
|
|
227
270
|
const hexValue = color.toString("hex");
|
|
228
271
|
const triggerClasses = (0, import_shared_utils2.cn)(
|
|
229
272
|
"flex h-10 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm",
|
|
@@ -233,9 +276,12 @@ function ColorPickerField({
|
|
|
233
276
|
triggerClassName
|
|
234
277
|
);
|
|
235
278
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorPicker, { value: color, onChange: handleChange, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_aria_components2.DialogTrigger, { children: [
|
|
236
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.Button, { className: triggerClasses, isDisabled, children: triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
279
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.Button, { className: triggerClasses, isDisabled, children: triggerContent != null ? triggerContent : hasColor ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
237
280
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorSwatch, { className: "size-5 rounded border" }),
|
|
238
281
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-mono", children: hexValue })
|
|
282
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
283
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "size-5 rounded border border-dashed border-muted-foreground/40 bg-transparent" }),
|
|
284
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-mono text-muted-foreground", children: "\u2014" })
|
|
239
285
|
] }) }),
|
|
240
286
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
241
287
|
import_react_aria_components2.Popover,
|
|
@@ -256,11 +302,38 @@ function ColorPickerField({
|
|
|
256
302
|
),
|
|
257
303
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorSlider, { colorSpace: "hsb", channel: "hue", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.SliderTrack, { className: "h-7 w-[192px] rounded-t-none rounded-b-md border border-t-0", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorThumb, { className: "top-1/2 size-5 rounded-full border-2 border-white shadow-md" }) }) })
|
|
258
304
|
] }),
|
|
259
|
-
!hideHexInput && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_aria_components2.ColorField, { colorSpace: "hsb", className: "flex flex-col gap-1", children: [
|
|
305
|
+
!hideHexInput && (hasColor ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_aria_components2.ColorField, { colorSpace: "hsb", className: "flex flex-col gap-1", children: [
|
|
260
306
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.Label, { className: "text-sm", children: t.hexLabel }),
|
|
261
307
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.Input, { className: "h-9 w-[192px] rounded-md border border-input bg-background px-3 font-mono text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" })
|
|
262
|
-
] }),
|
|
263
|
-
|
|
308
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
309
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.Label, { className: "text-sm text-muted-foreground/60", children: t.hexLabel }),
|
|
310
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
311
|
+
"input",
|
|
312
|
+
{
|
|
313
|
+
type: "text",
|
|
314
|
+
value: hexDraft,
|
|
315
|
+
onChange: (e) => setHexDraft(e.target.value),
|
|
316
|
+
onBlur: commitHexDraft,
|
|
317
|
+
onKeyDown: (e) => {
|
|
318
|
+
if (e.key === "Enter") {
|
|
319
|
+
e.preventDefault();
|
|
320
|
+
commitHexDraft();
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
placeholder: "#FFFFFF",
|
|
324
|
+
className: "h-9 w-[192px] rounded-md border border-input bg-background px-3 font-mono text-sm placeholder:text-muted-foreground/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
325
|
+
}
|
|
326
|
+
)
|
|
327
|
+
] })),
|
|
328
|
+
!hidePresets && presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorSwatchPicker, { className: "grid w-[192px] grid-cols-5 gap-1", children: presets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorSwatchPickerItem, { color: preset, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_aria_components2.ColorSwatch, { className: "size-8 rounded border" }) }, preset)) }),
|
|
329
|
+
allowClear && hasColor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
330
|
+
import_react_aria_components2.Button,
|
|
331
|
+
{
|
|
332
|
+
onPress: handleClear,
|
|
333
|
+
className: "w-[192px] rounded-md px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
334
|
+
children: t.clear
|
|
335
|
+
}
|
|
336
|
+
)
|
|
264
337
|
] })
|
|
265
338
|
}
|
|
266
339
|
)
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
ColorPickerField
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QFIB6TFB.mjs";
|
|
5
5
|
import {
|
|
6
6
|
ColorArea,
|
|
7
7
|
ColorField,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
SliderOutput,
|
|
17
17
|
SliderTrack
|
|
18
18
|
} from "./chunk-EA7FR3KG.mjs";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-CRQDZQE6.mjs";
|
|
20
20
|
export {
|
|
21
21
|
ColorArea,
|
|
22
22
|
ColorField,
|
package/dist/messages.d.mts
CHANGED
|
@@ -2,14 +2,22 @@ declare const messages: {
|
|
|
2
2
|
label: {
|
|
3
3
|
id: string;
|
|
4
4
|
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
5
6
|
};
|
|
6
7
|
hexLabel: {
|
|
7
8
|
id: string;
|
|
8
9
|
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
9
11
|
};
|
|
10
12
|
pickColor: {
|
|
11
13
|
id: string;
|
|
12
14
|
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
clear: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
13
21
|
};
|
|
14
22
|
};
|
|
15
23
|
|
package/dist/messages.d.ts
CHANGED
|
@@ -2,14 +2,22 @@ declare const messages: {
|
|
|
2
2
|
label: {
|
|
3
3
|
id: string;
|
|
4
4
|
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
5
6
|
};
|
|
6
7
|
hexLabel: {
|
|
7
8
|
id: string;
|
|
8
9
|
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
9
11
|
};
|
|
10
12
|
pickColor: {
|
|
11
13
|
id: string;
|
|
12
14
|
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
clear: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
13
21
|
};
|
|
14
22
|
};
|
|
15
23
|
|
package/dist/messages.js
CHANGED
|
@@ -28,15 +28,23 @@ var import_i18n = require("@kopexa/i18n");
|
|
|
28
28
|
var messages = (0, import_i18n.defineMessages)({
|
|
29
29
|
label: {
|
|
30
30
|
id: "color-picker.label",
|
|
31
|
-
defaultMessage: "Color"
|
|
31
|
+
defaultMessage: "Color",
|
|
32
|
+
description: "Generic label for a color field"
|
|
32
33
|
},
|
|
33
34
|
hexLabel: {
|
|
34
35
|
id: "color-picker.hex_label",
|
|
35
|
-
defaultMessage: "Hex"
|
|
36
|
+
defaultMessage: "Hex",
|
|
37
|
+
description: "Label for the hex input inside the color picker popover"
|
|
36
38
|
},
|
|
37
39
|
pickColor: {
|
|
38
40
|
id: "color-picker.pick_color",
|
|
39
|
-
defaultMessage: "Pick a color"
|
|
41
|
+
defaultMessage: "Pick a color",
|
|
42
|
+
description: "Prompt to pick a color"
|
|
43
|
+
},
|
|
44
|
+
clear: {
|
|
45
|
+
id: "color-picker.clear",
|
|
46
|
+
defaultMessage: "Clear",
|
|
47
|
+
description: "Button inside the color picker popover that resets the field to its unset state"
|
|
40
48
|
}
|
|
41
49
|
});
|
|
42
50
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/messages.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kopexa/color-picker",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"description": "Color picker components for selecting and managing colors.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"color-picker",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"react": ">=19.0.0-rc.0",
|
|
31
31
|
"react-dom": ">=19.0.0-rc.0",
|
|
32
|
-
"@kopexa/theme": "17.29.
|
|
32
|
+
"@kopexa/theme": "17.29.1"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"react-aria-components": "^1.7.1",
|
|
36
|
-
"@kopexa/i18n": "17.
|
|
37
|
-
"@kopexa/shared-utils": "17.0.
|
|
36
|
+
"@kopexa/i18n": "17.14.0",
|
|
37
|
+
"@kopexa/shared-utils": "17.0.80"
|
|
38
38
|
},
|
|
39
39
|
"clean-package": "../../../clean-package.config.json",
|
|
40
40
|
"module": "dist/index.mjs",
|
package/dist/chunk-JFALBXTO.mjs
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
// src/messages.ts
|
|
4
|
-
import { defineMessages } from "@kopexa/i18n";
|
|
5
|
-
var messages = defineMessages({
|
|
6
|
-
label: {
|
|
7
|
-
id: "color-picker.label",
|
|
8
|
-
defaultMessage: "Color"
|
|
9
|
-
},
|
|
10
|
-
hexLabel: {
|
|
11
|
-
id: "color-picker.hex_label",
|
|
12
|
-
defaultMessage: "Hex"
|
|
13
|
-
},
|
|
14
|
-
pickColor: {
|
|
15
|
-
id: "color-picker.pick_color",
|
|
16
|
-
defaultMessage: "Pick a color"
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
messages
|
|
22
|
-
};
|