@designbasekorea/ui 0.2.35 → 0.2.36
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/index.d.ts +6 -0
- package/dist/index.esm.js +141 -98
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +141 -98
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +141 -98
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1060,6 +1060,12 @@ interface ColorPickerProps {
|
|
|
1060
1060
|
showCopyButton?: boolean;
|
|
1061
1061
|
disabled?: boolean;
|
|
1062
1062
|
readonly?: boolean;
|
|
1063
|
+
/** 콜백 반환 포맷: 기본은 HEX, UI는 현재 선택 포맷 */
|
|
1064
|
+
onChangeFormat?: 'hex' | 'ui';
|
|
1065
|
+
/** 초기 마운트 시 onChange 발사 여부(기본 false) */
|
|
1066
|
+
fireOnInit?: boolean;
|
|
1067
|
+
/** 과발사 방지 디바운스(ms). 0은 비활성 */
|
|
1068
|
+
changeDebounceMs?: number;
|
|
1063
1069
|
onChange?: (color: string) => void;
|
|
1064
1070
|
onApply?: (color: string) => void;
|
|
1065
1071
|
onCancel?: () => void;
|
package/dist/index.esm.js
CHANGED
|
@@ -5321,17 +5321,19 @@ Chip.displayName = 'Chip';
|
|
|
5321
5321
|
|
|
5322
5322
|
/* ----------------------- 유틸 ----------------------- */
|
|
5323
5323
|
const clamp = (n, min, max) => Math.max(min, Math.min(max, n));
|
|
5324
|
+
const normalizeHex = (s) => (s || '').trim().toUpperCase();
|
|
5325
|
+
/** #RRGGBB → {r,g,b} */
|
|
5324
5326
|
const hexToRgb = (hex) => {
|
|
5325
5327
|
const m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim());
|
|
5326
5328
|
if (!m)
|
|
5327
5329
|
return null;
|
|
5328
5330
|
return { r: parseInt(m[1], 16), g: parseInt(m[2], 16), b: parseInt(m[3], 16) };
|
|
5329
5331
|
};
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5332
|
+
/** RGB → HEX */
|
|
5333
|
+
const toHex = (r, g, b) => {
|
|
5334
|
+
const h = (x) => clamp(Math.round(x), 0, 255).toString(16).padStart(2, '0');
|
|
5335
|
+
return `#${h(r)}${h(g)}${h(b)}`.toUpperCase();
|
|
5333
5336
|
};
|
|
5334
|
-
/** RGB ↔ HSV (HSV: h[0-360], s[0-100], v[0-100]) */
|
|
5335
5337
|
const rgbToHsv = (r, g, b) => {
|
|
5336
5338
|
r /= 255;
|
|
5337
5339
|
g /= 255;
|
|
@@ -5355,7 +5357,7 @@ const rgbToHsv = (r, g, b) => {
|
|
|
5355
5357
|
}
|
|
5356
5358
|
const s = max === 0 ? 0 : d / max;
|
|
5357
5359
|
const v = max;
|
|
5358
|
-
return { h
|
|
5360
|
+
return { h, s: s * 100, v: v * 100 };
|
|
5359
5361
|
};
|
|
5360
5362
|
const hsvToRgb = (h, s, v) => {
|
|
5361
5363
|
s /= 100;
|
|
@@ -5423,86 +5425,123 @@ const rgbToHsl = (r, g, b) => {
|
|
|
5423
5425
|
}
|
|
5424
5426
|
h *= 60;
|
|
5425
5427
|
}
|
|
5426
|
-
return {
|
|
5427
|
-
h: Math.round(h * 100) / 100,
|
|
5428
|
-
s: Math.round(s * 10000) / 100,
|
|
5429
|
-
l: Math.round(l * 10000) / 100,
|
|
5430
|
-
};
|
|
5428
|
+
return { h, s: s * 100, l: l * 100 };
|
|
5431
5429
|
};
|
|
5432
5430
|
/* ----------------------- 컴포넌트 ----------------------- */
|
|
5433
|
-
const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left', value, defaultValue = '#006FFF', showInput = true, showAlpha = true, showFormatSelector = true, showCopyButton = true, disabled = false, readonly = false, onChange, onApply, onCancel, className, }) => {
|
|
5434
|
-
/**
|
|
5435
|
-
const
|
|
5436
|
-
const
|
|
5437
|
-
const
|
|
5431
|
+
const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left', value, defaultValue = '#006FFF', showInput = true, showAlpha = true, showFormatSelector = true, showCopyButton = true, disabled = false, readonly = false, onChangeFormat = 'hex', fireOnInit = false, changeDebounceMs = 0, onChange, onApply, onCancel, className, }) => {
|
|
5432
|
+
/** 초기 HSV는 props에서 즉시 도출(StrictMode 안전) */
|
|
5433
|
+
const initialHex = normalizeHex(value || defaultValue) || '#006FFF';
|
|
5434
|
+
const initialRgb = hexToRgb(initialHex) || { r: 0, g: 111, b: 255 };
|
|
5435
|
+
const initialHsv = rgbToHsv(initialRgb.r, initialRgb.g, initialRgb.b);
|
|
5436
|
+
const [h, setH] = useState(() => initialHsv.h);
|
|
5437
|
+
const [s, setS] = useState(() => initialHsv.s);
|
|
5438
|
+
const [v, setV] = useState(() => initialHsv.v);
|
|
5438
5439
|
const [a, setA] = useState(100);
|
|
5439
5440
|
const [isOpen, setIsOpen] = useState(false);
|
|
5440
5441
|
const [format, setFormat] = useState('hex');
|
|
5441
5442
|
const [isCopied, setIsCopied] = useState(false);
|
|
5442
|
-
const [colorInput, setColorInput] = useState(
|
|
5443
|
+
const [colorInput, setColorInput] = useState(() => initialHex);
|
|
5443
5444
|
const [alphaInput, setAlphaInput] = useState('100');
|
|
5444
5445
|
const [tempColor, setTempColor] = useState('');
|
|
5445
5446
|
const pickerRef = useRef(null);
|
|
5446
5447
|
const areaRef = useRef(null);
|
|
5447
5448
|
const dragging = useRef(false);
|
|
5448
|
-
/**
|
|
5449
|
+
/** onChange 보호 상태 */
|
|
5450
|
+
const lastEmittedRef = useRef(normalizeHex(initialHex)); // ✅ 초기값 미리 기록
|
|
5451
|
+
const didMountRef = useRef(false); // ✅ 첫 렌더 감지
|
|
5452
|
+
const emitErrorCountRef = useRef(0);
|
|
5453
|
+
const emitBlockedUntilRef = useRef(0);
|
|
5454
|
+
/** 제어형(value) 변화 → HSV 반영 */
|
|
5449
5455
|
useEffect(() => {
|
|
5450
|
-
|
|
5451
|
-
const rgb = hexToRgb(initial);
|
|
5452
|
-
if (rgb) {
|
|
5453
|
-
const { h, s, v } = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
5454
|
-
setH(h);
|
|
5455
|
-
setS(s);
|
|
5456
|
-
setV(v);
|
|
5457
|
-
}
|
|
5458
|
-
setColorInput(initial);
|
|
5459
|
-
setAlphaInput('100');
|
|
5460
|
-
}, []);
|
|
5461
|
-
/** 제어형(value) → HSV */
|
|
5462
|
-
useEffect(() => {
|
|
5463
|
-
if (!value)
|
|
5456
|
+
if (value == null)
|
|
5464
5457
|
return;
|
|
5465
|
-
const
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5458
|
+
const norm = normalizeHex(value);
|
|
5459
|
+
const rgb = hexToRgb(norm);
|
|
5460
|
+
if (!rgb)
|
|
5461
|
+
return;
|
|
5462
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
5463
|
+
setH(hsv.h);
|
|
5464
|
+
setS(hsv.s);
|
|
5465
|
+
setV(hsv.v);
|
|
5466
|
+
setColorInput(norm);
|
|
5472
5467
|
}, [value]);
|
|
5473
|
-
/**
|
|
5468
|
+
/** 파생값 */
|
|
5474
5469
|
const rgb = useMemo(() => hsvToRgb(h, s, v), [h, s, v]);
|
|
5475
|
-
const hex = useMemo(() =>
|
|
5470
|
+
const hex = useMemo(() => toHex(rgb.r, rgb.g, rgb.b), [rgb]);
|
|
5476
5471
|
const hsl = useMemo(() => rgbToHsl(rgb.r, rgb.g, rgb.b), [rgb]);
|
|
5477
|
-
/**
|
|
5478
|
-
const
|
|
5472
|
+
/** UI 표시 문자열 */
|
|
5473
|
+
const uiFormatted = useMemo(() => {
|
|
5479
5474
|
const alpha = a / 100;
|
|
5480
5475
|
switch (format) {
|
|
5481
5476
|
case 'hex': return hex;
|
|
5482
5477
|
case 'rgb': return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
|
5483
5478
|
case 'rgba': return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha.toFixed(2)})`;
|
|
5484
|
-
case 'hsl': return `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;
|
|
5485
|
-
case 'hsla': return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${alpha.toFixed(2)})`;
|
|
5479
|
+
case 'hsl': return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
|
|
5480
|
+
case 'hsla': return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${alpha.toFixed(2)})`;
|
|
5486
5481
|
default: return hex;
|
|
5487
5482
|
}
|
|
5488
5483
|
}, [format, hex, rgb, hsl, a]);
|
|
5489
|
-
/**
|
|
5484
|
+
/** 콜백으로 내보낼 문자열 */
|
|
5485
|
+
const outward = useMemo(() => {
|
|
5486
|
+
if (onChangeFormat === 'hex')
|
|
5487
|
+
return hex;
|
|
5488
|
+
return uiFormatted;
|
|
5489
|
+
}, [hex, uiFormatted, onChangeFormat]);
|
|
5490
|
+
/** 최초 렌더 스킵 + 동일값/레이트리밋 검사 후 onChange */
|
|
5490
5491
|
useEffect(() => {
|
|
5491
|
-
if (
|
|
5492
|
+
if (!onChange)
|
|
5493
|
+
return;
|
|
5494
|
+
// 첫 렌더는 기본 차단 (옵션으로 허용)
|
|
5495
|
+
if (!didMountRef.current) {
|
|
5496
|
+
didMountRef.current = true;
|
|
5497
|
+
if (!fireOnInit)
|
|
5498
|
+
return; // 기본: 초기 발사 금지
|
|
5499
|
+
}
|
|
5500
|
+
const now = Date.now();
|
|
5501
|
+
if (emitBlockedUntilRef.current > now)
|
|
5492
5502
|
return;
|
|
5493
|
-
|
|
5503
|
+
const currentHexNorm = normalizeHex(outward);
|
|
5504
|
+
const last = lastEmittedRef.current;
|
|
5505
|
+
// 제어형: 부모 value와 동일하면 발사 금지
|
|
5506
|
+
if (value && normalizeHex(value) === currentHexNorm)
|
|
5507
|
+
return;
|
|
5508
|
+
// 직전 발사값과 동일하면 금지
|
|
5509
|
+
if (last === currentHexNorm)
|
|
5510
|
+
return;
|
|
5511
|
+
const fire = () => {
|
|
5512
|
+
try {
|
|
5513
|
+
lastEmittedRef.current = currentHexNorm;
|
|
5514
|
+
onChange(onChangeFormat === 'hex' ? currentHexNorm : outward);
|
|
5515
|
+
emitErrorCountRef.current = 0;
|
|
5516
|
+
}
|
|
5517
|
+
catch (e) {
|
|
5518
|
+
emitErrorCountRef.current += 1;
|
|
5519
|
+
if (emitErrorCountRef.current >= 20) {
|
|
5520
|
+
emitBlockedUntilRef.current = Date.now() + 3000;
|
|
5521
|
+
// eslint-disable-next-line no-console
|
|
5522
|
+
console.warn('[ColorPicker] onChange errors too frequent; temporarily muted.');
|
|
5523
|
+
}
|
|
5524
|
+
}
|
|
5525
|
+
};
|
|
5526
|
+
if (changeDebounceMs > 0) {
|
|
5527
|
+
const t = setTimeout(fire, changeDebounceMs);
|
|
5528
|
+
return () => clearTimeout(t);
|
|
5529
|
+
}
|
|
5530
|
+
fire();
|
|
5494
5531
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5495
|
-
}, [
|
|
5496
|
-
/**
|
|
5532
|
+
}, [outward]); // 의도적으로 onChange/value 제외
|
|
5533
|
+
/** colorInput 동기화(표시 전용) */
|
|
5497
5534
|
useEffect(() => {
|
|
5498
|
-
|
|
5499
|
-
|
|
5535
|
+
const next = format === 'hex' ? normalizeHex(uiFormatted) : uiFormatted;
|
|
5536
|
+
if (colorInput !== next)
|
|
5537
|
+
setColorInput(next);
|
|
5538
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5539
|
+
}, [uiFormatted, format]);
|
|
5500
5540
|
/** 드롭다운 외부 클릭 닫기 */
|
|
5501
5541
|
useEffect(() => {
|
|
5502
5542
|
const handler = (e) => {
|
|
5503
|
-
if (pickerRef.current && !pickerRef.current.contains(e.target))
|
|
5543
|
+
if (pickerRef.current && !pickerRef.current.contains(e.target))
|
|
5504
5544
|
setIsOpen(false);
|
|
5505
|
-
}
|
|
5506
5545
|
};
|
|
5507
5546
|
if (isOpen && type === 'dropdown')
|
|
5508
5547
|
document.addEventListener('mousedown', handler);
|
|
@@ -5516,8 +5555,8 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5516
5555
|
const rect = el.getBoundingClientRect();
|
|
5517
5556
|
const x = clamp(clientX - rect.left, 0, rect.width);
|
|
5518
5557
|
const y = clamp(clientY - rect.top, 0, rect.height);
|
|
5519
|
-
const newS =
|
|
5520
|
-
const newV =
|
|
5558
|
+
const newS = (x / rect.width) * 100;
|
|
5559
|
+
const newV = 100 - (y / rect.height) * 100;
|
|
5521
5560
|
setS(newS);
|
|
5522
5561
|
setV(newV);
|
|
5523
5562
|
};
|
|
@@ -5531,13 +5570,13 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5531
5570
|
return; const t = e.touches[0]; updateFromArea(t.clientX, t.clientY); };
|
|
5532
5571
|
const onAreaTouchEnd = () => { dragging.current = false; };
|
|
5533
5572
|
/** 슬라이더 */
|
|
5534
|
-
const onHueChange = useCallback((e) => setH(
|
|
5573
|
+
const onHueChange = useCallback((e) => setH(parseFloat(e.target.value)), []);
|
|
5535
5574
|
const onAlphaChange = useCallback((e) => {
|
|
5536
5575
|
const newAlpha = parseInt(e.target.value, 10);
|
|
5537
5576
|
setA(newAlpha);
|
|
5538
5577
|
setAlphaInput(String(newAlpha));
|
|
5539
5578
|
}, []);
|
|
5540
|
-
/** 컬러 인풋
|
|
5579
|
+
/** 컬러 인풋 확정 */
|
|
5541
5580
|
const commitColorInput = useCallback(() => {
|
|
5542
5581
|
const str = colorInput.trim();
|
|
5543
5582
|
if (/^#([0-9A-Fa-f]{6})$/.test(str)) {
|
|
@@ -5546,7 +5585,7 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5546
5585
|
setH(hsv.h);
|
|
5547
5586
|
setS(hsv.s);
|
|
5548
5587
|
setV(hsv.v);
|
|
5549
|
-
setColorInput(str
|
|
5588
|
+
setColorInput(normalizeHex(str));
|
|
5550
5589
|
return;
|
|
5551
5590
|
}
|
|
5552
5591
|
let m = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i.exec(str);
|
|
@@ -5558,7 +5597,7 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5558
5597
|
setH(hsv.h);
|
|
5559
5598
|
setS(hsv.s);
|
|
5560
5599
|
setV(hsv.v);
|
|
5561
|
-
setColorInput(`rgb(${r}, ${g}, ${b})
|
|
5600
|
+
setColorInput(`rgb(${r}, ${g}, ${b})`);
|
|
5562
5601
|
return;
|
|
5563
5602
|
}
|
|
5564
5603
|
m = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+)\s*\)$/i.exec(str);
|
|
@@ -5573,42 +5612,47 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5573
5612
|
setV(hsv.v);
|
|
5574
5613
|
setA(Math.round(alpha * 100));
|
|
5575
5614
|
setAlphaInput(String(Math.round(alpha * 100)));
|
|
5576
|
-
setColorInput(`rgba(${r}, ${g}, ${b}, ${alpha})
|
|
5615
|
+
setColorInput(`rgba(${r}, ${g}, ${b}, ${alpha})`);
|
|
5577
5616
|
return;
|
|
5578
5617
|
}
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5618
|
+
// 인식 실패 → 표시값으로 원복
|
|
5619
|
+
setColorInput(format === 'hex' ? normalizeHex(uiFormatted) : uiFormatted);
|
|
5620
|
+
}, [colorInput, uiFormatted, format]);
|
|
5621
|
+
const onColorKeyDown = (e) => { if (e.key === 'Enter')
|
|
5622
|
+
commitColorInput(); };
|
|
5623
|
+
const onColorBlur = () => {
|
|
5624
|
+
const next = format === 'hex' ? normalizeHex(uiFormatted) : uiFormatted;
|
|
5625
|
+
if (colorInput !== next)
|
|
5626
|
+
setColorInput(next);
|
|
5584
5627
|
};
|
|
5585
|
-
|
|
5586
|
-
/** 알파 인풋 (엔터 확정) */
|
|
5628
|
+
/** 알파 인풋 확정 */
|
|
5587
5629
|
const commitAlphaInput = useCallback(() => {
|
|
5588
5630
|
const n = Number(alphaInput.trim());
|
|
5589
5631
|
if (!Number.isNaN(n) && n >= 0 && n <= 100) {
|
|
5590
|
-
|
|
5591
|
-
|
|
5632
|
+
const rounded = Math.round(n);
|
|
5633
|
+
if (a !== rounded)
|
|
5634
|
+
setA(rounded);
|
|
5635
|
+
if (alphaInput !== String(rounded))
|
|
5636
|
+
setAlphaInput(String(rounded));
|
|
5592
5637
|
return;
|
|
5593
5638
|
}
|
|
5594
5639
|
setAlphaInput(String(a));
|
|
5595
5640
|
}, [alphaInput, a]);
|
|
5596
|
-
const onAlphaInputKeyDown = (e) => {
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
const onAlphaInputBlur = () => setAlphaInput(String(a));
|
|
5641
|
+
const onAlphaInputKeyDown = (e) => { if (e.key === 'Enter')
|
|
5642
|
+
commitAlphaInput(); };
|
|
5643
|
+
const onAlphaInputBlur = () => { if (alphaInput !== String(a))
|
|
5644
|
+
setAlphaInput(String(a)); };
|
|
5601
5645
|
/** 복사 */
|
|
5602
5646
|
const onCopy = useCallback(async () => {
|
|
5603
5647
|
try {
|
|
5604
|
-
await navigator.clipboard.writeText(
|
|
5648
|
+
await navigator.clipboard.writeText(uiFormatted);
|
|
5605
5649
|
setIsCopied(true);
|
|
5606
5650
|
setTimeout(() => setIsCopied(false), 1600);
|
|
5607
5651
|
}
|
|
5608
5652
|
catch (e) {
|
|
5609
5653
|
console.error(e);
|
|
5610
5654
|
}
|
|
5611
|
-
}, [
|
|
5655
|
+
}, [uiFormatted]);
|
|
5612
5656
|
/** EyeDropper */
|
|
5613
5657
|
const onEyedrop = useCallback(async () => {
|
|
5614
5658
|
try {
|
|
@@ -5626,7 +5670,7 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5626
5670
|
console.error(e);
|
|
5627
5671
|
}
|
|
5628
5672
|
}, []);
|
|
5629
|
-
/**
|
|
5673
|
+
/** 모달 */
|
|
5630
5674
|
const handleModalOpen = useCallback(() => {
|
|
5631
5675
|
if (type === 'modal')
|
|
5632
5676
|
setTempColor(hex);
|
|
@@ -5634,10 +5678,11 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5634
5678
|
}, [type, hex]);
|
|
5635
5679
|
const handleModalApply = useCallback(() => {
|
|
5636
5680
|
if (type === 'modal') {
|
|
5637
|
-
|
|
5681
|
+
const out = onChangeFormat === 'hex' ? hex : uiFormatted;
|
|
5682
|
+
onApply?.(out);
|
|
5638
5683
|
setIsOpen(false);
|
|
5639
5684
|
}
|
|
5640
|
-
}, [type,
|
|
5685
|
+
}, [type, hex, uiFormatted, onApply, onChangeFormat]);
|
|
5641
5686
|
const handleModalCancel = useCallback(() => {
|
|
5642
5687
|
if (type === 'modal') {
|
|
5643
5688
|
const rgb = hexToRgb(tempColor);
|
|
@@ -5654,28 +5699,28 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5654
5699
|
/** 스타일 */
|
|
5655
5700
|
const hueTrackStyle = useMemo(() => ({
|
|
5656
5701
|
background: `linear-gradient(to right,
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5702
|
+
hsl(0,100%,50%),
|
|
5703
|
+
hsl(60,100%,50%),
|
|
5704
|
+
hsl(120,100%,50%),
|
|
5705
|
+
hsl(180,100%,50%),
|
|
5706
|
+
hsl(240,100%,50%),
|
|
5707
|
+
hsl(300,100%,50%),
|
|
5708
|
+
hsl(360,100%,50%))`,
|
|
5664
5709
|
}), []);
|
|
5665
5710
|
const areaBackground = useMemo(() => ({
|
|
5666
5711
|
backgroundImage: `
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5712
|
+
linear-gradient(to top, rgba(0,0,0,1), rgba(0,0,0,0)),
|
|
5713
|
+
linear-gradient(to right, #ffffff, hsl(${h}, 100%, 50%))
|
|
5714
|
+
`,
|
|
5670
5715
|
}), [h]);
|
|
5671
5716
|
const alphaTrackStyle = useMemo(() => ({
|
|
5672
5717
|
backgroundImage: `
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5718
|
+
linear-gradient(45deg, var(--db-border-base) 25%, transparent 25%),
|
|
5719
|
+
linear-gradient(-45deg, var(--db-border-base) 25%, transparent 25%),
|
|
5720
|
+
linear-gradient(45deg, transparent 75%, var(--db-border-base) 75%),
|
|
5721
|
+
linear-gradient(-45deg, transparent 75%, var(--db-border-base) 75%),
|
|
5722
|
+
linear-gradient(to right, rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0), rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 1))
|
|
5723
|
+
`,
|
|
5679
5724
|
backgroundSize: '8px 8px,8px 8px,8px 8px,8px 8px,100% 100%',
|
|
5680
5725
|
backgroundPosition: '0 0,0 4px,4px -4px,-4px 0,0 0',
|
|
5681
5726
|
backgroundColor: 'var(--db-surface-base)',
|
|
@@ -5687,9 +5732,7 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
5687
5732
|
'designbase-color-picker--no-input': !showInput,
|
|
5688
5733
|
}, className);
|
|
5689
5734
|
const Trigger = (jsxs("div", { className: "designbase-color-picker__trigger", onClick: () => !disabled && !readonly && (type === 'modal' ? handleModalOpen() : setIsOpen(v => !v)), children: [jsx("div", { className: "designbase-color-picker__color-display", children: jsx("div", { className: "designbase-color-picker__color-box", style: {
|
|
5690
|
-
backgroundColor: showAlpha
|
|
5691
|
-
? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a / 100})`
|
|
5692
|
-
: hex
|
|
5735
|
+
backgroundColor: showAlpha ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a / 100})` : hex
|
|
5693
5736
|
} }) }), showInput && (jsx("input", { type: "text", value: colorInput, onChange: (e) => setColorInput(e.target.value), onKeyDown: onColorKeyDown, onBlur: onColorBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-color-picker__input", placeholder: "#000000" })), showInput && showCopyButton && (jsx("button", { type: "button", className: "designbase-color-picker__copy-button-inline", onClick: (e) => { e.stopPropagation(); onCopy(); }, disabled: disabled, "aria-label": "Copy color value", children: isCopied ? jsx(DoneIcon$1, { size: 14 }) : jsx(CopyIcon, { size: 14 }) })), jsx("button", { type: "button", className: "designbase-color-picker__toggle", disabled: disabled, "aria-label": "Toggle color picker", children: jsx(ChevronDownIcon, { size: 16 }) })] }));
|
|
5694
5737
|
const Selector = (jsxs("div", { className: "designbase-color-picker__selector", children: [jsx("div", { className: "designbase-color-picker__color-area", children: jsx("div", { ref: areaRef, className: "designbase-color-picker__color-field", style: areaBackground, onMouseDown: onAreaMouseDown, onMouseMove: onAreaMouseMove, onMouseUp: onAreaMouseUp, onMouseLeave: onAreaLeave, onTouchStart: onAreaTouchStart, onTouchMove: onAreaTouchMove, onTouchEnd: onAreaTouchEnd, children: jsx("div", { className: "designbase-color-picker__color-pointer", style: { left: `${s}%`, top: `${100 - v}%`, backgroundColor: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` } }) }) }), jsxs("div", { className: "designbase-color-picker__controls", children: [jsx(Button, { variant: "tertiary", size: "m", iconOnly: true, onClick: onEyedrop, "aria-label": "Eyedropper tool", children: jsx(EyedropperIcon, {}) }), jsxs("div", { className: "designbase-color-picker__slider-container", children: [jsx("div", { className: "designbase-color-picker__hue-slider", children: jsx("input", { type: "range", min: 0, max: 360, value: h, onChange: onHueChange, className: "designbase-color-picker__slider designbase-color-picker__slider--hue", style: hueTrackStyle }) }), showAlpha && (jsx("div", { className: "designbase-color-picker__alpha-slider", children: jsx("input", { type: "range", min: 0, max: 100, value: a, onChange: onAlphaChange, className: "designbase-color-picker__slider designbase-color-picker__slider--alpha", style: alphaTrackStyle }) }))] })] }), jsxs("div", { className: "designbase-color-picker__value-display", children: [showFormatSelector && (jsx(Select, { value: format, onChange: (v) => setFormat(v), showClearButton: false, options: [
|
|
5695
5738
|
{ label: 'HEX', value: 'hex' },
|