react-headless-color-picker 1.0.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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.d.mts +163 -0
- package/dist/index.d.ts +163 -0
- package/dist/index.js +671 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +600 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
// src/hooks/useColorManipulation.ts
|
|
2
|
+
import { useState, useEffect, useCallback, useRef as useRef2 } from "react";
|
|
3
|
+
|
|
4
|
+
// src/utils/round.ts
|
|
5
|
+
var round = (number, digits = 0, base = Math.pow(10, digits)) => {
|
|
6
|
+
return Math.round(base * number) / base;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// src/utils/convert.ts
|
|
10
|
+
var angleUnits = {
|
|
11
|
+
grad: 360 / 400,
|
|
12
|
+
turn: 360,
|
|
13
|
+
rad: 360 / (Math.PI * 2)
|
|
14
|
+
};
|
|
15
|
+
var hexToHsva = (hex) => rgbaToHsva(hexToRgba(hex));
|
|
16
|
+
var hexToRgba = (hex) => {
|
|
17
|
+
if (hex[0] === "#") hex = hex.substring(1);
|
|
18
|
+
if (hex.length < 6) {
|
|
19
|
+
return {
|
|
20
|
+
r: parseInt(hex[0] + hex[0], 16),
|
|
21
|
+
g: parseInt(hex[1] + hex[1], 16),
|
|
22
|
+
b: parseInt(hex[2] + hex[2], 16),
|
|
23
|
+
a: hex.length === 4 ? round(parseInt(hex[3] + hex[3], 16) / 255, 2) : 1
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
r: parseInt(hex.substring(0, 2), 16),
|
|
28
|
+
g: parseInt(hex.substring(2, 4), 16),
|
|
29
|
+
b: parseInt(hex.substring(4, 6), 16),
|
|
30
|
+
a: hex.length === 8 ? round(parseInt(hex.substring(6, 8), 16) / 255, 2) : 1
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
var parseHue = (value, unit = "deg") => {
|
|
34
|
+
return Number(value) * (angleUnits[unit] || 1);
|
|
35
|
+
};
|
|
36
|
+
var hslaStringToHsva = (hslString) => {
|
|
37
|
+
const matcher2 = /hsla?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i;
|
|
38
|
+
const match = matcher2.exec(hslString);
|
|
39
|
+
if (!match) return { h: 0, s: 0, v: 0, a: 1 };
|
|
40
|
+
return hslaToHsva({
|
|
41
|
+
h: parseHue(match[1], match[2]),
|
|
42
|
+
s: Number(match[3]),
|
|
43
|
+
l: Number(match[4]),
|
|
44
|
+
a: match[5] === void 0 ? 1 : Number(match[5]) / (match[6] ? 100 : 1)
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
var hslStringToHsva = hslaStringToHsva;
|
|
48
|
+
var hslaToHsva = ({ h, s, l, a }) => {
|
|
49
|
+
s *= (l < 50 ? l : 100 - l) / 100;
|
|
50
|
+
return {
|
|
51
|
+
h,
|
|
52
|
+
s: s > 0 ? 2 * s / (l + s) * 100 : 0,
|
|
53
|
+
v: l + s,
|
|
54
|
+
a
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
var hsvaToHex = (hsva) => rgbaToHex(hsvaToRgba(hsva));
|
|
58
|
+
var hsvaToHsla = ({ h, s, v, a }) => {
|
|
59
|
+
const hh = (200 - s) * v / 100;
|
|
60
|
+
return {
|
|
61
|
+
h: round(h),
|
|
62
|
+
s: round(hh > 0 && hh < 200 ? s * v / 100 / (hh <= 100 ? hh : 200 - hh) * 100 : 0),
|
|
63
|
+
l: round(hh / 2),
|
|
64
|
+
a: round(a, 2)
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
var hsvaToHslString = (hsva) => {
|
|
68
|
+
const { h, s, l } = hsvaToHsla(hsva);
|
|
69
|
+
return `hsl(${h}, ${s}%, ${l}%)`;
|
|
70
|
+
};
|
|
71
|
+
var hsvaToHsvString = (hsva) => {
|
|
72
|
+
const { h, s, v } = roundHsva(hsva);
|
|
73
|
+
return `hsv(${h}, ${s}%, ${v}%)`;
|
|
74
|
+
};
|
|
75
|
+
var hsvaToHsvaString = (hsva) => {
|
|
76
|
+
const { h, s, v, a } = roundHsva(hsva);
|
|
77
|
+
return `hsva(${h}, ${s}%, ${v}%, ${a})`;
|
|
78
|
+
};
|
|
79
|
+
var hsvaToHslaString = (hsva) => {
|
|
80
|
+
const { h, s, l, a } = hsvaToHsla(hsva);
|
|
81
|
+
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
|
|
82
|
+
};
|
|
83
|
+
var hsvaToRgba = ({ h, s, v, a }) => {
|
|
84
|
+
h = h / 360 * 6;
|
|
85
|
+
s = s / 100;
|
|
86
|
+
v = v / 100;
|
|
87
|
+
const hh = Math.floor(h), b = v * (1 - s), c = v * (1 - (h - hh) * s), d = v * (1 - (1 - h + hh) * s), module = hh % 6;
|
|
88
|
+
return {
|
|
89
|
+
r: round([v, c, b, b, d, v][module] * 255),
|
|
90
|
+
g: round([d, v, v, c, b, b][module] * 255),
|
|
91
|
+
b: round([b, b, d, v, v, c][module] * 255),
|
|
92
|
+
a: round(a, 2)
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
var hsvaToRgbString = (hsva) => {
|
|
96
|
+
const { r, g, b } = hsvaToRgba(hsva);
|
|
97
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
98
|
+
};
|
|
99
|
+
var hsvaToRgbaString = (hsva) => {
|
|
100
|
+
const { r, g, b, a } = hsvaToRgba(hsva);
|
|
101
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
102
|
+
};
|
|
103
|
+
var hsvaStringToHsva = (hsvString) => {
|
|
104
|
+
const matcher2 = /hsva?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i;
|
|
105
|
+
const match = matcher2.exec(hsvString);
|
|
106
|
+
if (!match) return { h: 0, s: 0, v: 0, a: 1 };
|
|
107
|
+
return roundHsva({
|
|
108
|
+
h: parseHue(match[1], match[2]),
|
|
109
|
+
s: Number(match[3]),
|
|
110
|
+
v: Number(match[4]),
|
|
111
|
+
a: match[5] === void 0 ? 1 : Number(match[5]) / (match[6] ? 100 : 1)
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
var hsvStringToHsva = hsvaStringToHsva;
|
|
115
|
+
var rgbaStringToHsva = (rgbaString) => {
|
|
116
|
+
const matcher2 = /rgba?\(?\s*(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i;
|
|
117
|
+
const match = matcher2.exec(rgbaString);
|
|
118
|
+
if (!match) return { h: 0, s: 0, v: 0, a: 1 };
|
|
119
|
+
return rgbaToHsva({
|
|
120
|
+
r: Number(match[1]) / (match[2] ? 100 / 255 : 1),
|
|
121
|
+
g: Number(match[3]) / (match[4] ? 100 / 255 : 1),
|
|
122
|
+
b: Number(match[5]) / (match[6] ? 100 / 255 : 1),
|
|
123
|
+
a: match[7] === void 0 ? 1 : Number(match[7]) / (match[8] ? 100 : 1)
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
var rgbStringToHsva = rgbaStringToHsva;
|
|
127
|
+
var format = (number) => {
|
|
128
|
+
const hex = number.toString(16);
|
|
129
|
+
return hex.length < 2 ? "0" + hex : hex;
|
|
130
|
+
};
|
|
131
|
+
var rgbaToHex = ({ r, g, b, a }) => {
|
|
132
|
+
const alphaHex = a < 1 ? format(round(a * 255)) : "";
|
|
133
|
+
return "#" + format(r) + format(g) + format(b) + alphaHex;
|
|
134
|
+
};
|
|
135
|
+
var rgbaToHsva = ({ r, g, b, a }) => {
|
|
136
|
+
const max = Math.max(r, g, b);
|
|
137
|
+
const delta = max - Math.min(r, g, b);
|
|
138
|
+
const hh = delta ? max === r ? (g - b) / delta : max === g ? 2 + (b - r) / delta : 4 + (r - g) / delta : 0;
|
|
139
|
+
return {
|
|
140
|
+
h: round(60 * (hh < 0 ? hh + 6 : hh)),
|
|
141
|
+
s: round(max ? delta / max * 100 : 0),
|
|
142
|
+
v: round(max / 255 * 100),
|
|
143
|
+
a
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
var roundHsva = (hsva) => ({
|
|
147
|
+
h: round(hsva.h),
|
|
148
|
+
s: round(hsva.s),
|
|
149
|
+
v: round(hsva.v),
|
|
150
|
+
a: round(hsva.a, 2)
|
|
151
|
+
});
|
|
152
|
+
var rgbaToRgb = ({ r, g, b }) => ({ r, g, b });
|
|
153
|
+
var hslaToHsl = ({ h, s, l }) => ({ h, s, l });
|
|
154
|
+
var hsvaToHsv = (hsva) => {
|
|
155
|
+
const { h, s, v } = roundHsva(hsva);
|
|
156
|
+
return { h, s, v };
|
|
157
|
+
};
|
|
158
|
+
var hsvaToHueHsl = (h) => {
|
|
159
|
+
return `hsl(${Math.round(h)}, 100%, 50%)`;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// src/utils/compare.ts
|
|
163
|
+
var equalColorObjects = (first, second) => {
|
|
164
|
+
if (first === second) return true;
|
|
165
|
+
for (const prop in first) {
|
|
166
|
+
if (first[prop] !== second[prop])
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
};
|
|
171
|
+
var equalColorString = (first, second) => {
|
|
172
|
+
return first.replace(/\s/g, "") === second.replace(/\s/g, "");
|
|
173
|
+
};
|
|
174
|
+
var equalHex = (first, second) => {
|
|
175
|
+
if (first.toLowerCase() === second.toLowerCase()) return true;
|
|
176
|
+
return equalColorObjects(hexToRgba(first), hexToRgba(second));
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/hooks/useEventCallback.ts
|
|
180
|
+
import { useRef } from "react";
|
|
181
|
+
function useEventCallback(handler) {
|
|
182
|
+
const callbackRef = useRef(handler);
|
|
183
|
+
const fn = useRef((value) => {
|
|
184
|
+
callbackRef.current && callbackRef.current(value);
|
|
185
|
+
});
|
|
186
|
+
callbackRef.current = handler;
|
|
187
|
+
return fn.current;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/hooks/useColorManipulation.ts
|
|
191
|
+
function useColorManipulation(colorModel, color, onChange) {
|
|
192
|
+
const onChangeCallback = useEventCallback(onChange);
|
|
193
|
+
const [hsva, updateHsva] = useState(() => colorModel.toHsva(color));
|
|
194
|
+
const cache = useRef2({ color, hsva });
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
if (!colorModel.equal(color, cache.current.color)) {
|
|
197
|
+
const newHsva = colorModel.toHsva(color);
|
|
198
|
+
cache.current = { hsva: newHsva, color };
|
|
199
|
+
updateHsva(newHsva);
|
|
200
|
+
}
|
|
201
|
+
}, [color, colorModel]);
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
let newColor;
|
|
204
|
+
if (!equalColorObjects(hsva, cache.current.hsva) && !colorModel.equal(newColor = colorModel.fromHsva(hsva), cache.current.color)) {
|
|
205
|
+
cache.current = { hsva, color: newColor };
|
|
206
|
+
onChangeCallback(newColor);
|
|
207
|
+
}
|
|
208
|
+
}, [hsva, colorModel, onChangeCallback]);
|
|
209
|
+
const handleChange = useCallback((params) => {
|
|
210
|
+
updateHsva((current) => Object.assign({}, current, params));
|
|
211
|
+
}, []);
|
|
212
|
+
return [hsva, handleChange];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/components/Hue.tsx
|
|
216
|
+
import { memo as memo2 } from "react";
|
|
217
|
+
|
|
218
|
+
// src/utils/clamp.ts
|
|
219
|
+
var clamp = (number, min = 0, max = 1) => {
|
|
220
|
+
return number > max ? max : number < min ? min : number;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// src/components/Interactive.tsx
|
|
224
|
+
import { memo, useEffect as useEffect2, useMemo, useRef as useRef3 } from "react";
|
|
225
|
+
import { jsx } from "react/jsx-runtime";
|
|
226
|
+
var isTouch = (e) => "touches" in e;
|
|
227
|
+
var getParentWindow = (node) => node?.ownerDocument?.defaultView ?? window;
|
|
228
|
+
var getRelativePosition = (node, event, touchId) => {
|
|
229
|
+
const rect = node.getBoundingClientRect();
|
|
230
|
+
const pointer = isTouch(event) ? Array.from(event.touches).find((t) => t.identifier === touchId) ?? event.touches[0] : event;
|
|
231
|
+
return {
|
|
232
|
+
left: clamp(
|
|
233
|
+
(pointer.pageX - (rect.left + getParentWindow(node).pageXOffset)) / rect.width
|
|
234
|
+
),
|
|
235
|
+
top: clamp(
|
|
236
|
+
(pointer.pageY - (rect.top + getParentWindow(node).pageYOffset)) / rect.height
|
|
237
|
+
)
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
var Interactive = memo(function Interactive2({
|
|
241
|
+
onMove,
|
|
242
|
+
onKey,
|
|
243
|
+
children,
|
|
244
|
+
style,
|
|
245
|
+
...rest
|
|
246
|
+
}) {
|
|
247
|
+
const container = useRef3(null);
|
|
248
|
+
const onMoveCallback = useEventCallback(onMove);
|
|
249
|
+
const onKeyCallback = useEventCallback(onKey);
|
|
250
|
+
const touchId = useRef3(null);
|
|
251
|
+
const hasTouch = useRef3(false);
|
|
252
|
+
const [handleMoveStart, handleKeyDown, toggleDocumentEvents] = useMemo(() => {
|
|
253
|
+
const handleMoveStart2 = ({
|
|
254
|
+
nativeEvent
|
|
255
|
+
}) => {
|
|
256
|
+
const el = container.current;
|
|
257
|
+
if (!el) return;
|
|
258
|
+
if (!isTouch(nativeEvent)) nativeEvent.preventDefault();
|
|
259
|
+
if (hasTouch.current && !isTouch(nativeEvent)) return;
|
|
260
|
+
if (isTouch(nativeEvent)) {
|
|
261
|
+
hasTouch.current = true;
|
|
262
|
+
touchId.current = nativeEvent.changedTouches?.[0]?.identifier ?? null;
|
|
263
|
+
}
|
|
264
|
+
el.focus();
|
|
265
|
+
onMoveCallback(
|
|
266
|
+
getRelativePosition(el, nativeEvent, touchId.current)
|
|
267
|
+
);
|
|
268
|
+
toggleDocumentEvents2(true);
|
|
269
|
+
};
|
|
270
|
+
const handleMove = (event) => {
|
|
271
|
+
if (!isTouch(event)) event.preventDefault();
|
|
272
|
+
const isDown = isTouch(event) ? event.touches.length > 0 : event.buttons > 0;
|
|
273
|
+
if (isDown && container.current) {
|
|
274
|
+
onMoveCallback(
|
|
275
|
+
getRelativePosition(
|
|
276
|
+
container.current,
|
|
277
|
+
event,
|
|
278
|
+
touchId.current
|
|
279
|
+
)
|
|
280
|
+
);
|
|
281
|
+
} else {
|
|
282
|
+
toggleDocumentEvents2(false);
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const handleMoveEnd = () => {
|
|
286
|
+
hasTouch.current = false;
|
|
287
|
+
touchId.current = null;
|
|
288
|
+
toggleDocumentEvents2(false);
|
|
289
|
+
};
|
|
290
|
+
const handleKeyDown2 = (event) => {
|
|
291
|
+
const k = event.key;
|
|
292
|
+
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(k)) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
event.preventDefault();
|
|
296
|
+
onKeyCallback({
|
|
297
|
+
left: k === "ArrowRight" ? 0.05 : k === "ArrowLeft" ? -0.05 : 0,
|
|
298
|
+
top: k === "ArrowDown" ? 0.05 : k === "ArrowUp" ? -0.05 : 0
|
|
299
|
+
});
|
|
300
|
+
};
|
|
301
|
+
function toggleDocumentEvents2(state) {
|
|
302
|
+
const el = container.current;
|
|
303
|
+
const win = getParentWindow(el);
|
|
304
|
+
const method = state ? win.addEventListener.bind(win) : win.removeEventListener.bind(win);
|
|
305
|
+
if (hasTouch.current) {
|
|
306
|
+
method("touchmove", handleMove);
|
|
307
|
+
method("touchend", handleMoveEnd);
|
|
308
|
+
} else {
|
|
309
|
+
method("mousemove", handleMove);
|
|
310
|
+
method("mouseup", handleMoveEnd);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return [handleMoveStart2, handleKeyDown2, toggleDocumentEvents2];
|
|
314
|
+
}, [onKeyCallback, onMoveCallback]);
|
|
315
|
+
useEffect2(() => {
|
|
316
|
+
return () => toggleDocumentEvents(false);
|
|
317
|
+
}, [toggleDocumentEvents]);
|
|
318
|
+
return /* @__PURE__ */ jsx(
|
|
319
|
+
"div",
|
|
320
|
+
{
|
|
321
|
+
...rest,
|
|
322
|
+
ref: container,
|
|
323
|
+
onMouseDown: handleMoveStart,
|
|
324
|
+
onTouchStart: handleMoveStart,
|
|
325
|
+
onKeyDown: handleKeyDown,
|
|
326
|
+
tabIndex: 0,
|
|
327
|
+
role: "slider",
|
|
328
|
+
style: {
|
|
329
|
+
position: "relative",
|
|
330
|
+
cursor: "crosshair",
|
|
331
|
+
outline: "none",
|
|
332
|
+
...style
|
|
333
|
+
},
|
|
334
|
+
children
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// src/components/Pointer.tsx
|
|
340
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
341
|
+
var Pointer = function Pointer2({
|
|
342
|
+
left,
|
|
343
|
+
top = 0.5,
|
|
344
|
+
children,
|
|
345
|
+
style,
|
|
346
|
+
...rest
|
|
347
|
+
}) {
|
|
348
|
+
return /* @__PURE__ */ jsx2(
|
|
349
|
+
"div",
|
|
350
|
+
{
|
|
351
|
+
...rest,
|
|
352
|
+
style: {
|
|
353
|
+
position: "absolute",
|
|
354
|
+
left: `${left * 100}%`,
|
|
355
|
+
top: `${top * 100}%`,
|
|
356
|
+
transform: "translate(-50%, -50%)",
|
|
357
|
+
...style
|
|
358
|
+
},
|
|
359
|
+
children
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
// src/components/Hue.tsx
|
|
365
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
366
|
+
var Hue = memo2(function Hue2({
|
|
367
|
+
hue,
|
|
368
|
+
onChange,
|
|
369
|
+
renderPointer,
|
|
370
|
+
style,
|
|
371
|
+
...rest
|
|
372
|
+
}) {
|
|
373
|
+
const handleMove = ({ left }) => onChange({ h: 360 * left });
|
|
374
|
+
const handleKey = ({ left }) => onChange({ h: clamp(hue + left * 360, 0, 360) });
|
|
375
|
+
return /* @__PURE__ */ jsx3(
|
|
376
|
+
Interactive,
|
|
377
|
+
{
|
|
378
|
+
onMove: handleMove,
|
|
379
|
+
onKey: handleKey,
|
|
380
|
+
"aria-label": "Hue",
|
|
381
|
+
"aria-valuenow": round(hue),
|
|
382
|
+
"aria-valuemax": 360,
|
|
383
|
+
"aria-valuemin": 0,
|
|
384
|
+
style: {
|
|
385
|
+
background: "linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)",
|
|
386
|
+
...style
|
|
387
|
+
},
|
|
388
|
+
...rest,
|
|
389
|
+
children: renderPointer ? renderPointer({ left: hue / 360, top: 0.5, hue }) : /* @__PURE__ */ jsx3(Pointer, { left: hue / 360 })
|
|
390
|
+
}
|
|
391
|
+
);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// src/components/Saturation.tsx
|
|
395
|
+
import { memo as memo3 } from "react";
|
|
396
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
397
|
+
var Saturation = memo3(function Saturation2({
|
|
398
|
+
hsva,
|
|
399
|
+
onChange,
|
|
400
|
+
style,
|
|
401
|
+
renderPointer,
|
|
402
|
+
...rest
|
|
403
|
+
}) {
|
|
404
|
+
const handleMove = ({ left, top }) => onChange({ s: left * 100, v: 100 - top * 100 });
|
|
405
|
+
const handleKey = ({ left, top }) => onChange({
|
|
406
|
+
s: clamp(hsva.s + left * 100, 0, 100),
|
|
407
|
+
v: clamp(hsva.v - top * 100, 0, 100)
|
|
408
|
+
});
|
|
409
|
+
return /* @__PURE__ */ jsx4(
|
|
410
|
+
Interactive,
|
|
411
|
+
{
|
|
412
|
+
onMove: handleMove,
|
|
413
|
+
onKey: handleKey,
|
|
414
|
+
"aria-label": "Color",
|
|
415
|
+
"aria-valuetext": `Saturation ${round(hsva.s)}%, Brightness ${round(hsva.v)}%`,
|
|
416
|
+
style: {
|
|
417
|
+
width: "100%",
|
|
418
|
+
height: "100%",
|
|
419
|
+
background: `
|
|
420
|
+
linear-gradient(to top, #000, transparent),
|
|
421
|
+
linear-gradient(to right, #fff, transparent),
|
|
422
|
+
${hsvaToHueHsl(hsva.h)}
|
|
423
|
+
`,
|
|
424
|
+
...style
|
|
425
|
+
},
|
|
426
|
+
...rest,
|
|
427
|
+
children: renderPointer ? renderPointer({ left: hsva.s / 100, top: 1 - hsva.v / 100, hsva }) : /* @__PURE__ */ jsx4(Pointer, { left: hsva.s / 100, top: 1 - hsva.v / 100 })
|
|
428
|
+
}
|
|
429
|
+
);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// src/components/Alpha.tsx
|
|
433
|
+
import { memo as memo4 } from "react";
|
|
434
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
435
|
+
var Alpha = memo4(function Alpha2({
|
|
436
|
+
hsva,
|
|
437
|
+
onChange,
|
|
438
|
+
renderPointer,
|
|
439
|
+
style,
|
|
440
|
+
...rest
|
|
441
|
+
}) {
|
|
442
|
+
const handleMove = ({ left }) => onChange({ a: left });
|
|
443
|
+
const handleKey = ({ left }) => onChange({ a: clamp(hsva.a + left) });
|
|
444
|
+
const colorFrom = `hsla(${Math.round(hsva.h)}, 100%, 50%, 0)`;
|
|
445
|
+
const colorTo = `hsla(${Math.round(hsva.h)}, 100%, 50%, 1)`;
|
|
446
|
+
return /* @__PURE__ */ jsx5(
|
|
447
|
+
"div",
|
|
448
|
+
{
|
|
449
|
+
style: {
|
|
450
|
+
position: "relative",
|
|
451
|
+
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Crect width='4' height='4' fill='%23ccc'/%3E%3Crect x='4' y='4' width='4' height='4' fill='%23ccc'/%3E%3C/svg%3E")`,
|
|
452
|
+
...style
|
|
453
|
+
},
|
|
454
|
+
children: /* @__PURE__ */ jsx5(
|
|
455
|
+
Interactive,
|
|
456
|
+
{
|
|
457
|
+
onMove: handleMove,
|
|
458
|
+
onKey: handleKey,
|
|
459
|
+
"aria-label": "Alpha",
|
|
460
|
+
"aria-valuenow": round(hsva.a * 100),
|
|
461
|
+
"aria-valuemin": 0,
|
|
462
|
+
"aria-valuemax": 100,
|
|
463
|
+
"aria-valuetext": `${round(hsva.a * 100)}%`,
|
|
464
|
+
style: {
|
|
465
|
+
width: "100%",
|
|
466
|
+
height: "100%",
|
|
467
|
+
background: `linear-gradient(90deg, ${colorFrom}, ${colorTo})`
|
|
468
|
+
},
|
|
469
|
+
...rest,
|
|
470
|
+
children: renderPointer ? renderPointer({ left: hsva.a, top: 0.5, hsva }) : /* @__PURE__ */ jsx5(Pointer, { left: hsva.a })
|
|
471
|
+
}
|
|
472
|
+
)
|
|
473
|
+
}
|
|
474
|
+
);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// src/components/ColorPicker.tsx
|
|
478
|
+
import { Fragment, jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
479
|
+
function ColorPicker({
|
|
480
|
+
colorModel,
|
|
481
|
+
color,
|
|
482
|
+
onChange,
|
|
483
|
+
children,
|
|
484
|
+
renderSaturationPointer,
|
|
485
|
+
renderHuePointer,
|
|
486
|
+
...rest
|
|
487
|
+
}) {
|
|
488
|
+
const [hsva, updateHsva] = useColorManipulation(colorModel, color, onChange);
|
|
489
|
+
if (children) {
|
|
490
|
+
return /* @__PURE__ */ jsx6(Fragment, { children: children({ hsva, updateHsva, Saturation, Hue, Alpha, Pointer }) });
|
|
491
|
+
}
|
|
492
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, children: [
|
|
493
|
+
/* @__PURE__ */ jsx6(
|
|
494
|
+
Saturation,
|
|
495
|
+
{
|
|
496
|
+
hsva,
|
|
497
|
+
onChange: updateHsva,
|
|
498
|
+
renderPointer: renderSaturationPointer,
|
|
499
|
+
style: { width: "100%", aspectRatio: "1", borderRadius: "4px 4px 0 0" }
|
|
500
|
+
}
|
|
501
|
+
),
|
|
502
|
+
/* @__PURE__ */ jsx6(
|
|
503
|
+
Hue,
|
|
504
|
+
{
|
|
505
|
+
hue: hsva.h,
|
|
506
|
+
onChange: updateHsva,
|
|
507
|
+
renderPointer: renderHuePointer,
|
|
508
|
+
style: { width: "100%", height: 24, borderRadius: "0 0 4px 4px", marginTop: 4 }
|
|
509
|
+
}
|
|
510
|
+
)
|
|
511
|
+
] });
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// src/components/HexColorPicker.tsx
|
|
515
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
516
|
+
var hexColorModel = {
|
|
517
|
+
defaultColor: "#ff0000",
|
|
518
|
+
toHsva: hexToHsva,
|
|
519
|
+
fromHsva: (hsva) => hsvaToHex(hsva),
|
|
520
|
+
equal: equalHex
|
|
521
|
+
};
|
|
522
|
+
function HexColorPicker({
|
|
523
|
+
color = "#ff0000",
|
|
524
|
+
...rest
|
|
525
|
+
}) {
|
|
526
|
+
return /* @__PURE__ */ jsx7(ColorPicker, { colorModel: hexColorModel, color, ...rest });
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// src/utils/validate.ts
|
|
530
|
+
var matcher = /^#?([0-9A-F]{3,8})$/i;
|
|
531
|
+
var validHex = (value, alpha) => {
|
|
532
|
+
const match = matcher.exec(value);
|
|
533
|
+
const length = match ? match[1].length : 0;
|
|
534
|
+
return length === 3 || // '#rgb' format
|
|
535
|
+
length === 6 || // '#rrggbb' format
|
|
536
|
+
!!alpha && length === 4 || // '#rgba' format
|
|
537
|
+
!!alpha && length === 8;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// src/utils/nonce.ts
|
|
541
|
+
var nonce;
|
|
542
|
+
var getNonce = () => {
|
|
543
|
+
if (nonce) return nonce;
|
|
544
|
+
if (typeof __webpack_nonce__ !== "undefined") return __webpack_nonce__;
|
|
545
|
+
return void 0;
|
|
546
|
+
};
|
|
547
|
+
var setNonce = (hash) => {
|
|
548
|
+
nonce = hash;
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
// src/utils/format.ts
|
|
552
|
+
var formatClassName = (names) => names.filter(Boolean).join(" ");
|
|
553
|
+
export {
|
|
554
|
+
Alpha,
|
|
555
|
+
ColorPicker,
|
|
556
|
+
HexColorPicker,
|
|
557
|
+
Hue,
|
|
558
|
+
Interactive,
|
|
559
|
+
Pointer,
|
|
560
|
+
Saturation,
|
|
561
|
+
clamp,
|
|
562
|
+
equalColorObjects,
|
|
563
|
+
equalColorString,
|
|
564
|
+
equalHex,
|
|
565
|
+
formatClassName,
|
|
566
|
+
getNonce,
|
|
567
|
+
hexColorModel,
|
|
568
|
+
hexToHsva,
|
|
569
|
+
hexToRgba,
|
|
570
|
+
hslStringToHsva,
|
|
571
|
+
hslaStringToHsva,
|
|
572
|
+
hslaToHsl,
|
|
573
|
+
hslaToHsva,
|
|
574
|
+
hsvStringToHsva,
|
|
575
|
+
hsvaStringToHsva,
|
|
576
|
+
hsvaToHex,
|
|
577
|
+
hsvaToHslString,
|
|
578
|
+
hsvaToHsla,
|
|
579
|
+
hsvaToHslaString,
|
|
580
|
+
hsvaToHsv,
|
|
581
|
+
hsvaToHsvString,
|
|
582
|
+
hsvaToHsvaString,
|
|
583
|
+
hsvaToHueHsl,
|
|
584
|
+
hsvaToRgbString,
|
|
585
|
+
hsvaToRgba,
|
|
586
|
+
hsvaToRgbaString,
|
|
587
|
+
parseHue,
|
|
588
|
+
rgbStringToHsva,
|
|
589
|
+
rgbaStringToHsva,
|
|
590
|
+
rgbaToHex,
|
|
591
|
+
rgbaToHsva,
|
|
592
|
+
rgbaToRgb,
|
|
593
|
+
round,
|
|
594
|
+
roundHsva,
|
|
595
|
+
setNonce,
|
|
596
|
+
useColorManipulation,
|
|
597
|
+
useEventCallback,
|
|
598
|
+
validHex
|
|
599
|
+
};
|
|
600
|
+
//# sourceMappingURL=index.mjs.map
|