@fab1o978/react-ui 0.1.5 → 0.1.7
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 +205 -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 +205 -63
- package/dist/components/ColorPicker/index.js.map +1 -1
- package/dist/components/SliderControl/index.cjs +268 -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 +21 -0
- package/dist/components/SliderControl/index.d.ts +21 -0
- package/dist/components/SliderControl/index.js +266 -0
- package/dist/components/SliderControl/index.js.map +1 -0
- package/dist/index.cjs +206 -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 +206 -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,175 @@ 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
|
+
leftIcon,
|
|
176
|
+
rightIcon,
|
|
177
|
+
railBackground,
|
|
178
|
+
accent,
|
|
179
|
+
className,
|
|
180
|
+
disabled = false
|
|
181
|
+
}) => {
|
|
182
|
+
const isControlled = controlledValue !== void 0;
|
|
183
|
+
const [internalValue, setInternalValue] = react.useState(defaultValue);
|
|
184
|
+
const [isDragging, setIsDragging] = react.useState(false);
|
|
185
|
+
const [isFocused, setIsFocused] = react.useState(false);
|
|
186
|
+
const trackRef = react.useRef(null);
|
|
187
|
+
const thumbRef = react.useRef(null);
|
|
188
|
+
const value = isControlled ? controlledValue : internalValue;
|
|
189
|
+
const pct = (clamp(value, min, max) - min) / (max - min);
|
|
190
|
+
const accentVars = accent ? accentToCssVars(deriveAccent(accent), "slider") : {};
|
|
191
|
+
const setValue = react.useCallback(
|
|
192
|
+
(next) => {
|
|
193
|
+
const snapped = clamp(snapToStep(next, min, step), min, max);
|
|
194
|
+
if (!isControlled) setInternalValue(snapped);
|
|
195
|
+
onChange?.(snapped);
|
|
196
|
+
},
|
|
197
|
+
[isControlled, min, max, step, onChange]
|
|
198
|
+
);
|
|
199
|
+
const valueFromPointer = react.useCallback(
|
|
200
|
+
(e) => {
|
|
201
|
+
const rect = trackRef.current.getBoundingClientRect();
|
|
202
|
+
const ratio = clamp((e.clientX - rect.left) / rect.width, 0, 1);
|
|
203
|
+
return min + ratio * (max - min);
|
|
204
|
+
},
|
|
205
|
+
[min, max]
|
|
206
|
+
);
|
|
207
|
+
const handlePointerDown = react.useCallback(
|
|
208
|
+
(e) => {
|
|
209
|
+
if (disabled) return;
|
|
210
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
211
|
+
setIsDragging(true);
|
|
212
|
+
thumbRef.current?.focus();
|
|
213
|
+
setValue(valueFromPointer(e.nativeEvent));
|
|
214
|
+
},
|
|
215
|
+
[disabled, setValue, valueFromPointer]
|
|
216
|
+
);
|
|
217
|
+
const handlePointerMove = react.useCallback(
|
|
218
|
+
(e) => {
|
|
219
|
+
if (!isDragging || disabled) return;
|
|
220
|
+
setValue(valueFromPointer(e.nativeEvent));
|
|
221
|
+
},
|
|
222
|
+
[isDragging, disabled, setValue, valueFromPointer]
|
|
223
|
+
);
|
|
224
|
+
const handlePointerUp = react.useCallback(() => {
|
|
225
|
+
setIsDragging(false);
|
|
226
|
+
thumbRef.current?.blur();
|
|
227
|
+
}, []);
|
|
228
|
+
react.useEffect(() => {
|
|
229
|
+
const el = trackRef.current;
|
|
230
|
+
if (!el) return;
|
|
231
|
+
const onWheel = (e) => {
|
|
232
|
+
if (disabled) return;
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
setValue(value + (e.deltaY < 0 ? step : -step));
|
|
235
|
+
};
|
|
236
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
237
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
238
|
+
}, [disabled, value, step, setValue]);
|
|
239
|
+
const handleKeyDown = react.useCallback(
|
|
240
|
+
(e) => {
|
|
241
|
+
if (disabled) return;
|
|
242
|
+
const map = {
|
|
243
|
+
ArrowRight: step,
|
|
244
|
+
ArrowUp: step,
|
|
245
|
+
ArrowLeft: -step,
|
|
246
|
+
ArrowDown: -step,
|
|
247
|
+
PageUp: step * 10,
|
|
248
|
+
PageDown: -step * 10
|
|
249
|
+
};
|
|
250
|
+
if (e.key === "Home") {
|
|
251
|
+
setValue(min);
|
|
252
|
+
e.preventDefault();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (e.key === "End") {
|
|
256
|
+
setValue(max);
|
|
257
|
+
e.preventDefault();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (map[e.key] !== void 0) {
|
|
261
|
+
setValue(value + map[e.key]);
|
|
262
|
+
e.preventDefault();
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
[disabled, step, min, max, value, setValue]
|
|
266
|
+
);
|
|
267
|
+
const tooltipVisible = showTooltip === "always" || showTooltip === "drag" && (isDragging || isFocused);
|
|
268
|
+
const displayValue = `${Math.round(value)}%`;
|
|
269
|
+
const tooltipOffset = `calc(${pct * 100}% + ${(0.5 - pct) * 20}px)`;
|
|
270
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
271
|
+
"div",
|
|
272
|
+
{
|
|
273
|
+
className: [SliderControl_module_default.wrapper, disabled ? SliderControl_module_default.disabled : "", className ?? ""].filter(Boolean).join(" "),
|
|
274
|
+
style: accentVars,
|
|
275
|
+
children: [
|
|
276
|
+
leftIcon !== null && leftIcon !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: SliderControl_module_default.icon, children: leftIcon }),
|
|
277
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
278
|
+
"div",
|
|
279
|
+
{
|
|
280
|
+
ref: trackRef,
|
|
281
|
+
className: SliderControl_module_default.trackArea,
|
|
282
|
+
onPointerDown: handlePointerDown,
|
|
283
|
+
onPointerMove: handlePointerMove,
|
|
284
|
+
onPointerUp: handlePointerUp,
|
|
285
|
+
onPointerCancel: handlePointerUp,
|
|
286
|
+
children: [
|
|
287
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: SliderControl_module_default.groove, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
className: SliderControl_module_default.rail,
|
|
291
|
+
style: railBackground ? { background: railBackground } : void 0,
|
|
292
|
+
children: !railBackground && /* @__PURE__ */ jsxRuntime.jsx("div", { className: SliderControl_module_default.fill, style: { width: `${pct * 100}%` } })
|
|
293
|
+
}
|
|
294
|
+
) }),
|
|
295
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
296
|
+
"div",
|
|
297
|
+
{
|
|
298
|
+
ref: thumbRef,
|
|
299
|
+
role: "slider",
|
|
300
|
+
tabIndex: disabled ? -1 : 0,
|
|
301
|
+
"aria-valuenow": Math.round(value),
|
|
302
|
+
"aria-valuemin": min,
|
|
303
|
+
"aria-valuemax": max,
|
|
304
|
+
"aria-disabled": disabled,
|
|
305
|
+
className: [SliderControl_module_default.thumb, isDragging ? SliderControl_module_default.thumbDragging : ""].filter(Boolean).join(" "),
|
|
306
|
+
style: { left: `calc(${pct * 100}% + ${(0.5 - pct) * 24}px)` },
|
|
307
|
+
onKeyDown: handleKeyDown,
|
|
308
|
+
onFocus: () => setIsFocused(true),
|
|
309
|
+
onBlur: () => setIsFocused(false)
|
|
310
|
+
}
|
|
311
|
+
),
|
|
312
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
313
|
+
"div",
|
|
314
|
+
{
|
|
315
|
+
className: [SliderControl_module_default.tooltip, tooltipVisible ? SliderControl_module_default.tooltipVisible : ""].filter(Boolean).join(" "),
|
|
316
|
+
style: { left: tooltipOffset },
|
|
317
|
+
"aria-hidden": "true",
|
|
318
|
+
children: displayValue
|
|
319
|
+
}
|
|
320
|
+
)
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
),
|
|
324
|
+
rightIcon !== null && rightIcon !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: SliderControl_module_default.icon, children: rightIcon })
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
SliderControl.displayName = "SliderControl";
|
|
150
330
|
var DISC = 200;
|
|
151
331
|
var CopyIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
|
|
152
332
|
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", y: "5", width: "7", height: "7", rx: "1.5", stroke: "currentColor", strokeWidth: "1.4" }),
|
|
@@ -316,50 +496,21 @@ var ColorPicker = ({
|
|
|
316
496
|
},
|
|
317
497
|
[updateDisc]
|
|
318
498
|
);
|
|
319
|
-
const
|
|
320
|
-
(
|
|
321
|
-
const nl = Math.max(0, Math.min(100, (clientX - rect.left) / rect.width * 100));
|
|
499
|
+
const handleLChange = react.useCallback(
|
|
500
|
+
(nl) => {
|
|
322
501
|
setL(nl);
|
|
323
502
|
notify(h, s, nl, a);
|
|
324
503
|
},
|
|
325
504
|
[h, s, a, notify]
|
|
326
505
|
);
|
|
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));
|
|
506
|
+
const handleAChange = react.useCallback(
|
|
507
|
+
(val) => {
|
|
508
|
+
const na = val / 100;
|
|
344
509
|
setA(na);
|
|
345
510
|
notify(h, s, l, na);
|
|
346
511
|
},
|
|
347
512
|
[h, s, l, notify]
|
|
348
513
|
);
|
|
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
514
|
const { r: rr, g: gg, b: bb } = hslToRgb(h, s, l);
|
|
364
515
|
const luminance = (0.299 * rr + 0.587 * gg + 0.114 * bb) / 255;
|
|
365
516
|
const swatchFg = luminance > 0.6 ? "rgba(0,0,0,0.5)" : "rgba(255,255,255,0.9)";
|
|
@@ -372,7 +523,6 @@ var ColorPicker = ({
|
|
|
372
523
|
hsl(${h}, ${s}%, 5%),
|
|
373
524
|
hsl(${h}, ${s}%, 50%),
|
|
374
525
|
hsl(${h}, ${s}%, 95%))`;
|
|
375
|
-
const alphaGradient = `linear-gradient(to right, transparent, ${rgbStr})`;
|
|
376
526
|
const handleEyeDropper = async () => {
|
|
377
527
|
if (!window.EyeDropper) return;
|
|
378
528
|
try {
|
|
@@ -433,35 +583,27 @@ var ColorPicker = ({
|
|
|
433
583
|
)
|
|
434
584
|
] }) }),
|
|
435
585
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
436
|
-
|
|
586
|
+
SliderControl,
|
|
437
587
|
{
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
className: ColorPicker_module_default.lThumb,
|
|
446
|
-
style: { left: `${l}%` }
|
|
447
|
-
}
|
|
448
|
-
)
|
|
588
|
+
value: l,
|
|
589
|
+
onChange: handleLChange,
|
|
590
|
+
min: 0,
|
|
591
|
+
max: 100,
|
|
592
|
+
step: 1,
|
|
593
|
+
showTooltip: "never",
|
|
594
|
+
railBackground: lGradient
|
|
449
595
|
}
|
|
450
596
|
),
|
|
451
597
|
showAlpha && /* @__PURE__ */ jsxRuntime.jsx(
|
|
452
|
-
|
|
598
|
+
SliderControl,
|
|
453
599
|
{
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
className: ColorPicker_module_default.alphaThumb,
|
|
462
|
-
style: { left: `${a * 100}%` }
|
|
463
|
-
}
|
|
464
|
-
)
|
|
600
|
+
value: Math.round(a * 100),
|
|
601
|
+
onChange: handleAChange,
|
|
602
|
+
min: 0,
|
|
603
|
+
max: 100,
|
|
604
|
+
step: 1,
|
|
605
|
+
showTooltip: "never",
|
|
606
|
+
railBackground: `linear-gradient(to right, transparent, ${rgbStr}), repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 0 / 10px 10px`
|
|
465
607
|
}
|
|
466
608
|
),
|
|
467
609
|
/* @__PURE__ */ jsxRuntime.jsx(
|