@fab1o978/react-ui 0.1.7 → 0.2.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/dist/components/Badge/index.d.cts +3 -3
- package/dist/components/Badge/index.d.ts +3 -3
- package/dist/components/Button/index.d.cts +3 -3
- package/dist/components/Button/index.d.ts +3 -3
- package/dist/components/ColorPicker/index.cjs +3 -1
- package/dist/components/ColorPicker/index.cjs.map +1 -1
- package/dist/components/ColorPicker/index.d.cts +2 -2
- package/dist/components/ColorPicker/index.d.ts +2 -2
- package/dist/components/ColorPicker/index.js +3 -1
- package/dist/components/ColorPicker/index.js.map +1 -1
- package/dist/components/ColorWheel/index.cjs +671 -0
- package/dist/components/ColorWheel/index.cjs.map +1 -0
- package/dist/components/ColorWheel/index.css +494 -0
- package/dist/components/ColorWheel/index.css.map +1 -0
- package/dist/components/ColorWheel/index.d.cts +49 -0
- package/dist/components/ColorWheel/index.d.ts +49 -0
- package/dist/components/ColorWheel/index.js +669 -0
- package/dist/components/ColorWheel/index.js.map +1 -0
- package/dist/components/Input/index.d.cts +5 -5
- package/dist/components/Input/index.d.ts +5 -5
- package/dist/components/RainCanvas/index.d.cts +4 -4
- package/dist/components/RainCanvas/index.d.ts +4 -4
- package/dist/components/RichTextEditor/index.d.cts +6 -6
- package/dist/components/RichTextEditor/index.d.ts +6 -6
- package/dist/components/SliderControl/index.cjs +3 -1
- package/dist/components/SliderControl/index.cjs.map +1 -1
- package/dist/components/SliderControl/index.d.cts +5 -4
- package/dist/components/SliderControl/index.d.ts +5 -4
- package/dist/components/SliderControl/index.js +3 -1
- package/dist/components/SliderControl/index.js.map +1 -1
- package/dist/components/SlidingCounter/index.d.cts +2 -2
- package/dist/components/SlidingCounter/index.d.ts +2 -2
- package/dist/components/Timeline/index.d.cts +3 -3
- package/dist/components/Timeline/index.d.ts +3 -3
- package/dist/index.cjs +591 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +494 -0
- 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 +592 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -651,6 +651,7 @@ var SliderControl = ({
|
|
|
651
651
|
step = 1,
|
|
652
652
|
onChange,
|
|
653
653
|
showTooltip = "drag",
|
|
654
|
+
showPercentage = false,
|
|
654
655
|
leftIcon,
|
|
655
656
|
rightIcon,
|
|
656
657
|
railBackground,
|
|
@@ -744,7 +745,8 @@ var SliderControl = ({
|
|
|
744
745
|
[disabled, step, min, max, value, setValue]
|
|
745
746
|
);
|
|
746
747
|
const tooltipVisible = showTooltip === "always" || showTooltip === "drag" && (isDragging || isFocused);
|
|
747
|
-
const
|
|
748
|
+
const decimals = step < 1 ? Math.ceil(-Math.log10(step)) : 0;
|
|
749
|
+
const displayValue = showPercentage ? `${Math.round((value - min) / (max - min) * 100)}%` : value.toFixed(decimals);
|
|
748
750
|
const tooltipOffset = `calc(${pct * 100}% + ${(0.5 - pct) * 20}px)`;
|
|
749
751
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
750
752
|
"div",
|
|
@@ -4693,6 +4695,593 @@ var PageBreakButton = () => {
|
|
|
4693
4695
|
);
|
|
4694
4696
|
};
|
|
4695
4697
|
|
|
4698
|
+
// src/components/ColorWheel/ColorWheel.module.scss
|
|
4699
|
+
var ColorWheel_module_default = {
|
|
4700
|
+
root: "ColorWheel_module_root",
|
|
4701
|
+
recents: "ColorWheel_module_recents",
|
|
4702
|
+
chipWrap: "ColorWheel_module_chipWrap",
|
|
4703
|
+
chip: "ColorWheel_module_chip",
|
|
4704
|
+
chipRemove: "ColorWheel_module_chipRemove",
|
|
4705
|
+
picker: "ColorWheel_module_picker",
|
|
4706
|
+
glow: "ColorWheel_module_glow",
|
|
4707
|
+
modeToggle: "ColorWheel_module_modeToggle",
|
|
4708
|
+
modePill: "ColorWheel_module_modePill",
|
|
4709
|
+
modeButton: "ColorWheel_module_modeButton",
|
|
4710
|
+
active: "ColorWheel_module_active",
|
|
4711
|
+
stage: "ColorWheel_module_stage",
|
|
4712
|
+
stageShadow: "ColorWheel_module_stageShadow",
|
|
4713
|
+
ring: "ColorWheel_module_ring",
|
|
4714
|
+
hueHandlePivot: "ColorWheel_module_hueHandlePivot",
|
|
4715
|
+
hueHandle: "ColorWheel_module_hueHandle",
|
|
4716
|
+
alphaArcShadowWrap: "ColorWheel_module_alphaArcShadowWrap",
|
|
4717
|
+
alphaArcShadow: "ColorWheel_module_alphaArcShadow",
|
|
4718
|
+
alphaArc: "ColorWheel_module_alphaArc",
|
|
4719
|
+
alphaArcFill: "ColorWheel_module_alphaArcFill",
|
|
4720
|
+
alphaArcCap: "ColorWheel_module_alphaArcCap",
|
|
4721
|
+
alphaArcCapStart: "ColorWheel_module_alphaArcCapStart",
|
|
4722
|
+
alphaArcCapEnd: "ColorWheel_module_alphaArcCapEnd",
|
|
4723
|
+
alphaArcHandle: "ColorWheel_module_alphaArcHandle",
|
|
4724
|
+
currentDisc: "ColorWheel_module_currentDisc",
|
|
4725
|
+
discFill: "ColorWheel_module_discFill",
|
|
4726
|
+
currentHex: "ColorWheel_module_currentHex",
|
|
4727
|
+
currentHexInput: "ColorWheel_module_currentHexInput",
|
|
4728
|
+
copied: "ColorWheel_module_copied",
|
|
4729
|
+
discBadge: "ColorWheel_module_discBadge",
|
|
4730
|
+
discBadgeTop: "ColorWheel_module_discBadgeTop",
|
|
4731
|
+
pulse: "ColorWheel_module_pulse",
|
|
4732
|
+
discBadgeBottom: "ColorWheel_module_discBadgeBottom"
|
|
4733
|
+
};
|
|
4734
|
+
function usePointerDrag(ref, onMove, onEnd, onDraggingChange) {
|
|
4735
|
+
const onMoveRef = React.useRef(onMove);
|
|
4736
|
+
onMoveRef.current = onMove;
|
|
4737
|
+
const onEndRef = React.useRef(onEnd);
|
|
4738
|
+
onEndRef.current = onEnd;
|
|
4739
|
+
const onDraggingChangeRef = React.useRef(onDraggingChange);
|
|
4740
|
+
onDraggingChangeRef.current = onDraggingChange;
|
|
4741
|
+
React.useEffect(() => {
|
|
4742
|
+
const el = ref.current;
|
|
4743
|
+
if (!el) return;
|
|
4744
|
+
function pointerPos(e) {
|
|
4745
|
+
return { x: e.clientX, y: e.clientY };
|
|
4746
|
+
}
|
|
4747
|
+
function move(e) {
|
|
4748
|
+
onMoveRef.current(pointerPos(e));
|
|
4749
|
+
}
|
|
4750
|
+
function up() {
|
|
4751
|
+
onDraggingChangeRef.current?.(false);
|
|
4752
|
+
window.removeEventListener("pointermove", move);
|
|
4753
|
+
window.removeEventListener("pointerup", up);
|
|
4754
|
+
onEndRef.current?.();
|
|
4755
|
+
}
|
|
4756
|
+
function down(e) {
|
|
4757
|
+
const pe = e;
|
|
4758
|
+
pe.preventDefault();
|
|
4759
|
+
pe.stopPropagation();
|
|
4760
|
+
onDraggingChangeRef.current?.(true);
|
|
4761
|
+
onMoveRef.current(pointerPos(pe));
|
|
4762
|
+
window.addEventListener("pointermove", move);
|
|
4763
|
+
window.addEventListener("pointerup", up);
|
|
4764
|
+
}
|
|
4765
|
+
el.addEventListener("pointerdown", down);
|
|
4766
|
+
return () => {
|
|
4767
|
+
el.removeEventListener("pointerdown", down);
|
|
4768
|
+
window.removeEventListener("pointermove", move);
|
|
4769
|
+
window.removeEventListener("pointerup", up);
|
|
4770
|
+
};
|
|
4771
|
+
}, [ref]);
|
|
4772
|
+
}
|
|
4773
|
+
function useUnwrappedAngle(targetDeg) {
|
|
4774
|
+
const continuousRef = React.useRef(targetDeg);
|
|
4775
|
+
const targetMod = (targetDeg % 360 + 360) % 360;
|
|
4776
|
+
const currentMod = (continuousRef.current % 360 + 360) % 360;
|
|
4777
|
+
let delta = targetMod - currentMod;
|
|
4778
|
+
if (delta > 180) delta -= 360;
|
|
4779
|
+
else if (delta < -180) delta += 360;
|
|
4780
|
+
continuousRef.current += delta;
|
|
4781
|
+
return continuousRef.current;
|
|
4782
|
+
}
|
|
4783
|
+
|
|
4784
|
+
// src/components/ColorWheel/colorMath.ts
|
|
4785
|
+
function hsvToRgb(h, s, v) {
|
|
4786
|
+
s /= 100;
|
|
4787
|
+
v /= 100;
|
|
4788
|
+
const c = v * s;
|
|
4789
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
4790
|
+
const m = v - c;
|
|
4791
|
+
let r, g, b;
|
|
4792
|
+
if (h < 60) {
|
|
4793
|
+
r = c;
|
|
4794
|
+
g = x;
|
|
4795
|
+
b = 0;
|
|
4796
|
+
} else if (h < 120) {
|
|
4797
|
+
r = x;
|
|
4798
|
+
g = c;
|
|
4799
|
+
b = 0;
|
|
4800
|
+
} else if (h < 180) {
|
|
4801
|
+
r = 0;
|
|
4802
|
+
g = c;
|
|
4803
|
+
b = x;
|
|
4804
|
+
} else if (h < 240) {
|
|
4805
|
+
r = 0;
|
|
4806
|
+
g = x;
|
|
4807
|
+
b = c;
|
|
4808
|
+
} else if (h < 300) {
|
|
4809
|
+
r = x;
|
|
4810
|
+
g = 0;
|
|
4811
|
+
b = c;
|
|
4812
|
+
} else {
|
|
4813
|
+
r = c;
|
|
4814
|
+
g = 0;
|
|
4815
|
+
b = x;
|
|
4816
|
+
}
|
|
4817
|
+
return {
|
|
4818
|
+
r: Math.round((r + m) * 255),
|
|
4819
|
+
g: Math.round((g + m) * 255),
|
|
4820
|
+
b: Math.round((b + m) * 255)
|
|
4821
|
+
};
|
|
4822
|
+
}
|
|
4823
|
+
function rgbToHsv(r, g, b) {
|
|
4824
|
+
r /= 255;
|
|
4825
|
+
g /= 255;
|
|
4826
|
+
b /= 255;
|
|
4827
|
+
const max = Math.max(r, g, b);
|
|
4828
|
+
const min = Math.min(r, g, b);
|
|
4829
|
+
const d = max - min;
|
|
4830
|
+
let h = 0;
|
|
4831
|
+
if (d !== 0) {
|
|
4832
|
+
if (max === r) h = (g - b) / d % 6;
|
|
4833
|
+
else if (max === g) h = (b - r) / d + 2;
|
|
4834
|
+
else h = (r - g) / d + 4;
|
|
4835
|
+
h *= 60;
|
|
4836
|
+
if (h < 0) h += 360;
|
|
4837
|
+
}
|
|
4838
|
+
const s = max === 0 ? 0 : d / max;
|
|
4839
|
+
return { h, s: s * 100, v: max * 100 };
|
|
4840
|
+
}
|
|
4841
|
+
function toHexByte(n) {
|
|
4842
|
+
const h = Math.max(0, Math.min(255, Math.round(n))).toString(16);
|
|
4843
|
+
return h.length === 1 ? "0" + h : h;
|
|
4844
|
+
}
|
|
4845
|
+
function rgbToHex(c) {
|
|
4846
|
+
return ("#" + toHexByte(c.r) + toHexByte(c.g) + toHexByte(c.b)).toUpperCase();
|
|
4847
|
+
}
|
|
4848
|
+
function hsvaToHex(hsv, a) {
|
|
4849
|
+
const rgb = hsvToRgb(hsv.h, hsv.s, hsv.v);
|
|
4850
|
+
let hex = rgbToHex(rgb);
|
|
4851
|
+
if (a < 1) hex += toHexByte(Math.round(a * 255));
|
|
4852
|
+
return hex;
|
|
4853
|
+
}
|
|
4854
|
+
function hexToHsva(input) {
|
|
4855
|
+
let clean = input.trim().replace(/^#/, "");
|
|
4856
|
+
if (/^[0-9a-fA-F]{3}$/.test(clean)) {
|
|
4857
|
+
clean = clean.split("").map((ch) => ch + ch).join("");
|
|
4858
|
+
}
|
|
4859
|
+
if (!/^[0-9a-fA-F]{6}$/.test(clean) && !/^[0-9a-fA-F]{8}$/.test(clean)) return null;
|
|
4860
|
+
const r = parseInt(clean.slice(0, 2), 16);
|
|
4861
|
+
const g = parseInt(clean.slice(2, 4), 16);
|
|
4862
|
+
const b = parseInt(clean.slice(4, 6), 16);
|
|
4863
|
+
const a = clean.length === 8 ? parseInt(clean.slice(6, 8), 16) / 255 : 1;
|
|
4864
|
+
return { hsv: rgbToHsv(r, g, b), a };
|
|
4865
|
+
}
|
|
4866
|
+
function clamp2(v, min, max) {
|
|
4867
|
+
return Math.min(max, Math.max(min, v));
|
|
4868
|
+
}
|
|
4869
|
+
function round2(n) {
|
|
4870
|
+
return Math.round(n * 100) / 100;
|
|
4871
|
+
}
|
|
4872
|
+
function angleDistance(a, b) {
|
|
4873
|
+
const d = Math.abs(a - b) % 360;
|
|
4874
|
+
return d > 180 ? 360 - d : d;
|
|
4875
|
+
}
|
|
4876
|
+
function relativeLuminance(c) {
|
|
4877
|
+
return (0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) / 255;
|
|
4878
|
+
}
|
|
4879
|
+
var RING_SPECTRUM = "conic-gradient(from 180deg, hsl(0 100% 50%) 0%, hsl(60 100% 50%) 16.667%, hsl(120 100% 50%) 33.333%, hsl(180 100% 50%) 50%, hsl(240 100% 50%) 66.667%, hsl(300 100% 50%) 83.333%, hsl(360 100% 50%) 100%)";
|
|
4880
|
+
var RING_INNER_FRAC = 0.3382;
|
|
4881
|
+
var RING_OUTER_FRAC = 0.5;
|
|
4882
|
+
var ARC_A0 = 30;
|
|
4883
|
+
var ARC_A1 = 150;
|
|
4884
|
+
var ARC_HANDLE_R_FRAC = 152 / 380;
|
|
4885
|
+
var MODES_HSV = ["h", "s", "v"];
|
|
4886
|
+
var MODES_HSVA = ["h", "s", "v", "a"];
|
|
4887
|
+
function ringGradient(mode, hsv) {
|
|
4888
|
+
if (mode === "s") {
|
|
4889
|
+
const grey = rgbToHex(hsvToRgb(hsv.h, 0, hsv.v));
|
|
4890
|
+
const full = rgbToHex(hsvToRgb(hsv.h, 100, hsv.v));
|
|
4891
|
+
return `conic-gradient(from 180deg, ${grey} 0deg, ${full} 360deg)`;
|
|
4892
|
+
}
|
|
4893
|
+
if (mode === "v") {
|
|
4894
|
+
const bright = rgbToHex(hsvToRgb(hsv.h, hsv.s, 100));
|
|
4895
|
+
return `conic-gradient(from 180deg, #000000 0deg, ${bright} 360deg)`;
|
|
4896
|
+
}
|
|
4897
|
+
if (mode === "a") {
|
|
4898
|
+
const full = rgbToHex(hsvToRgb(hsv.h, hsv.s, hsv.v));
|
|
4899
|
+
return `conic-gradient(from 180deg, transparent 0deg, ${full} 360deg)`;
|
|
4900
|
+
}
|
|
4901
|
+
return RING_SPECTRUM;
|
|
4902
|
+
}
|
|
4903
|
+
var EMPTY_FAVORITES = [];
|
|
4904
|
+
function ColorWheel({
|
|
4905
|
+
value,
|
|
4906
|
+
onChange,
|
|
4907
|
+
favorites = EMPTY_FAVORITES,
|
|
4908
|
+
onFavoritesChange,
|
|
4909
|
+
maxFavorites = 5,
|
|
4910
|
+
showAlphaControl = true,
|
|
4911
|
+
alphaMode = "arc",
|
|
4912
|
+
theme = "system",
|
|
4913
|
+
size = 1,
|
|
4914
|
+
accent,
|
|
4915
|
+
className
|
|
4916
|
+
}) {
|
|
4917
|
+
const ringIsFourWay = showAlphaControl && alphaMode === "ring";
|
|
4918
|
+
const arcVisible = showAlphaControl && alphaMode === "arc";
|
|
4919
|
+
const modes = ringIsFourWay ? MODES_HSVA : MODES_HSV;
|
|
4920
|
+
const parsed = React.useMemo(() => hexToHsva(value), [value]);
|
|
4921
|
+
const [hsv, setHsv] = React.useState(() => parsed?.hsv ?? { h: 0, s: 0, v: 100 });
|
|
4922
|
+
const [alpha, setAlpha] = React.useState(() => parsed?.a ?? 1);
|
|
4923
|
+
const [mode, setMode] = React.useState("h");
|
|
4924
|
+
const [dragging, setDragging] = React.useState(false);
|
|
4925
|
+
const [copied, setCopied] = React.useState(false);
|
|
4926
|
+
const [pulseFavorite, setPulseFavorite] = React.useState(false);
|
|
4927
|
+
const [editing, setEditing] = React.useState(false);
|
|
4928
|
+
const [editValue, setEditValue] = React.useState("");
|
|
4929
|
+
const [eyedropperSupported, setEyedropperSupported] = React.useState(false);
|
|
4930
|
+
const accentVars = accent ? accentToCssVars(deriveAccent(accent), "colorwheel") : {};
|
|
4931
|
+
const lastEmitted = React.useRef(value);
|
|
4932
|
+
React.useEffect(() => {
|
|
4933
|
+
if (value === lastEmitted.current) return;
|
|
4934
|
+
const next = hexToHsva(value);
|
|
4935
|
+
if (next) {
|
|
4936
|
+
setHsv(next.hsv);
|
|
4937
|
+
setAlpha(next.a);
|
|
4938
|
+
}
|
|
4939
|
+
lastEmitted.current = value;
|
|
4940
|
+
}, [value]);
|
|
4941
|
+
React.useEffect(() => {
|
|
4942
|
+
setEyedropperSupported(typeof window !== "undefined" && "EyeDropper" in window);
|
|
4943
|
+
}, []);
|
|
4944
|
+
React.useEffect(() => {
|
|
4945
|
+
if (!ringIsFourWay && mode === "a") setMode("h");
|
|
4946
|
+
}, [ringIsFourWay, mode]);
|
|
4947
|
+
const stageRef = React.useRef(null);
|
|
4948
|
+
const alphaArcRef = React.useRef(null);
|
|
4949
|
+
const modeToggleRef = React.useRef(null);
|
|
4950
|
+
const hexInputRef = React.useRef(null);
|
|
4951
|
+
function commit(nextHsv, nextAlpha) {
|
|
4952
|
+
setHsv(nextHsv);
|
|
4953
|
+
setAlpha(nextAlpha);
|
|
4954
|
+
const hex = hsvaToHex(nextHsv, nextAlpha);
|
|
4955
|
+
lastEmitted.current = hex;
|
|
4956
|
+
onChange(hex);
|
|
4957
|
+
}
|
|
4958
|
+
const rgb = hsvToRgb(hsv.h, hsv.s, hsv.v);
|
|
4959
|
+
const solidHex = rgbToHex(rgb);
|
|
4960
|
+
const hexString = hsvaToHex(hsv, alpha);
|
|
4961
|
+
const luminance = relativeLuminance(rgb);
|
|
4962
|
+
const isLight = luminance > 0.58;
|
|
4963
|
+
const discText = isLight ? "#1A1913" : "#FFFFFF";
|
|
4964
|
+
const badgeBg = isLight ? "rgba(0,0,0,0.02)" : "rgba(255,255,255,0.03)";
|
|
4965
|
+
const badgeGrooveDark = isLight ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.32)";
|
|
4966
|
+
const badgeGrooveLight = isLight ? "rgba(255,255,255,0.35)" : "rgba(255,255,255,0.12)";
|
|
4967
|
+
const badgeIcon = isLight ? "rgba(0,0,0,0.72)" : "rgba(255,255,255,0.88)";
|
|
4968
|
+
const badgeShadow = {
|
|
4969
|
+
background: badgeBg,
|
|
4970
|
+
color: badgeIcon,
|
|
4971
|
+
boxShadow: `inset 0 1px 1px ${badgeGrooveDark}, inset 0 -1px 1px ${badgeGrooveLight}`
|
|
4972
|
+
};
|
|
4973
|
+
const ringLogicalAngle = mode === "h" ? hsv.h : mode === "a" ? alpha * 360 : (mode === "s" ? hsv.s : hsv.v) / 100 * 360;
|
|
4974
|
+
const ringAngleFromTopDeg = useUnwrappedAngle(180 + ringLogicalAngle);
|
|
4975
|
+
const arcLogicalAngle = ARC_A1 - alpha * (ARC_A1 - ARC_A0);
|
|
4976
|
+
const arcAngleFromTop = (90 + arcLogicalAngle) * (Math.PI / 180);
|
|
4977
|
+
const arcHandleR = ARC_HANDLE_R_FRAC * 380;
|
|
4978
|
+
const arcHandleDx = arcHandleR * Math.sin(arcAngleFromTop);
|
|
4979
|
+
const arcHandleDy = -arcHandleR * Math.cos(arcAngleFromTop);
|
|
4980
|
+
function applyRingAngle(angle) {
|
|
4981
|
+
if (mode === "h") commit({ ...hsv, h: angle }, alpha);
|
|
4982
|
+
else if (mode === "s") commit({ ...hsv, s: angle / 360 * 100 }, alpha);
|
|
4983
|
+
else if (mode === "a") commit(hsv, angle / 360);
|
|
4984
|
+
else commit({ ...hsv, v: angle / 360 * 100 }, alpha);
|
|
4985
|
+
}
|
|
4986
|
+
const dragPrevAngleRef = React.useRef(null);
|
|
4987
|
+
const dragAccumRef = React.useRef(0);
|
|
4988
|
+
usePointerDrag(
|
|
4989
|
+
stageRef,
|
|
4990
|
+
(pos) => {
|
|
4991
|
+
const rect = stageRef.current.getBoundingClientRect();
|
|
4992
|
+
const cx = rect.left + rect.width / 2;
|
|
4993
|
+
const cy = rect.top + rect.height / 2;
|
|
4994
|
+
const dx = pos.x - cx;
|
|
4995
|
+
const dy = pos.y - cy;
|
|
4996
|
+
const dist = Math.hypot(dx, dy);
|
|
4997
|
+
if (dist < rect.width * RING_INNER_FRAC || dist > rect.width * RING_OUTER_FRAC) return;
|
|
4998
|
+
let angle = Math.atan2(dy, dx) * (180 / Math.PI) - 90;
|
|
4999
|
+
angle = (angle % 360 + 360) % 360;
|
|
5000
|
+
if (mode === "h") {
|
|
5001
|
+
applyRingAngle(angle);
|
|
5002
|
+
return;
|
|
5003
|
+
}
|
|
5004
|
+
if (dragPrevAngleRef.current === null) {
|
|
5005
|
+
dragAccumRef.current = angle;
|
|
5006
|
+
} else {
|
|
5007
|
+
let delta = angle - dragPrevAngleRef.current;
|
|
5008
|
+
if (delta > 180) delta -= 360;
|
|
5009
|
+
else if (delta < -180) delta += 360;
|
|
5010
|
+
dragAccumRef.current = clamp2(dragAccumRef.current + delta, 0, 360);
|
|
5011
|
+
}
|
|
5012
|
+
dragPrevAngleRef.current = angle;
|
|
5013
|
+
applyRingAngle(dragAccumRef.current);
|
|
5014
|
+
},
|
|
5015
|
+
void 0,
|
|
5016
|
+
(dragging2) => {
|
|
5017
|
+
if (!dragging2) dragPrevAngleRef.current = null;
|
|
5018
|
+
setDragging(dragging2);
|
|
5019
|
+
}
|
|
5020
|
+
);
|
|
5021
|
+
React.useEffect(() => {
|
|
5022
|
+
const el = stageRef.current;
|
|
5023
|
+
if (!el) return;
|
|
5024
|
+
function onWheel(e) {
|
|
5025
|
+
const rect = el.getBoundingClientRect();
|
|
5026
|
+
const cx = rect.left + rect.width / 2;
|
|
5027
|
+
const cy = rect.top + rect.height / 2;
|
|
5028
|
+
const dist = Math.hypot(e.clientX - cx, e.clientY - cy);
|
|
5029
|
+
if (dist < rect.width * RING_INNER_FRAC || dist > rect.width * RING_OUTER_FRAC) return;
|
|
5030
|
+
e.preventDefault();
|
|
5031
|
+
const dir = e.deltaY > 0 ? -1 : 1;
|
|
5032
|
+
if (mode === "h") commit({ ...hsv, h: (hsv.h + dir * 4 + 360) % 360 }, alpha);
|
|
5033
|
+
else if (mode === "s") commit({ ...hsv, s: clamp2(hsv.s + dir * 3, 0, 100) }, alpha);
|
|
5034
|
+
else if (mode === "a") commit(hsv, clamp2(round2(alpha + dir * 0.03), 0, 1));
|
|
5035
|
+
else commit({ ...hsv, v: clamp2(hsv.v + dir * 3, 0, 100) }, alpha);
|
|
5036
|
+
}
|
|
5037
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
5038
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
5039
|
+
}, [mode, hsv, alpha]);
|
|
5040
|
+
usePointerDrag(
|
|
5041
|
+
alphaArcRef,
|
|
5042
|
+
(pos) => {
|
|
5043
|
+
const rect = alphaArcRef.current.getBoundingClientRect();
|
|
5044
|
+
const cx = rect.left + rect.width / 2;
|
|
5045
|
+
const cy = rect.top + rect.height / 2;
|
|
5046
|
+
let angle = Math.atan2(pos.y - cy, pos.x - cx) * (180 / Math.PI);
|
|
5047
|
+
if (angle < 0) angle += 360;
|
|
5048
|
+
if (angle < ARC_A0 || angle > ARC_A1) {
|
|
5049
|
+
angle = angleDistance(angle, ARC_A0) < angleDistance(angle, ARC_A1) ? ARC_A0 : ARC_A1;
|
|
5050
|
+
}
|
|
5051
|
+
commit(hsv, round2((ARC_A1 - angle) / (ARC_A1 - ARC_A0)));
|
|
5052
|
+
},
|
|
5053
|
+
void 0,
|
|
5054
|
+
setDragging
|
|
5055
|
+
);
|
|
5056
|
+
React.useEffect(() => {
|
|
5057
|
+
const el = alphaArcRef.current;
|
|
5058
|
+
if (!el) return;
|
|
5059
|
+
function onWheel(e) {
|
|
5060
|
+
e.preventDefault();
|
|
5061
|
+
const dir = e.deltaY > 0 ? -1 : 1;
|
|
5062
|
+
commit(hsv, clamp2(round2(alpha + dir * 0.05), 0, 1));
|
|
5063
|
+
}
|
|
5064
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
5065
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
5066
|
+
}, [hsv, alpha]);
|
|
5067
|
+
React.useEffect(() => {
|
|
5068
|
+
const el = modeToggleRef.current;
|
|
5069
|
+
if (!el) return;
|
|
5070
|
+
function onWheel(e) {
|
|
5071
|
+
e.preventDefault();
|
|
5072
|
+
const idx = modes.indexOf(mode);
|
|
5073
|
+
const dir = e.deltaY > 0 ? -1 : 1;
|
|
5074
|
+
setMode(modes[clamp2(idx + dir, 0, modes.length - 1)]);
|
|
5075
|
+
}
|
|
5076
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
5077
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
5078
|
+
}, [mode, modes]);
|
|
5079
|
+
function handleDiscClick() {
|
|
5080
|
+
const done = () => {
|
|
5081
|
+
setCopied(true);
|
|
5082
|
+
setTimeout(() => setCopied(false), 900);
|
|
5083
|
+
};
|
|
5084
|
+
if (navigator.clipboard?.writeText) {
|
|
5085
|
+
navigator.clipboard.writeText(hexString).then(done, done);
|
|
5086
|
+
} else {
|
|
5087
|
+
done();
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
function beginEdit(e) {
|
|
5091
|
+
e.stopPropagation();
|
|
5092
|
+
setEditValue(hexString);
|
|
5093
|
+
setEditing(true);
|
|
5094
|
+
requestAnimationFrame(() => {
|
|
5095
|
+
hexInputRef.current?.focus();
|
|
5096
|
+
hexInputRef.current?.setSelectionRange(1, hexString.length);
|
|
5097
|
+
});
|
|
5098
|
+
}
|
|
5099
|
+
function commitEdit(cancelled) {
|
|
5100
|
+
if (!cancelled) {
|
|
5101
|
+
const next = hexToHsva(editValue);
|
|
5102
|
+
if (next) commit(next.hsv, next.a);
|
|
5103
|
+
}
|
|
5104
|
+
setEditing(false);
|
|
5105
|
+
}
|
|
5106
|
+
function pickFromScreen() {
|
|
5107
|
+
const dropper = new window.EyeDropper();
|
|
5108
|
+
dropper.open().then((result) => {
|
|
5109
|
+
const next = hexToHsva(result.sRGBHex);
|
|
5110
|
+
if (next) commit(next.hsv, next.a);
|
|
5111
|
+
}).catch(() => {
|
|
5112
|
+
});
|
|
5113
|
+
}
|
|
5114
|
+
function saveFavorite() {
|
|
5115
|
+
const next = [hexString, ...favorites.filter((h) => h !== hexString)].slice(0, maxFavorites);
|
|
5116
|
+
onFavoritesChange?.(next);
|
|
5117
|
+
setPulseFavorite(false);
|
|
5118
|
+
requestAnimationFrame(() => setPulseFavorite(true));
|
|
5119
|
+
}
|
|
5120
|
+
function applyFavorite(hex) {
|
|
5121
|
+
const next = hexToHsva(hex);
|
|
5122
|
+
if (next) commit(next.hsv, next.a);
|
|
5123
|
+
}
|
|
5124
|
+
function removeFavorite(hex) {
|
|
5125
|
+
onFavoritesChange?.(favorites.filter((h) => h !== hex));
|
|
5126
|
+
}
|
|
5127
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5128
|
+
"div",
|
|
5129
|
+
{
|
|
5130
|
+
className: [ColorWheel_module_default.root, className].filter(Boolean).join(" "),
|
|
5131
|
+
"data-theme": theme === "system" ? void 0 : theme,
|
|
5132
|
+
"data-dragging": dragging ? "true" : void 0,
|
|
5133
|
+
style: {
|
|
5134
|
+
...accentVars,
|
|
5135
|
+
...size !== 1 ? { transform: `scale(${size})`, transformOrigin: "top center" } : void 0
|
|
5136
|
+
},
|
|
5137
|
+
children: [
|
|
5138
|
+
favorites.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.recents, children: favorites.map((hex, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorWheel_module_default.chipWrap, style: { animationDelay: `${i * 0.02}s` }, children: [
|
|
5139
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5140
|
+
"button",
|
|
5141
|
+
{
|
|
5142
|
+
type: "button",
|
|
5143
|
+
className: ColorWheel_module_default.chip,
|
|
5144
|
+
style: { background: hex.length > 7 ? hex.slice(0, 7) : hex },
|
|
5145
|
+
title: hex,
|
|
5146
|
+
"aria-label": `Apply color ${hex}`,
|
|
5147
|
+
onClick: () => applyFavorite(hex)
|
|
5148
|
+
}
|
|
5149
|
+
),
|
|
5150
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5151
|
+
"button",
|
|
5152
|
+
{
|
|
5153
|
+
type: "button",
|
|
5154
|
+
className: ColorWheel_module_default.chipRemove,
|
|
5155
|
+
"aria-label": `Remove ${hex} from favorites`,
|
|
5156
|
+
onClick: (e) => {
|
|
5157
|
+
e.stopPropagation();
|
|
5158
|
+
removeFavorite(hex);
|
|
5159
|
+
},
|
|
5160
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 3, strokeLinecap: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 6l12 12M18 6L6 18" }) })
|
|
5161
|
+
}
|
|
5162
|
+
)
|
|
5163
|
+
] }, hex + i)) }),
|
|
5164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorWheel_module_default.picker, children: [
|
|
5165
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5166
|
+
"div",
|
|
5167
|
+
{
|
|
5168
|
+
className: ColorWheel_module_default.glow,
|
|
5169
|
+
style: { background: `radial-gradient(closest-side, ${solidHex}, transparent 72%)` }
|
|
5170
|
+
}
|
|
5171
|
+
),
|
|
5172
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5173
|
+
"div",
|
|
5174
|
+
{
|
|
5175
|
+
className: ColorWheel_module_default.modeToggle,
|
|
5176
|
+
ref: modeToggleRef,
|
|
5177
|
+
style: { width: modes.length * 28, gridTemplateColumns: `repeat(${modes.length}, 1fr)` },
|
|
5178
|
+
children: [
|
|
5179
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5180
|
+
"div",
|
|
5181
|
+
{
|
|
5182
|
+
className: ColorWheel_module_default.modePill,
|
|
5183
|
+
style: {
|
|
5184
|
+
width: `calc(${100 / modes.length}% - 2px)`,
|
|
5185
|
+
transform: `translateX(calc(${modes.indexOf(mode)} * (100% + 1px)))`
|
|
5186
|
+
}
|
|
5187
|
+
}
|
|
5188
|
+
),
|
|
5189
|
+
modes.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5190
|
+
"button",
|
|
5191
|
+
{
|
|
5192
|
+
type: "button",
|
|
5193
|
+
className: [ColorWheel_module_default.modeButton, mode === m ? ColorWheel_module_default.active : ""].join(" "),
|
|
5194
|
+
onClick: () => setMode(m),
|
|
5195
|
+
children: m.toUpperCase()
|
|
5196
|
+
},
|
|
5197
|
+
m
|
|
5198
|
+
))
|
|
5199
|
+
]
|
|
5200
|
+
}
|
|
5201
|
+
),
|
|
5202
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorWheel_module_default.stage, ref: stageRef, children: [
|
|
5203
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.stageShadow }),
|
|
5204
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.ring, style: { background: ringGradient(mode, hsv) } }),
|
|
5205
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ColorWheel_module_default.currentDisc, onClick: handleDiscClick, children: [
|
|
5206
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.discFill, style: { background: `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})` } }),
|
|
5207
|
+
!editing && /* @__PURE__ */ jsxRuntime.jsx("span", { className: [ColorWheel_module_default.currentHex, copied ? ColorWheel_module_default.copied : ""].join(" "), style: { color: discText }, onClick: beginEdit, children: copied ? "Copied" : hexString }),
|
|
5208
|
+
editing && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5209
|
+
"input",
|
|
5210
|
+
{
|
|
5211
|
+
ref: hexInputRef,
|
|
5212
|
+
className: ColorWheel_module_default.currentHexInput,
|
|
5213
|
+
style: { color: discText },
|
|
5214
|
+
type: "text",
|
|
5215
|
+
inputMode: "text",
|
|
5216
|
+
autoComplete: "off",
|
|
5217
|
+
spellCheck: false,
|
|
5218
|
+
maxLength: 9,
|
|
5219
|
+
value: editValue,
|
|
5220
|
+
onClick: (e) => e.stopPropagation(),
|
|
5221
|
+
onChange: (e) => setEditValue(e.target.value),
|
|
5222
|
+
onKeyDown: (e) => {
|
|
5223
|
+
if (e.key === "Enter") hexInputRef.current?.blur();
|
|
5224
|
+
else if (e.key === "Escape") {
|
|
5225
|
+
commitEdit(true);
|
|
5226
|
+
}
|
|
5227
|
+
},
|
|
5228
|
+
onBlur: () => commitEdit(false)
|
|
5229
|
+
}
|
|
5230
|
+
)
|
|
5231
|
+
] }),
|
|
5232
|
+
eyedropperSupported && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5233
|
+
"button",
|
|
5234
|
+
{
|
|
5235
|
+
type: "button",
|
|
5236
|
+
className: [ColorWheel_module_default.discBadge, ColorWheel_module_default.discBadgeBottom].join(" "),
|
|
5237
|
+
style: badgeShadow,
|
|
5238
|
+
"aria-label": "Pick color from screen",
|
|
5239
|
+
onClick: pickFromScreen,
|
|
5240
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 32 32", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M27.7,3.3c-1.5-1.5-3.9-1.5-5.4,0L17,8.6l-1.3-1.3c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l1.3,1.3L5,20.6c-0.6,0.6-1,1.4-1.1,2.3C3.3,23.4,3,24.2,3,25c0,1.7,1.3,3,3,3c0.8,0,1.6-0.3,2.2-0.9C9,27,9.8,26.6,10.4,26L21,15.4l1.3,1.3c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L22.4,14l5.3-5.3C29.2,7.2,29.2,4.8,27.7,3.3z M9,24.6c-0.4,0.4-0.8,0.6-1.3,0.5c-0.4,0-0.7,0.2-0.9,0.5C6.7,25.8,6.3,26,6,26c-0.6,0-1-0.4-1-1c0-0.3,0.2-0.7,0.5-0.8c0.3-0.2,0.5-0.5,0.5-0.9c0-0.5,0.2-1,0.5-1.3L17,11.4l2.6,2.6L9,24.6z" }) })
|
|
5241
|
+
}
|
|
5242
|
+
),
|
|
5243
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5244
|
+
"button",
|
|
5245
|
+
{
|
|
5246
|
+
type: "button",
|
|
5247
|
+
className: [ColorWheel_module_default.discBadge, ColorWheel_module_default.discBadgeTop, pulseFavorite ? ColorWheel_module_default.pulse : ""].join(" "),
|
|
5248
|
+
style: badgeShadow,
|
|
5249
|
+
"aria-label": "Save current color to favorites",
|
|
5250
|
+
onClick: saveFavorite,
|
|
5251
|
+
onAnimationEnd: () => setPulseFavorite(false),
|
|
5252
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 5v14M5 12h14" }) })
|
|
5253
|
+
}
|
|
5254
|
+
),
|
|
5255
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.hueHandlePivot, style: { transform: `translate(-50%, -50%) rotate(${ringAngleFromTopDeg}deg)` }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.hueHandle, style: { background: solidHex } }) })
|
|
5256
|
+
] }),
|
|
5257
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: arcVisible ? "contents" : "none" }, children: [
|
|
5258
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.alphaArcShadowWrap, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.alphaArcShadow }) }),
|
|
5259
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ColorWheel_module_default.alphaArc, ref: alphaArcRef, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5260
|
+
"div",
|
|
5261
|
+
{
|
|
5262
|
+
className: ColorWheel_module_default.alphaArcFill,
|
|
5263
|
+
style: { background: `conic-gradient(from 90deg, ${solidHex} 30deg, transparent 150deg)` }
|
|
5264
|
+
}
|
|
5265
|
+
) }),
|
|
5266
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: [ColorWheel_module_default.alphaArcCap, ColorWheel_module_default.alphaArcCapStart].join(" "), style: { background: solidHex } }),
|
|
5267
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: [ColorWheel_module_default.alphaArcCap, ColorWheel_module_default.alphaArcCapEnd].join(" ") }),
|
|
5268
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5269
|
+
"div",
|
|
5270
|
+
{
|
|
5271
|
+
className: ColorWheel_module_default.alphaArcHandle,
|
|
5272
|
+
style: {
|
|
5273
|
+
transform: `translate(calc(-50% + ${arcHandleDx}px), calc(-50% + ${arcHandleDy}px))`,
|
|
5274
|
+
background: solidHex
|
|
5275
|
+
}
|
|
5276
|
+
}
|
|
5277
|
+
)
|
|
5278
|
+
] })
|
|
5279
|
+
] })
|
|
5280
|
+
]
|
|
5281
|
+
}
|
|
5282
|
+
);
|
|
5283
|
+
}
|
|
5284
|
+
|
|
4696
5285
|
Object.defineProperty(exports, "useCurrentEditor", {
|
|
4697
5286
|
enumerable: true,
|
|
4698
5287
|
get: function () { return react.useCurrentEditor; }
|
|
@@ -4700,6 +5289,7 @@ Object.defineProperty(exports, "useCurrentEditor", {
|
|
|
4700
5289
|
exports.Badge = Badge;
|
|
4701
5290
|
exports.Button = Button;
|
|
4702
5291
|
exports.ColorPicker = ColorPicker;
|
|
5292
|
+
exports.ColorWheel = ColorWheel;
|
|
4703
5293
|
exports.Highlight = Highlight;
|
|
4704
5294
|
exports.HighlightButton = HighlightButton;
|
|
4705
5295
|
exports.Input = Input;
|