@fab1o978/react-ui 0.1.5 → 0.1.8
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/components/ColorPicker/index.cjs +207 -63
- package/dist/components/ColorPicker/index.cjs.map +1 -1
- package/dist/components/ColorPicker/index.css +200 -42
- package/dist/components/ColorPicker/index.css.map +1 -1
- package/dist/components/ColorPicker/index.js +207 -63
- package/dist/components/ColorPicker/index.js.map +1 -1
- package/dist/components/SliderControl/index.cjs +270 -0
- package/dist/components/SliderControl/index.cjs.map +1 -0
- package/dist/components/SliderControl/index.css +202 -0
- package/dist/components/SliderControl/index.css.map +1 -0
- package/dist/components/SliderControl/index.d.cts +22 -0
- package/dist/components/SliderControl/index.d.ts +22 -0
- package/dist/components/SliderControl/index.js +268 -0
- package/dist/components/SliderControl/index.js.map +1 -0
- package/dist/index.cjs +208 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +200 -42
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +208 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,10 +12,6 @@ var ColorPicker_module_default = {
|
|
|
12
12
|
discWrapper: "ColorPicker_module_discWrapper2",
|
|
13
13
|
disc: "ColorPicker_module_disc2",
|
|
14
14
|
dot: "ColorPicker_module_dot2",
|
|
15
|
-
lSlider: "ColorPicker_module_lSlider2",
|
|
16
|
-
lThumb: "ColorPicker_module_lThumb2",
|
|
17
|
-
alphaSlider: "ColorPicker_module_alphaSlider2",
|
|
18
|
-
alphaThumb: "ColorPicker_module_alphaThumb2",
|
|
19
15
|
previewSwatch: "ColorPicker_module_previewSwatch2",
|
|
20
16
|
eyedropperBtn: "ColorPicker_module_eyedropperBtn2",
|
|
21
17
|
inputSection: "ColorPicker_module_inputSection2",
|
|
@@ -32,6 +28,21 @@ var ColorPicker_module_default = {
|
|
|
32
28
|
recentSwatch: "ColorPicker_module_recentSwatch2"
|
|
33
29
|
};
|
|
34
30
|
|
|
31
|
+
// src/components/SliderControl/SliderControl.module.scss
|
|
32
|
+
var SliderControl_module_default = {
|
|
33
|
+
wrapper: "SliderControl_module_wrapper2",
|
|
34
|
+
disabled: "SliderControl_module_disabled2",
|
|
35
|
+
icon: "SliderControl_module_icon2",
|
|
36
|
+
trackArea: "SliderControl_module_trackArea2",
|
|
37
|
+
groove: "SliderControl_module_groove2",
|
|
38
|
+
rail: "SliderControl_module_rail2",
|
|
39
|
+
fill: "SliderControl_module_fill2",
|
|
40
|
+
thumb: "SliderControl_module_thumb2",
|
|
41
|
+
thumbDragging: "SliderControl_module_thumbDragging2",
|
|
42
|
+
tooltip: "SliderControl_module_tooltip2",
|
|
43
|
+
tooltipVisible: "SliderControl_module_tooltipVisible2"
|
|
44
|
+
};
|
|
45
|
+
|
|
35
46
|
// src/utils/color.ts
|
|
36
47
|
function hexToHsl(hex) {
|
|
37
48
|
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -147,6 +158,177 @@ function accentToCssVars(tokens, prefix) {
|
|
|
147
158
|
[`--${prefix}-accent-light`]: tokens.light
|
|
148
159
|
};
|
|
149
160
|
}
|
|
161
|
+
function clamp(v, min, max) {
|
|
162
|
+
return Math.min(Math.max(v, min), max);
|
|
163
|
+
}
|
|
164
|
+
function snapToStep(v, min, step) {
|
|
165
|
+
return Math.round((v - min) / step) * step + min;
|
|
166
|
+
}
|
|
167
|
+
var SliderControl = ({
|
|
168
|
+
value: controlledValue,
|
|
169
|
+
defaultValue = 50,
|
|
170
|
+
min = 0,
|
|
171
|
+
max = 100,
|
|
172
|
+
step = 1,
|
|
173
|
+
onChange,
|
|
174
|
+
showTooltip = "drag",
|
|
175
|
+
showPercentage = false,
|
|
176
|
+
leftIcon,
|
|
177
|
+
rightIcon,
|
|
178
|
+
railBackground,
|
|
179
|
+
accent,
|
|
180
|
+
className,
|
|
181
|
+
disabled = false
|
|
182
|
+
}) => {
|
|
183
|
+
const isControlled = controlledValue !== void 0;
|
|
184
|
+
const [internalValue, setInternalValue] = react.useState(defaultValue);
|
|
185
|
+
const [isDragging, setIsDragging] = react.useState(false);
|
|
186
|
+
const [isFocused, setIsFocused] = react.useState(false);
|
|
187
|
+
const trackRef = react.useRef(null);
|
|
188
|
+
const thumbRef = react.useRef(null);
|
|
189
|
+
const value = isControlled ? controlledValue : internalValue;
|
|
190
|
+
const pct = (clamp(value, min, max) - min) / (max - min);
|
|
191
|
+
const accentVars = accent ? accentToCssVars(deriveAccent(accent), "slider") : {};
|
|
192
|
+
const setValue = react.useCallback(
|
|
193
|
+
(next) => {
|
|
194
|
+
const snapped = clamp(snapToStep(next, min, step), min, max);
|
|
195
|
+
if (!isControlled) setInternalValue(snapped);
|
|
196
|
+
onChange?.(snapped);
|
|
197
|
+
},
|
|
198
|
+
[isControlled, min, max, step, onChange]
|
|
199
|
+
);
|
|
200
|
+
const valueFromPointer = react.useCallback(
|
|
201
|
+
(e) => {
|
|
202
|
+
const rect = trackRef.current.getBoundingClientRect();
|
|
203
|
+
const ratio = clamp((e.clientX - rect.left) / rect.width, 0, 1);
|
|
204
|
+
return min + ratio * (max - min);
|
|
205
|
+
},
|
|
206
|
+
[min, max]
|
|
207
|
+
);
|
|
208
|
+
const handlePointerDown = react.useCallback(
|
|
209
|
+
(e) => {
|
|
210
|
+
if (disabled) return;
|
|
211
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
212
|
+
setIsDragging(true);
|
|
213
|
+
thumbRef.current?.focus();
|
|
214
|
+
setValue(valueFromPointer(e.nativeEvent));
|
|
215
|
+
},
|
|
216
|
+
[disabled, setValue, valueFromPointer]
|
|
217
|
+
);
|
|
218
|
+
const handlePointerMove = react.useCallback(
|
|
219
|
+
(e) => {
|
|
220
|
+
if (!isDragging || disabled) return;
|
|
221
|
+
setValue(valueFromPointer(e.nativeEvent));
|
|
222
|
+
},
|
|
223
|
+
[isDragging, disabled, setValue, valueFromPointer]
|
|
224
|
+
);
|
|
225
|
+
const handlePointerUp = react.useCallback(() => {
|
|
226
|
+
setIsDragging(false);
|
|
227
|
+
thumbRef.current?.blur();
|
|
228
|
+
}, []);
|
|
229
|
+
react.useEffect(() => {
|
|
230
|
+
const el = trackRef.current;
|
|
231
|
+
if (!el) return;
|
|
232
|
+
const onWheel = (e) => {
|
|
233
|
+
if (disabled) return;
|
|
234
|
+
e.preventDefault();
|
|
235
|
+
setValue(value + (e.deltaY < 0 ? step : -step));
|
|
236
|
+
};
|
|
237
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
238
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
239
|
+
}, [disabled, value, step, setValue]);
|
|
240
|
+
const handleKeyDown = react.useCallback(
|
|
241
|
+
(e) => {
|
|
242
|
+
if (disabled) return;
|
|
243
|
+
const map = {
|
|
244
|
+
ArrowRight: step,
|
|
245
|
+
ArrowUp: step,
|
|
246
|
+
ArrowLeft: -step,
|
|
247
|
+
ArrowDown: -step,
|
|
248
|
+
PageUp: step * 10,
|
|
249
|
+
PageDown: -step * 10
|
|
250
|
+
};
|
|
251
|
+
if (e.key === "Home") {
|
|
252
|
+
setValue(min);
|
|
253
|
+
e.preventDefault();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (e.key === "End") {
|
|
257
|
+
setValue(max);
|
|
258
|
+
e.preventDefault();
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (map[e.key] !== void 0) {
|
|
262
|
+
setValue(value + map[e.key]);
|
|
263
|
+
e.preventDefault();
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
[disabled, step, min, max, value, setValue]
|
|
267
|
+
);
|
|
268
|
+
const tooltipVisible = showTooltip === "always" || showTooltip === "drag" && (isDragging || isFocused);
|
|
269
|
+
const decimals = step < 1 ? Math.ceil(-Math.log10(step)) : 0;
|
|
270
|
+
const displayValue = showPercentage ? `${Math.round((value - min) / (max - min) * 100)}%` : value.toFixed(decimals);
|
|
271
|
+
const tooltipOffset = `calc(${pct * 100}% + ${(0.5 - pct) * 20}px)`;
|
|
272
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
273
|
+
"div",
|
|
274
|
+
{
|
|
275
|
+
className: [SliderControl_module_default.wrapper, disabled ? SliderControl_module_default.disabled : "", className ?? ""].filter(Boolean).join(" "),
|
|
276
|
+
style: accentVars,
|
|
277
|
+
children: [
|
|
278
|
+
leftIcon !== null && leftIcon !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: SliderControl_module_default.icon, children: leftIcon }),
|
|
279
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
280
|
+
"div",
|
|
281
|
+
{
|
|
282
|
+
ref: trackRef,
|
|
283
|
+
className: SliderControl_module_default.trackArea,
|
|
284
|
+
onPointerDown: handlePointerDown,
|
|
285
|
+
onPointerMove: handlePointerMove,
|
|
286
|
+
onPointerUp: handlePointerUp,
|
|
287
|
+
onPointerCancel: handlePointerUp,
|
|
288
|
+
children: [
|
|
289
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: SliderControl_module_default.groove, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
290
|
+
"div",
|
|
291
|
+
{
|
|
292
|
+
className: SliderControl_module_default.rail,
|
|
293
|
+
style: railBackground ? { background: railBackground } : void 0,
|
|
294
|
+
children: !railBackground && /* @__PURE__ */ jsxRuntime.jsx("div", { className: SliderControl_module_default.fill, style: { width: `${pct * 100}%` } })
|
|
295
|
+
}
|
|
296
|
+
) }),
|
|
297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
298
|
+
"div",
|
|
299
|
+
{
|
|
300
|
+
ref: thumbRef,
|
|
301
|
+
role: "slider",
|
|
302
|
+
tabIndex: disabled ? -1 : 0,
|
|
303
|
+
"aria-valuenow": Math.round(value),
|
|
304
|
+
"aria-valuemin": min,
|
|
305
|
+
"aria-valuemax": max,
|
|
306
|
+
"aria-disabled": disabled,
|
|
307
|
+
className: [SliderControl_module_default.thumb, isDragging ? SliderControl_module_default.thumbDragging : ""].filter(Boolean).join(" "),
|
|
308
|
+
style: { left: `calc(${pct * 100}% + ${(0.5 - pct) * 24}px)` },
|
|
309
|
+
onKeyDown: handleKeyDown,
|
|
310
|
+
onFocus: () => setIsFocused(true),
|
|
311
|
+
onBlur: () => setIsFocused(false)
|
|
312
|
+
}
|
|
313
|
+
),
|
|
314
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
315
|
+
"div",
|
|
316
|
+
{
|
|
317
|
+
className: [SliderControl_module_default.tooltip, tooltipVisible ? SliderControl_module_default.tooltipVisible : ""].filter(Boolean).join(" "),
|
|
318
|
+
style: { left: tooltipOffset },
|
|
319
|
+
"aria-hidden": "true",
|
|
320
|
+
children: displayValue
|
|
321
|
+
}
|
|
322
|
+
)
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
),
|
|
326
|
+
rightIcon !== null && rightIcon !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: SliderControl_module_default.icon, children: rightIcon })
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
};
|
|
331
|
+
SliderControl.displayName = "SliderControl";
|
|
150
332
|
var DISC = 200;
|
|
151
333
|
var CopyIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
|
|
152
334
|
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", y: "5", width: "7", height: "7", rx: "1.5", stroke: "currentColor", strokeWidth: "1.4" }),
|
|
@@ -316,50 +498,21 @@ var ColorPicker = ({
|
|
|
316
498
|
},
|
|
317
499
|
[updateDisc]
|
|
318
500
|
);
|
|
319
|
-
const
|
|
320
|
-
(
|
|
321
|
-
const nl = Math.max(0, Math.min(100, (clientX - rect.left) / rect.width * 100));
|
|
501
|
+
const handleLChange = react.useCallback(
|
|
502
|
+
(nl) => {
|
|
322
503
|
setL(nl);
|
|
323
504
|
notify(h, s, nl, a);
|
|
324
505
|
},
|
|
325
506
|
[h, s, a, notify]
|
|
326
507
|
);
|
|
327
|
-
const
|
|
328
|
-
(
|
|
329
|
-
|
|
330
|
-
updateL(e.clientX, e.currentTarget.getBoundingClientRect());
|
|
331
|
-
},
|
|
332
|
-
[updateL]
|
|
333
|
-
);
|
|
334
|
-
const handleLPointerMove = react.useCallback(
|
|
335
|
-
(e) => {
|
|
336
|
-
if (e.buttons === 0) return;
|
|
337
|
-
updateL(e.clientX, e.currentTarget.getBoundingClientRect());
|
|
338
|
-
},
|
|
339
|
-
[updateL]
|
|
340
|
-
);
|
|
341
|
-
const updateA = react.useCallback(
|
|
342
|
-
(clientX, rect) => {
|
|
343
|
-
const na = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
|
|
508
|
+
const handleAChange = react.useCallback(
|
|
509
|
+
(val) => {
|
|
510
|
+
const na = val / 100;
|
|
344
511
|
setA(na);
|
|
345
512
|
notify(h, s, l, na);
|
|
346
513
|
},
|
|
347
514
|
[h, s, l, notify]
|
|
348
515
|
);
|
|
349
|
-
const handleAPointerDown = react.useCallback(
|
|
350
|
-
(e) => {
|
|
351
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
352
|
-
updateA(e.clientX, e.currentTarget.getBoundingClientRect());
|
|
353
|
-
},
|
|
354
|
-
[updateA]
|
|
355
|
-
);
|
|
356
|
-
const handleAPointerMove = react.useCallback(
|
|
357
|
-
(e) => {
|
|
358
|
-
if (e.buttons === 0) return;
|
|
359
|
-
updateA(e.clientX, e.currentTarget.getBoundingClientRect());
|
|
360
|
-
},
|
|
361
|
-
[updateA]
|
|
362
|
-
);
|
|
363
516
|
const { r: rr, g: gg, b: bb } = hslToRgb(h, s, l);
|
|
364
517
|
const luminance = (0.299 * rr + 0.587 * gg + 0.114 * bb) / 255;
|
|
365
518
|
const swatchFg = luminance > 0.6 ? "rgba(0,0,0,0.5)" : "rgba(255,255,255,0.9)";
|
|
@@ -372,7 +525,6 @@ var ColorPicker = ({
|
|
|
372
525
|
hsl(${h}, ${s}%, 5%),
|
|
373
526
|
hsl(${h}, ${s}%, 50%),
|
|
374
527
|
hsl(${h}, ${s}%, 95%))`;
|
|
375
|
-
const alphaGradient = `linear-gradient(to right, transparent, ${rgbStr})`;
|
|
376
528
|
const handleEyeDropper = async () => {
|
|
377
529
|
if (!window.EyeDropper) return;
|
|
378
530
|
try {
|
|
@@ -433,35 +585,27 @@ var ColorPicker = ({
|
|
|
433
585
|
)
|
|
434
586
|
] }) }),
|
|
435
587
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
436
|
-
|
|
588
|
+
SliderControl,
|
|
437
589
|
{
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
className: ColorPicker_module_default.lThumb,
|
|
446
|
-
style: { left: `${l}%` }
|
|
447
|
-
}
|
|
448
|
-
)
|
|
590
|
+
value: l,
|
|
591
|
+
onChange: handleLChange,
|
|
592
|
+
min: 0,
|
|
593
|
+
max: 100,
|
|
594
|
+
step: 1,
|
|
595
|
+
showTooltip: "never",
|
|
596
|
+
railBackground: lGradient
|
|
449
597
|
}
|
|
450
598
|
),
|
|
451
599
|
showAlpha && /* @__PURE__ */ jsxRuntime.jsx(
|
|
452
|
-
|
|
600
|
+
SliderControl,
|
|
453
601
|
{
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
className: ColorPicker_module_default.alphaThumb,
|
|
462
|
-
style: { left: `${a * 100}%` }
|
|
463
|
-
}
|
|
464
|
-
)
|
|
602
|
+
value: Math.round(a * 100),
|
|
603
|
+
onChange: handleAChange,
|
|
604
|
+
min: 0,
|
|
605
|
+
max: 100,
|
|
606
|
+
step: 1,
|
|
607
|
+
showTooltip: "never",
|
|
608
|
+
railBackground: `linear-gradient(to right, transparent, ${rgbStr}), repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 0 / 10px 10px`
|
|
465
609
|
}
|
|
466
610
|
),
|
|
467
611
|
/* @__PURE__ */ jsxRuntime.jsx(
|