@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/index.js CHANGED
@@ -599,10 +599,6 @@ var ColorPicker_module_default = {
599
599
  discWrapper: "ColorPicker_module_discWrapper",
600
600
  disc: "ColorPicker_module_disc",
601
601
  dot: "ColorPicker_module_dot",
602
- lSlider: "ColorPicker_module_lSlider",
603
- lThumb: "ColorPicker_module_lThumb",
604
- alphaSlider: "ColorPicker_module_alphaSlider",
605
- alphaThumb: "ColorPicker_module_alphaThumb",
606
602
  previewSwatch: "ColorPicker_module_previewSwatch",
607
603
  eyedropperBtn: "ColorPicker_module_eyedropperBtn",
608
604
  inputSection: "ColorPicker_module_inputSection",
@@ -618,6 +614,192 @@ var ColorPicker_module_default = {
618
614
  swatches: "ColorPicker_module_swatches",
619
615
  recentSwatch: "ColorPicker_module_recentSwatch"
620
616
  };
617
+
618
+ // src/components/SliderControl/SliderControl.module.scss
619
+ var SliderControl_module_default = {
620
+ wrapper: "SliderControl_module_wrapper",
621
+ disabled: "SliderControl_module_disabled",
622
+ icon: "SliderControl_module_icon",
623
+ trackArea: "SliderControl_module_trackArea",
624
+ groove: "SliderControl_module_groove",
625
+ rail: "SliderControl_module_rail",
626
+ fill: "SliderControl_module_fill",
627
+ thumb: "SliderControl_module_thumb",
628
+ thumbDragging: "SliderControl_module_thumbDragging",
629
+ tooltip: "SliderControl_module_tooltip",
630
+ tooltipVisible: "SliderControl_module_tooltipVisible"
631
+ };
632
+ function clamp(v, min, max) {
633
+ return Math.min(Math.max(v, min), max);
634
+ }
635
+ function snapToStep(v, min, step) {
636
+ return Math.round((v - min) / step) * step + min;
637
+ }
638
+ var SliderControl = ({
639
+ value: controlledValue,
640
+ defaultValue = 50,
641
+ min = 0,
642
+ max = 100,
643
+ step = 1,
644
+ onChange,
645
+ showTooltip = "drag",
646
+ showPercentage = false,
647
+ leftIcon,
648
+ rightIcon,
649
+ railBackground,
650
+ accent,
651
+ className,
652
+ disabled = false
653
+ }) => {
654
+ const isControlled = controlledValue !== void 0;
655
+ const [internalValue, setInternalValue] = useState(defaultValue);
656
+ const [isDragging, setIsDragging] = useState(false);
657
+ const [isFocused, setIsFocused] = useState(false);
658
+ const trackRef = useRef(null);
659
+ const thumbRef = useRef(null);
660
+ const value = isControlled ? controlledValue : internalValue;
661
+ const pct = (clamp(value, min, max) - min) / (max - min);
662
+ const accentVars = accent ? accentToCssVars(deriveAccent(accent), "slider") : {};
663
+ const setValue = useCallback(
664
+ (next) => {
665
+ const snapped = clamp(snapToStep(next, min, step), min, max);
666
+ if (!isControlled) setInternalValue(snapped);
667
+ onChange?.(snapped);
668
+ },
669
+ [isControlled, min, max, step, onChange]
670
+ );
671
+ const valueFromPointer = useCallback(
672
+ (e) => {
673
+ const rect = trackRef.current.getBoundingClientRect();
674
+ const ratio = clamp((e.clientX - rect.left) / rect.width, 0, 1);
675
+ return min + ratio * (max - min);
676
+ },
677
+ [min, max]
678
+ );
679
+ const handlePointerDown = useCallback(
680
+ (e) => {
681
+ if (disabled) return;
682
+ e.currentTarget.setPointerCapture(e.pointerId);
683
+ setIsDragging(true);
684
+ thumbRef.current?.focus();
685
+ setValue(valueFromPointer(e.nativeEvent));
686
+ },
687
+ [disabled, setValue, valueFromPointer]
688
+ );
689
+ const handlePointerMove = useCallback(
690
+ (e) => {
691
+ if (!isDragging || disabled) return;
692
+ setValue(valueFromPointer(e.nativeEvent));
693
+ },
694
+ [isDragging, disabled, setValue, valueFromPointer]
695
+ );
696
+ const handlePointerUp = useCallback(() => {
697
+ setIsDragging(false);
698
+ thumbRef.current?.blur();
699
+ }, []);
700
+ useEffect(() => {
701
+ const el = trackRef.current;
702
+ if (!el) return;
703
+ const onWheel = (e) => {
704
+ if (disabled) return;
705
+ e.preventDefault();
706
+ setValue(value + (e.deltaY < 0 ? step : -step));
707
+ };
708
+ el.addEventListener("wheel", onWheel, { passive: false });
709
+ return () => el.removeEventListener("wheel", onWheel);
710
+ }, [disabled, value, step, setValue]);
711
+ const handleKeyDown = useCallback(
712
+ (e) => {
713
+ if (disabled) return;
714
+ const map = {
715
+ ArrowRight: step,
716
+ ArrowUp: step,
717
+ ArrowLeft: -step,
718
+ ArrowDown: -step,
719
+ PageUp: step * 10,
720
+ PageDown: -step * 10
721
+ };
722
+ if (e.key === "Home") {
723
+ setValue(min);
724
+ e.preventDefault();
725
+ return;
726
+ }
727
+ if (e.key === "End") {
728
+ setValue(max);
729
+ e.preventDefault();
730
+ return;
731
+ }
732
+ if (map[e.key] !== void 0) {
733
+ setValue(value + map[e.key]);
734
+ e.preventDefault();
735
+ }
736
+ },
737
+ [disabled, step, min, max, value, setValue]
738
+ );
739
+ const tooltipVisible = showTooltip === "always" || showTooltip === "drag" && (isDragging || isFocused);
740
+ const decimals = step < 1 ? Math.ceil(-Math.log10(step)) : 0;
741
+ const displayValue = showPercentage ? `${Math.round((value - min) / (max - min) * 100)}%` : value.toFixed(decimals);
742
+ const tooltipOffset = `calc(${pct * 100}% + ${(0.5 - pct) * 20}px)`;
743
+ return /* @__PURE__ */ jsxs(
744
+ "div",
745
+ {
746
+ className: [SliderControl_module_default.wrapper, disabled ? SliderControl_module_default.disabled : "", className ?? ""].filter(Boolean).join(" "),
747
+ style: accentVars,
748
+ children: [
749
+ leftIcon !== null && leftIcon !== void 0 && /* @__PURE__ */ jsx("span", { className: SliderControl_module_default.icon, children: leftIcon }),
750
+ /* @__PURE__ */ jsxs(
751
+ "div",
752
+ {
753
+ ref: trackRef,
754
+ className: SliderControl_module_default.trackArea,
755
+ onPointerDown: handlePointerDown,
756
+ onPointerMove: handlePointerMove,
757
+ onPointerUp: handlePointerUp,
758
+ onPointerCancel: handlePointerUp,
759
+ children: [
760
+ /* @__PURE__ */ jsx("div", { className: SliderControl_module_default.groove, children: /* @__PURE__ */ jsx(
761
+ "div",
762
+ {
763
+ className: SliderControl_module_default.rail,
764
+ style: railBackground ? { background: railBackground } : void 0,
765
+ children: !railBackground && /* @__PURE__ */ jsx("div", { className: SliderControl_module_default.fill, style: { width: `${pct * 100}%` } })
766
+ }
767
+ ) }),
768
+ /* @__PURE__ */ jsx(
769
+ "div",
770
+ {
771
+ ref: thumbRef,
772
+ role: "slider",
773
+ tabIndex: disabled ? -1 : 0,
774
+ "aria-valuenow": Math.round(value),
775
+ "aria-valuemin": min,
776
+ "aria-valuemax": max,
777
+ "aria-disabled": disabled,
778
+ className: [SliderControl_module_default.thumb, isDragging ? SliderControl_module_default.thumbDragging : ""].filter(Boolean).join(" "),
779
+ style: { left: `calc(${pct * 100}% + ${(0.5 - pct) * 24}px)` },
780
+ onKeyDown: handleKeyDown,
781
+ onFocus: () => setIsFocused(true),
782
+ onBlur: () => setIsFocused(false)
783
+ }
784
+ ),
785
+ /* @__PURE__ */ jsx(
786
+ "div",
787
+ {
788
+ className: [SliderControl_module_default.tooltip, tooltipVisible ? SliderControl_module_default.tooltipVisible : ""].filter(Boolean).join(" "),
789
+ style: { left: tooltipOffset },
790
+ "aria-hidden": "true",
791
+ children: displayValue
792
+ }
793
+ )
794
+ ]
795
+ }
796
+ ),
797
+ rightIcon !== null && rightIcon !== void 0 && /* @__PURE__ */ jsx("span", { className: SliderControl_module_default.icon, children: rightIcon })
798
+ ]
799
+ }
800
+ );
801
+ };
802
+ SliderControl.displayName = "SliderControl";
621
803
  var DISC = 200;
622
804
  var CopyIcon = () => /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [
623
805
  /* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "7", height: "7", rx: "1.5", stroke: "currentColor", strokeWidth: "1.4" }),
@@ -787,50 +969,21 @@ var ColorPicker = ({
787
969
  },
788
970
  [updateDisc]
789
971
  );
790
- const updateL = useCallback(
791
- (clientX, rect) => {
792
- const nl = Math.max(0, Math.min(100, (clientX - rect.left) / rect.width * 100));
972
+ const handleLChange = useCallback(
973
+ (nl) => {
793
974
  setL(nl);
794
975
  notify(h, s, nl, a);
795
976
  },
796
977
  [h, s, a, notify]
797
978
  );
798
- const handleLPointerDown = useCallback(
799
- (e) => {
800
- e.currentTarget.setPointerCapture(e.pointerId);
801
- updateL(e.clientX, e.currentTarget.getBoundingClientRect());
802
- },
803
- [updateL]
804
- );
805
- const handleLPointerMove = useCallback(
806
- (e) => {
807
- if (e.buttons === 0) return;
808
- updateL(e.clientX, e.currentTarget.getBoundingClientRect());
809
- },
810
- [updateL]
811
- );
812
- const updateA = useCallback(
813
- (clientX, rect) => {
814
- const na = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
979
+ const handleAChange = useCallback(
980
+ (val) => {
981
+ const na = val / 100;
815
982
  setA(na);
816
983
  notify(h, s, l, na);
817
984
  },
818
985
  [h, s, l, notify]
819
986
  );
820
- const handleAPointerDown = useCallback(
821
- (e) => {
822
- e.currentTarget.setPointerCapture(e.pointerId);
823
- updateA(e.clientX, e.currentTarget.getBoundingClientRect());
824
- },
825
- [updateA]
826
- );
827
- const handleAPointerMove = useCallback(
828
- (e) => {
829
- if (e.buttons === 0) return;
830
- updateA(e.clientX, e.currentTarget.getBoundingClientRect());
831
- },
832
- [updateA]
833
- );
834
987
  const { r: rr, g: gg, b: bb } = hslToRgb(h, s, l);
835
988
  const luminance = (0.299 * rr + 0.587 * gg + 0.114 * bb) / 255;
836
989
  const swatchFg = luminance > 0.6 ? "rgba(0,0,0,0.5)" : "rgba(255,255,255,0.9)";
@@ -843,7 +996,6 @@ var ColorPicker = ({
843
996
  hsl(${h}, ${s}%, 5%),
844
997
  hsl(${h}, ${s}%, 50%),
845
998
  hsl(${h}, ${s}%, 95%))`;
846
- const alphaGradient = `linear-gradient(to right, transparent, ${rgbStr})`;
847
999
  const handleEyeDropper = async () => {
848
1000
  if (!window.EyeDropper) return;
849
1001
  try {
@@ -904,35 +1056,27 @@ var ColorPicker = ({
904
1056
  )
905
1057
  ] }) }),
906
1058
  /* @__PURE__ */ jsx(
907
- "div",
1059
+ SliderControl,
908
1060
  {
909
- className: ColorPicker_module_default.lSlider,
910
- style: { backgroundImage: lGradient },
911
- onPointerDown: handleLPointerDown,
912
- onPointerMove: handleLPointerMove,
913
- children: /* @__PURE__ */ jsx(
914
- "div",
915
- {
916
- className: ColorPicker_module_default.lThumb,
917
- style: { left: `${l}%` }
918
- }
919
- )
1061
+ value: l,
1062
+ onChange: handleLChange,
1063
+ min: 0,
1064
+ max: 100,
1065
+ step: 1,
1066
+ showTooltip: "never",
1067
+ railBackground: lGradient
920
1068
  }
921
1069
  ),
922
1070
  showAlpha && /* @__PURE__ */ jsx(
923
- "div",
1071
+ SliderControl,
924
1072
  {
925
- className: ColorPicker_module_default.alphaSlider,
926
- style: { backgroundImage: alphaGradient },
927
- onPointerDown: handleAPointerDown,
928
- onPointerMove: handleAPointerMove,
929
- children: /* @__PURE__ */ jsx(
930
- "div",
931
- {
932
- className: ColorPicker_module_default.alphaThumb,
933
- style: { left: `${a * 100}%` }
934
- }
935
- )
1073
+ value: Math.round(a * 100),
1074
+ onChange: handleAChange,
1075
+ min: 0,
1076
+ max: 100,
1077
+ step: 1,
1078
+ showTooltip: "never",
1079
+ railBackground: `linear-gradient(to right, transparent, ${rgbStr}), repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 0 / 10px 10px`
936
1080
  }
937
1081
  ),
938
1082
  /* @__PURE__ */ jsx(
@@ -4543,6 +4687,6 @@ var PageBreakButton = () => {
4543
4687
  );
4544
4688
  };
4545
4689
 
4546
- export { Badge, Button, ColorPicker, Highlight, HighlightButton, Input, PageBreak, PageBreakButton, RainCanvas, RichTextEditor, SlidingCounter, Timeline };
4690
+ export { Badge, Button, ColorPicker, Highlight, HighlightButton, Input, PageBreak, PageBreakButton, RainCanvas, RichTextEditor, SliderControl, SlidingCounter, Timeline };
4547
4691
  //# sourceMappingURL=index.js.map
4548
4692
  //# sourceMappingURL=index.js.map