@janovix/blocks 1.0.0-rc.2 → 1.0.0-rc.3

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.cjs CHANGED
@@ -6,6 +6,10 @@ var react = require('motion/react');
6
6
  var React32 = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var ReactDOM = require('react-dom');
9
+ var SliderPrimitive = require('@radix-ui/react-slider');
10
+ var TogglePrimitive = require('@radix-ui/react-toggle');
11
+ var DialogPrimitive = require('@radix-ui/react-dialog');
12
+ var vaul = require('vaul');
9
13
 
10
14
  function _interopNamespace(e) {
11
15
  if (e && e.__esModule) return e;
@@ -27,6 +31,9 @@ function _interopNamespace(e) {
27
31
 
28
32
  var React32__namespace = /*#__PURE__*/_interopNamespace(React32);
29
33
  var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
34
+ var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
35
+ var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespace(TogglePrimitive);
36
+ var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
30
37
 
31
38
  function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
32
39
  return function handleEvent(event) {
@@ -9528,8 +9535,1109 @@ function LanguageSwitcher({
9528
9535
  }
9529
9536
  );
9530
9537
  }
9538
+ function Slider({
9539
+ className,
9540
+ defaultValue,
9541
+ value,
9542
+ min: min2 = 0,
9543
+ max: max2 = 100,
9544
+ ...props
9545
+ }) {
9546
+ const _values = React32__namespace.useMemo(
9547
+ () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min2, max2],
9548
+ [value, defaultValue, min2, max2]
9549
+ );
9550
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9551
+ SliderPrimitive__namespace.Root,
9552
+ {
9553
+ "data-slot": "slider",
9554
+ defaultValue,
9555
+ value,
9556
+ min: min2,
9557
+ max: max2,
9558
+ className: cn(
9559
+ "relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
9560
+ className
9561
+ ),
9562
+ ...props,
9563
+ children: [
9564
+ /* @__PURE__ */ jsxRuntime.jsx(
9565
+ SliderPrimitive__namespace.Track,
9566
+ {
9567
+ "data-slot": "slider-track",
9568
+ className: cn(
9569
+ "bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
9570
+ ),
9571
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9572
+ SliderPrimitive__namespace.Range,
9573
+ {
9574
+ "data-slot": "slider-range",
9575
+ className: cn(
9576
+ "bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
9577
+ )
9578
+ }
9579
+ )
9580
+ }
9581
+ ),
9582
+ Array.from({ length: _values.length }, (_, index2) => /* @__PURE__ */ jsxRuntime.jsx(
9583
+ SliderPrimitive__namespace.Thumb,
9584
+ {
9585
+ "data-slot": "slider-thumb",
9586
+ className: "border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
9587
+ },
9588
+ index2
9589
+ ))
9590
+ ]
9591
+ }
9592
+ );
9593
+ }
9594
+ var toggleVariants = cva(
9595
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
9596
+ {
9597
+ variants: {
9598
+ variant: {
9599
+ default: "bg-transparent",
9600
+ outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
9601
+ },
9602
+ size: {
9603
+ default: "h-9 px-2 min-w-9",
9604
+ sm: "h-8 px-1.5 min-w-8",
9605
+ lg: "h-10 px-2.5 min-w-10"
9606
+ }
9607
+ },
9608
+ defaultVariants: {
9609
+ variant: "default",
9610
+ size: "default"
9611
+ }
9612
+ }
9613
+ );
9614
+ function Toggle({
9615
+ className,
9616
+ variant,
9617
+ size: size4,
9618
+ ...props
9619
+ }) {
9620
+ return /* @__PURE__ */ jsxRuntime.jsx(
9621
+ TogglePrimitive__namespace.Root,
9622
+ {
9623
+ "data-slot": "toggle",
9624
+ className: cn(toggleVariants({ variant, size: size4, className })),
9625
+ ...props
9626
+ }
9627
+ );
9628
+ }
9629
+ function AvatarEditor({
9630
+ value,
9631
+ onChange,
9632
+ size: size4 = 280,
9633
+ showGrid: initialShowGrid = false,
9634
+ outputSize = 256,
9635
+ outputFormat = "png",
9636
+ outputQuality = 0.92,
9637
+ className,
9638
+ controlSize = "default",
9639
+ defaultImage,
9640
+ initials: _initials
9641
+ }) {
9642
+ const canvasRef = React32.useRef(null);
9643
+ const fileInputRef = React32.useRef(null);
9644
+ const containerRef = React32.useRef(null);
9645
+ const imageSource = value ?? defaultImage;
9646
+ const [image, setImage] = React32.useState(null);
9647
+ const [imageLoaded, setImageLoaded] = React32.useState(false);
9648
+ const [zoom, setZoom] = React32.useState(1);
9649
+ const [rotation, setRotation] = React32.useState(0);
9650
+ const [position, setPosition] = React32.useState({ x: 0, y: 0 });
9651
+ const [isDragging, setIsDragging] = React32.useState(false);
9652
+ const [dragStart, setDragStart] = React32.useState({ x: 0, y: 0 });
9653
+ const [showGrid, setShowGrid] = React32.useState(initialShowGrid);
9654
+ React32.useEffect(() => {
9655
+ if (imageSource && !imageSource.startsWith("data:")) {
9656
+ const img = new Image();
9657
+ img.crossOrigin = "anonymous";
9658
+ img.onload = () => {
9659
+ setImage(img);
9660
+ setImageLoaded(true);
9661
+ setZoom(1);
9662
+ setRotation(0);
9663
+ setPosition({ x: 0, y: 0 });
9664
+ };
9665
+ img.src = imageSource;
9666
+ }
9667
+ }, [imageSource]);
9668
+ const generateOutput = React32.useCallback(() => {
9669
+ if (!image) return null;
9670
+ const outputCanvas = document.createElement("canvas");
9671
+ outputCanvas.width = outputSize;
9672
+ outputCanvas.height = outputSize;
9673
+ const ctx = outputCanvas.getContext("2d");
9674
+ if (!ctx) return null;
9675
+ ctx.imageSmoothingEnabled = true;
9676
+ ctx.imageSmoothingQuality = "high";
9677
+ if (outputFormat === "jpeg") {
9678
+ ctx.fillStyle = "#ffffff";
9679
+ ctx.fillRect(0, 0, outputSize, outputSize);
9680
+ }
9681
+ ctx.save();
9682
+ ctx.translate(outputSize / 2, outputSize / 2);
9683
+ ctx.rotate(rotation * Math.PI / 180);
9684
+ const scale = zoom;
9685
+ const imgAspect = image.width / image.height;
9686
+ let drawWidth, drawHeight;
9687
+ if (imgAspect > 1) {
9688
+ drawHeight = outputSize * scale;
9689
+ drawWidth = drawHeight * imgAspect;
9690
+ } else {
9691
+ drawWidth = outputSize * scale;
9692
+ drawHeight = drawWidth / imgAspect;
9693
+ }
9694
+ const positionScale = outputSize / size4;
9695
+ const scaledPosX = position.x * positionScale;
9696
+ const scaledPosY = position.y * positionScale;
9697
+ ctx.drawImage(
9698
+ image,
9699
+ -drawWidth / 2 + scaledPosX,
9700
+ -drawHeight / 2 + scaledPosY,
9701
+ drawWidth,
9702
+ drawHeight
9703
+ );
9704
+ ctx.restore();
9705
+ const mimeType = `image/${outputFormat}`;
9706
+ return outputCanvas.toDataURL(mimeType, outputQuality);
9707
+ }, [
9708
+ image,
9709
+ outputSize,
9710
+ outputFormat,
9711
+ outputQuality,
9712
+ zoom,
9713
+ rotation,
9714
+ position,
9715
+ size4
9716
+ ]);
9717
+ React32.useEffect(() => {
9718
+ if (!canvasRef.current || !image || !imageLoaded) return;
9719
+ const canvas = canvasRef.current;
9720
+ const ctx = canvas.getContext("2d");
9721
+ if (!ctx) return;
9722
+ const displaySize = size4;
9723
+ canvas.width = displaySize;
9724
+ canvas.height = displaySize;
9725
+ ctx.clearRect(0, 0, displaySize, displaySize);
9726
+ ctx.fillStyle = "#1a1a2e";
9727
+ ctx.fillRect(0, 0, displaySize, displaySize);
9728
+ ctx.save();
9729
+ ctx.translate(displaySize / 2, displaySize / 2);
9730
+ ctx.rotate(rotation * Math.PI / 180);
9731
+ const scale = zoom;
9732
+ const imgAspect = image.width / image.height;
9733
+ let drawWidth, drawHeight;
9734
+ if (imgAspect > 1) {
9735
+ drawHeight = displaySize * scale;
9736
+ drawWidth = drawHeight * imgAspect;
9737
+ } else {
9738
+ drawWidth = displaySize * scale;
9739
+ drawHeight = drawWidth / imgAspect;
9740
+ }
9741
+ ctx.drawImage(
9742
+ image,
9743
+ -drawWidth / 2 + position.x,
9744
+ -drawHeight / 2 + position.y,
9745
+ drawWidth,
9746
+ drawHeight
9747
+ );
9748
+ ctx.restore();
9749
+ ctx.globalCompositeOperation = "destination-in";
9750
+ ctx.beginPath();
9751
+ ctx.arc(
9752
+ displaySize / 2,
9753
+ displaySize / 2,
9754
+ displaySize / 2 - 4,
9755
+ 0,
9756
+ Math.PI * 2
9757
+ );
9758
+ ctx.fill();
9759
+ ctx.globalCompositeOperation = "source-over";
9760
+ ctx.strokeStyle = "hsl(var(--primary))";
9761
+ ctx.lineWidth = 3;
9762
+ ctx.beginPath();
9763
+ ctx.arc(
9764
+ displaySize / 2,
9765
+ displaySize / 2,
9766
+ displaySize / 2 - 2,
9767
+ 0,
9768
+ Math.PI * 2
9769
+ );
9770
+ ctx.stroke();
9771
+ const dataUrl = generateOutput();
9772
+ if (dataUrl) {
9773
+ onChange?.(dataUrl);
9774
+ }
9775
+ }, [
9776
+ image,
9777
+ imageLoaded,
9778
+ zoom,
9779
+ rotation,
9780
+ position,
9781
+ size4,
9782
+ generateOutput,
9783
+ onChange
9784
+ ]);
9785
+ const resetTransforms = React32.useCallback(() => {
9786
+ setZoom(1);
9787
+ setRotation(0);
9788
+ setPosition({ x: 0, y: 0 });
9789
+ }, []);
9790
+ const handleFileSelect = React32.useCallback(
9791
+ (e) => {
9792
+ const file = e.target.files?.[0];
9793
+ if (!file) return;
9794
+ const reader = new FileReader();
9795
+ reader.onload = (event) => {
9796
+ const img = new Image();
9797
+ img.crossOrigin = "anonymous";
9798
+ img.onload = () => {
9799
+ setImage(img);
9800
+ setImageLoaded(true);
9801
+ resetTransforms();
9802
+ };
9803
+ img.src = event.target?.result;
9804
+ };
9805
+ reader.readAsDataURL(file);
9806
+ },
9807
+ [resetTransforms]
9808
+ );
9809
+ const handleMouseDown = React32.useCallback(
9810
+ (e) => {
9811
+ if (!imageLoaded) return;
9812
+ setIsDragging(true);
9813
+ setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });
9814
+ },
9815
+ [imageLoaded, position]
9816
+ );
9817
+ const handleMouseMove = React32.useCallback(
9818
+ (e) => {
9819
+ if (!isDragging) return;
9820
+ setPosition({
9821
+ x: e.clientX - dragStart.x,
9822
+ y: e.clientY - dragStart.y
9823
+ });
9824
+ },
9825
+ [isDragging, dragStart]
9826
+ );
9827
+ const handleMouseUp = React32.useCallback(() => {
9828
+ setIsDragging(false);
9829
+ }, []);
9830
+ const handleTouchStart = React32.useCallback(
9831
+ (e) => {
9832
+ if (!imageLoaded) return;
9833
+ const touch = e.touches[0];
9834
+ setIsDragging(true);
9835
+ setDragStart({
9836
+ x: touch.clientX - position.x,
9837
+ y: touch.clientY - position.y
9838
+ });
9839
+ },
9840
+ [imageLoaded, position]
9841
+ );
9842
+ const handleTouchMove = React32.useCallback(
9843
+ (e) => {
9844
+ if (!isDragging) return;
9845
+ const touch = e.touches[0];
9846
+ setPosition({
9847
+ x: touch.clientX - dragStart.x,
9848
+ y: touch.clientY - dragStart.y
9849
+ });
9850
+ },
9851
+ [isDragging, dragStart]
9852
+ );
9853
+ const handleDiscard = React32.useCallback(() => {
9854
+ setImage(null);
9855
+ setImageLoaded(false);
9856
+ resetTransforms();
9857
+ if (fileInputRef.current) {
9858
+ fileInputRef.current.value = "";
9859
+ }
9860
+ onChange?.(null);
9861
+ }, [resetTransforms, onChange]);
9862
+ const handleZoomIn = () => setZoom((z) => Math.min(z + 0.1, 3));
9863
+ const handleZoomOut = () => setZoom((z) => Math.max(z - 0.1, 0.5));
9864
+ const handleRotateLeft = () => setRotation((r2) => r2 - 15);
9865
+ const handleRotateRight = () => setRotation((r2) => r2 + 15);
9866
+ const isLarge = controlSize === "large";
9867
+ const buttonSize = isLarge ? "h-12 w-12" : "h-8 w-8";
9868
+ const iconSize = isLarge ? "w-6 h-6" : "w-4 h-4";
9869
+ const smallIconSize = isLarge ? "w-5 h-5" : "w-3 h-3";
9870
+ const textSize = isLarge ? "text-sm" : "text-xs";
9871
+ const uploadIconSize = isLarge ? "w-12 h-12" : "w-8 h-8";
9872
+ const uploadContainerSize = isLarge ? "w-24 h-24" : "w-16 h-16";
9873
+ const gapSize = isLarge ? "gap-6" : "gap-4";
9874
+ const controlGap = isLarge ? "gap-3" : "gap-2";
9875
+ const sliderHeight = isLarge ? "[&_[role=slider]]:h-6 [&_[role=slider]]:w-6" : "";
9876
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9877
+ "div",
9878
+ {
9879
+ className: cn("flex flex-col", gapSize, className),
9880
+ style: { width: size4 },
9881
+ children: [
9882
+ /* @__PURE__ */ jsxRuntime.jsxs(
9883
+ "div",
9884
+ {
9885
+ ref: containerRef,
9886
+ className: "relative bg-muted rounded-2xl overflow-hidden",
9887
+ style: { width: size4, height: size4 },
9888
+ children: [
9889
+ !imageLoaded && /* @__PURE__ */ jsxRuntime.jsxs(
9890
+ "button",
9891
+ {
9892
+ onClick: () => fileInputRef.current?.click(),
9893
+ className: cn(
9894
+ "absolute inset-0 z-10 flex flex-col items-center justify-center text-muted-foreground hover:text-foreground hover:bg-muted/80 transition-colors cursor-pointer",
9895
+ isLarge ? "gap-4" : "gap-3"
9896
+ ),
9897
+ "aria-label": "Upload image",
9898
+ type: "button",
9899
+ children: [
9900
+ /* @__PURE__ */ jsxRuntime.jsx(
9901
+ "div",
9902
+ {
9903
+ className: cn(
9904
+ "rounded-full bg-primary/10 flex items-center justify-center",
9905
+ uploadContainerSize
9906
+ ),
9907
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { className: cn("text-primary", uploadIconSize) })
9908
+ }
9909
+ ),
9910
+ /* @__PURE__ */ jsxRuntime.jsx(
9911
+ "span",
9912
+ {
9913
+ className: cn("font-medium", isLarge ? "text-base" : "text-sm"),
9914
+ children: "Click to upload"
9915
+ }
9916
+ ),
9917
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-muted-foreground", textSize), children: "PNG, JPG up to 10MB" })
9918
+ ]
9919
+ }
9920
+ ),
9921
+ /* @__PURE__ */ jsxRuntime.jsx(
9922
+ "canvas",
9923
+ {
9924
+ ref: canvasRef,
9925
+ className: cn(
9926
+ "absolute inset-0",
9927
+ imageLoaded ? "cursor-move" : "pointer-events-none opacity-0"
9928
+ ),
9929
+ style: { width: size4, height: size4 },
9930
+ onMouseDown: handleMouseDown,
9931
+ onMouseMove: handleMouseMove,
9932
+ onMouseUp: handleMouseUp,
9933
+ onMouseLeave: handleMouseUp,
9934
+ onTouchStart: handleTouchStart,
9935
+ onTouchMove: handleTouchMove,
9936
+ onTouchEnd: handleMouseUp
9937
+ }
9938
+ ),
9939
+ showGrid && imageLoaded && /* @__PURE__ */ jsxRuntime.jsx(
9940
+ "div",
9941
+ {
9942
+ className: "absolute inset-0 pointer-events-none",
9943
+ style: { width: size4, height: size4 },
9944
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: size4, height: size4, className: "opacity-30", children: [
9945
+ /* @__PURE__ */ jsxRuntime.jsx(
9946
+ "line",
9947
+ {
9948
+ x1: size4 / 3,
9949
+ y1: 0,
9950
+ x2: size4 / 3,
9951
+ y2: size4,
9952
+ stroke: "white",
9953
+ strokeWidth: "1"
9954
+ }
9955
+ ),
9956
+ /* @__PURE__ */ jsxRuntime.jsx(
9957
+ "line",
9958
+ {
9959
+ x1: size4 * 2 / 3,
9960
+ y1: 0,
9961
+ x2: size4 * 2 / 3,
9962
+ y2: size4,
9963
+ stroke: "white",
9964
+ strokeWidth: "1"
9965
+ }
9966
+ ),
9967
+ /* @__PURE__ */ jsxRuntime.jsx(
9968
+ "line",
9969
+ {
9970
+ x1: 0,
9971
+ y1: size4 / 3,
9972
+ x2: size4,
9973
+ y2: size4 / 3,
9974
+ stroke: "white",
9975
+ strokeWidth: "1"
9976
+ }
9977
+ ),
9978
+ /* @__PURE__ */ jsxRuntime.jsx(
9979
+ "line",
9980
+ {
9981
+ x1: 0,
9982
+ y1: size4 * 2 / 3,
9983
+ x2: size4,
9984
+ y2: size4 * 2 / 3,
9985
+ stroke: "white",
9986
+ strokeWidth: "1"
9987
+ }
9988
+ ),
9989
+ /* @__PURE__ */ jsxRuntime.jsx(
9990
+ "line",
9991
+ {
9992
+ x1: size4 / 2 - 10,
9993
+ y1: size4 / 2,
9994
+ x2: size4 / 2 + 10,
9995
+ y2: size4 / 2,
9996
+ stroke: "white",
9997
+ strokeWidth: "1"
9998
+ }
9999
+ ),
10000
+ /* @__PURE__ */ jsxRuntime.jsx(
10001
+ "line",
10002
+ {
10003
+ x1: size4 / 2,
10004
+ y1: size4 / 2 - 10,
10005
+ x2: size4 / 2,
10006
+ y2: size4 / 2 + 10,
10007
+ stroke: "white",
10008
+ strokeWidth: "1"
10009
+ }
10010
+ )
10011
+ ] })
10012
+ }
10013
+ ),
10014
+ imageLoaded && isDragging && /* @__PURE__ */ jsxRuntime.jsxs(
10015
+ "div",
10016
+ {
10017
+ className: cn(
10018
+ "absolute top-2 left-1/2 -translate-x-1/2 bg-black/60 rounded text-white flex items-center",
10019
+ isLarge ? "px-3 py-2 text-sm gap-2" : "px-2 py-1 text-xs gap-1"
10020
+ ),
10021
+ children: [
10022
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Move, { className: smallIconSize }),
10023
+ "Dragging"
10024
+ ]
10025
+ }
10026
+ )
10027
+ ]
10028
+ }
10029
+ ),
10030
+ imageLoaded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4", isLarge && "space-y-5"), children: [
10031
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center", controlGap), children: [
10032
+ /* @__PURE__ */ jsxRuntime.jsx(
10033
+ Button,
10034
+ {
10035
+ variant: "ghost",
10036
+ size: "icon",
10037
+ className: cn(buttonSize, "shrink-0"),
10038
+ onClick: handleZoomOut,
10039
+ "aria-label": "Zoom out",
10040
+ type: "button",
10041
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { className: iconSize })
10042
+ }
10043
+ ),
10044
+ /* @__PURE__ */ jsxRuntime.jsx(
10045
+ Slider,
10046
+ {
10047
+ value: [zoom],
10048
+ onValueChange: ([v]) => setZoom(v),
10049
+ min: 0.5,
10050
+ max: 3,
10051
+ step: 0.01,
10052
+ className: cn("flex-1", sliderHeight),
10053
+ "aria-label": "Zoom level"
10054
+ }
10055
+ ),
10056
+ /* @__PURE__ */ jsxRuntime.jsx(
10057
+ Button,
10058
+ {
10059
+ variant: "ghost",
10060
+ size: "icon",
10061
+ className: cn(buttonSize, "shrink-0"),
10062
+ onClick: handleZoomIn,
10063
+ "aria-label": "Zoom in",
10064
+ type: "button",
10065
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { className: iconSize })
10066
+ }
10067
+ )
10068
+ ] }),
10069
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center justify-between", controlGap), children: [
10070
+ /* @__PURE__ */ jsxRuntime.jsxs(
10071
+ "div",
10072
+ {
10073
+ className: cn("flex items-center", isLarge ? "gap-2" : "gap-1"),
10074
+ children: [
10075
+ /* @__PURE__ */ jsxRuntime.jsx(
10076
+ Button,
10077
+ {
10078
+ variant: "ghost",
10079
+ size: "icon",
10080
+ className: buttonSize,
10081
+ onClick: handleRotateLeft,
10082
+ "aria-label": "Rotate left 15 degrees",
10083
+ type: "button",
10084
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: iconSize })
10085
+ }
10086
+ ),
10087
+ /* @__PURE__ */ jsxRuntime.jsxs(
10088
+ "span",
10089
+ {
10090
+ className: cn(
10091
+ "text-muted-foreground text-center tabular-nums",
10092
+ textSize,
10093
+ isLarge ? "w-16" : "w-12"
10094
+ ),
10095
+ children: [
10096
+ rotation,
10097
+ "\xB0"
10098
+ ]
10099
+ }
10100
+ ),
10101
+ /* @__PURE__ */ jsxRuntime.jsx(
10102
+ Button,
10103
+ {
10104
+ variant: "ghost",
10105
+ size: "icon",
10106
+ className: buttonSize,
10107
+ onClick: handleRotateRight,
10108
+ "aria-label": "Rotate right 15 degrees",
10109
+ type: "button",
10110
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCw, { className: iconSize })
10111
+ }
10112
+ )
10113
+ ]
10114
+ }
10115
+ ),
10116
+ /* @__PURE__ */ jsxRuntime.jsxs(
10117
+ "div",
10118
+ {
10119
+ className: cn("flex items-center", isLarge ? "gap-2" : "gap-1"),
10120
+ children: [
10121
+ /* @__PURE__ */ jsxRuntime.jsx(
10122
+ Toggle,
10123
+ {
10124
+ pressed: showGrid,
10125
+ onPressedChange: setShowGrid,
10126
+ size: "sm",
10127
+ className: cn(buttonSize, "p-0"),
10128
+ "aria-label": "Toggle grid overlay",
10129
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: iconSize })
10130
+ }
10131
+ ),
10132
+ /* @__PURE__ */ jsxRuntime.jsx(
10133
+ Button,
10134
+ {
10135
+ variant: "ghost",
10136
+ size: "icon",
10137
+ className: buttonSize,
10138
+ onClick: resetTransforms,
10139
+ "aria-label": "Reset all transforms",
10140
+ type: "button",
10141
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: iconSize })
10142
+ }
10143
+ ),
10144
+ /* @__PURE__ */ jsxRuntime.jsx(
10145
+ Button,
10146
+ {
10147
+ variant: "ghost",
10148
+ size: "icon",
10149
+ className: buttonSize,
10150
+ onClick: () => fileInputRef.current?.click(),
10151
+ "aria-label": "Upload new image",
10152
+ type: "button",
10153
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { className: iconSize })
10154
+ }
10155
+ ),
10156
+ /* @__PURE__ */ jsxRuntime.jsx(
10157
+ Button,
10158
+ {
10159
+ variant: "ghost",
10160
+ size: "icon",
10161
+ className: cn(
10162
+ buttonSize,
10163
+ "text-destructive hover:text-destructive hover:bg-destructive/10"
10164
+ ),
10165
+ onClick: handleDiscard,
10166
+ "aria-label": "Discard image",
10167
+ type: "button",
10168
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: iconSize })
10169
+ }
10170
+ )
10171
+ ]
10172
+ }
10173
+ )
10174
+ ] })
10175
+ ] }),
10176
+ /* @__PURE__ */ jsxRuntime.jsx(
10177
+ "input",
10178
+ {
10179
+ ref: fileInputRef,
10180
+ type: "file",
10181
+ accept: "image/*",
10182
+ onChange: handleFileSelect,
10183
+ className: "hidden",
10184
+ "aria-hidden": "true"
10185
+ }
10186
+ )
10187
+ ]
10188
+ }
10189
+ );
10190
+ }
10191
+ function Dialog({
10192
+ ...props
10193
+ }) {
10194
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
10195
+ }
10196
+ function DialogTrigger({
10197
+ ...props
10198
+ }) {
10199
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Trigger, { "data-slot": "dialog-trigger", ...props });
10200
+ }
10201
+ function DialogPortal({
10202
+ ...props
10203
+ }) {
10204
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
10205
+ }
10206
+ function DialogClose({
10207
+ ...props
10208
+ }) {
10209
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { "data-slot": "dialog-close", ...props });
10210
+ }
10211
+ function DialogOverlay({
10212
+ className,
10213
+ ...props
10214
+ }) {
10215
+ return /* @__PURE__ */ jsxRuntime.jsx(
10216
+ DialogPrimitive__namespace.Overlay,
10217
+ {
10218
+ "data-slot": "dialog-overlay",
10219
+ className: cn(
10220
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
10221
+ className
10222
+ ),
10223
+ ...props
10224
+ }
10225
+ );
10226
+ }
10227
+ function DialogContent({
10228
+ className,
10229
+ children,
10230
+ showCloseButton = true,
10231
+ ...props
10232
+ }) {
10233
+ return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
10234
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
10235
+ /* @__PURE__ */ jsxRuntime.jsxs(
10236
+ DialogPrimitive__namespace.Content,
10237
+ {
10238
+ "data-slot": "dialog-content",
10239
+ className: cn(
10240
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
10241
+ className
10242
+ ),
10243
+ ...props,
10244
+ children: [
10245
+ children,
10246
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsxs(
10247
+ DialogPrimitive__namespace.Close,
10248
+ {
10249
+ "data-slot": "dialog-close",
10250
+ className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
10251
+ children: [
10252
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
10253
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
10254
+ ]
10255
+ }
10256
+ )
10257
+ ]
10258
+ }
10259
+ )
10260
+ ] });
10261
+ }
10262
+ function DialogHeader({ className, ...props }) {
10263
+ return /* @__PURE__ */ jsxRuntime.jsx(
10264
+ "div",
10265
+ {
10266
+ "data-slot": "dialog-header",
10267
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
10268
+ ...props
10269
+ }
10270
+ );
10271
+ }
10272
+ function DialogFooter({ className, ...props }) {
10273
+ return /* @__PURE__ */ jsxRuntime.jsx(
10274
+ "div",
10275
+ {
10276
+ "data-slot": "dialog-footer",
10277
+ className: cn(
10278
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
10279
+ className
10280
+ ),
10281
+ ...props
10282
+ }
10283
+ );
10284
+ }
10285
+ function DialogTitle({
10286
+ className,
10287
+ ...props
10288
+ }) {
10289
+ return /* @__PURE__ */ jsxRuntime.jsx(
10290
+ DialogPrimitive__namespace.Title,
10291
+ {
10292
+ "data-slot": "dialog-title",
10293
+ className: cn("text-lg leading-none font-semibold", className),
10294
+ ...props
10295
+ }
10296
+ );
10297
+ }
10298
+ function DialogDescription({
10299
+ className,
10300
+ ...props
10301
+ }) {
10302
+ return /* @__PURE__ */ jsxRuntime.jsx(
10303
+ DialogPrimitive__namespace.Description,
10304
+ {
10305
+ "data-slot": "dialog-description",
10306
+ className: cn("text-muted-foreground text-sm", className),
10307
+ ...props
10308
+ }
10309
+ );
10310
+ }
10311
+ function Drawer({
10312
+ ...props
10313
+ }) {
10314
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Root, { "data-slot": "drawer", ...props });
10315
+ }
10316
+ function DrawerTrigger({
10317
+ ...props
10318
+ }) {
10319
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Trigger, { "data-slot": "drawer-trigger", ...props });
10320
+ }
10321
+ function DrawerPortal({
10322
+ ...props
10323
+ }) {
10324
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Portal, { "data-slot": "drawer-portal", ...props });
10325
+ }
10326
+ function DrawerClose({
10327
+ ...props
10328
+ }) {
10329
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Close, { "data-slot": "drawer-close", ...props });
10330
+ }
10331
+ function DrawerOverlay({
10332
+ className,
10333
+ ...props
10334
+ }) {
10335
+ return /* @__PURE__ */ jsxRuntime.jsx(
10336
+ vaul.Drawer.Overlay,
10337
+ {
10338
+ "data-slot": "drawer-overlay",
10339
+ className: cn(
10340
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
10341
+ className
10342
+ ),
10343
+ ...props
10344
+ }
10345
+ );
10346
+ }
10347
+ function DrawerContent({
10348
+ className,
10349
+ children,
10350
+ ...props
10351
+ }) {
10352
+ return /* @__PURE__ */ jsxRuntime.jsxs(DrawerPortal, { "data-slot": "drawer-portal", children: [
10353
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerOverlay, {}),
10354
+ /* @__PURE__ */ jsxRuntime.jsxs(
10355
+ vaul.Drawer.Content,
10356
+ {
10357
+ "data-slot": "drawer-content",
10358
+ className: cn(
10359
+ "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
10360
+ "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
10361
+ "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
10362
+ "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
10363
+ "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
10364
+ className
10365
+ ),
10366
+ ...props,
10367
+ children: [
10368
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
10369
+ children
10370
+ ]
10371
+ }
10372
+ )
10373
+ ] });
10374
+ }
10375
+ function DrawerHeader({ className, ...props }) {
10376
+ return /* @__PURE__ */ jsxRuntime.jsx(
10377
+ "div",
10378
+ {
10379
+ "data-slot": "drawer-header",
10380
+ className: cn(
10381
+ "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left",
10382
+ className
10383
+ ),
10384
+ ...props
10385
+ }
10386
+ );
10387
+ }
10388
+ function DrawerFooter({ className, ...props }) {
10389
+ return /* @__PURE__ */ jsxRuntime.jsx(
10390
+ "div",
10391
+ {
10392
+ "data-slot": "drawer-footer",
10393
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
10394
+ ...props
10395
+ }
10396
+ );
10397
+ }
10398
+ function DrawerTitle({
10399
+ className,
10400
+ ...props
10401
+ }) {
10402
+ return /* @__PURE__ */ jsxRuntime.jsx(
10403
+ vaul.Drawer.Title,
10404
+ {
10405
+ "data-slot": "drawer-title",
10406
+ className: cn("text-foreground font-semibold", className),
10407
+ ...props
10408
+ }
10409
+ );
10410
+ }
10411
+ function DrawerDescription({
10412
+ className,
10413
+ ...props
10414
+ }) {
10415
+ return /* @__PURE__ */ jsxRuntime.jsx(
10416
+ vaul.Drawer.Description,
10417
+ {
10418
+ "data-slot": "drawer-description",
10419
+ className: cn("text-muted-foreground text-sm", className),
10420
+ ...props
10421
+ }
10422
+ );
10423
+ }
10424
+ function useMediaQuery(query) {
10425
+ const [matches, setMatches] = React32.useState(false);
10426
+ React32.useEffect(() => {
10427
+ const media = window.matchMedia(query);
10428
+ if (media.matches !== matches) {
10429
+ setMatches(media.matches);
10430
+ }
10431
+ const listener = () => setMatches(media.matches);
10432
+ media.addEventListener("change", listener);
10433
+ return () => media.removeEventListener("change", listener);
10434
+ }, [matches, query]);
10435
+ return matches;
10436
+ }
10437
+ function AvatarEditorDialog({
10438
+ value,
10439
+ onChange,
10440
+ onSave,
10441
+ displaySize = 120,
10442
+ editorSize = 280,
10443
+ outputSize = 256,
10444
+ placeholder: _placeholder = "Add Photo",
10445
+ editLabel = "Edit avatar",
10446
+ dialogTitle = "Edit Avatar",
10447
+ acceptText = "Accept",
10448
+ cancelText = "Cancel",
10449
+ successMessage = "Avatar saved successfully!",
10450
+ errorMessage = "Failed to save avatar. Please try again.",
10451
+ className
10452
+ }) {
10453
+ const [isOpen, setIsOpen] = React32.useState(false);
10454
+ const [editedValue, setEditedValue] = React32.useState(value ?? null);
10455
+ const [isSaving, setIsSaving] = React32.useState(false);
10456
+ const [feedback, setFeedback] = React32.useState(null);
10457
+ const isMobile = useMediaQuery("(max-width: 640px)");
10458
+ const handleOpenChange = React32.useCallback(
10459
+ (open) => {
10460
+ if (open) {
10461
+ setEditedValue(value ?? null);
10462
+ setFeedback(null);
10463
+ }
10464
+ setIsOpen(open);
10465
+ },
10466
+ [value]
10467
+ );
10468
+ const handleAccept = React32.useCallback(async () => {
10469
+ if (!editedValue) return;
10470
+ setIsSaving(true);
10471
+ setFeedback(null);
10472
+ try {
10473
+ if (onSave) {
10474
+ const result = await onSave(editedValue);
10475
+ if (result) {
10476
+ setFeedback({ type: "success", message: successMessage });
10477
+ setTimeout(() => {
10478
+ setIsOpen(false);
10479
+ setFeedback(null);
10480
+ }, 1500);
10481
+ } else {
10482
+ setFeedback({ type: "error", message: errorMessage });
10483
+ }
10484
+ } else {
10485
+ onChange?.(editedValue);
10486
+ setFeedback({ type: "success", message: successMessage });
10487
+ setTimeout(() => {
10488
+ setIsOpen(false);
10489
+ setFeedback(null);
10490
+ }, 1500);
10491
+ }
10492
+ } catch {
10493
+ setFeedback({ type: "error", message: errorMessage });
10494
+ } finally {
10495
+ setIsSaving(false);
10496
+ }
10497
+ }, [editedValue, onChange, onSave, successMessage, errorMessage]);
10498
+ const AvatarDisplay = /* @__PURE__ */ jsxRuntime.jsxs(
10499
+ "div",
10500
+ {
10501
+ className: cn("relative group", className),
10502
+ style: { width: displaySize, height: displaySize },
10503
+ children: [
10504
+ /* @__PURE__ */ jsxRuntime.jsx(
10505
+ "div",
10506
+ {
10507
+ className: "w-full h-full rounded-full overflow-hidden bg-muted border-2 border-border flex items-center justify-center",
10508
+ style: { width: displaySize, height: displaySize },
10509
+ children: value ? /* @__PURE__ */ jsxRuntime.jsx(
10510
+ "img",
10511
+ {
10512
+ src: value || "/placeholder.svg",
10513
+ alt: "Avatar",
10514
+ className: "w-full h-full object-cover"
10515
+ }
10516
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-10 h-10" }) })
10517
+ }
10518
+ ),
10519
+ /* @__PURE__ */ jsxRuntime.jsx(
10520
+ "button",
10521
+ {
10522
+ onClick: () => handleOpenChange(true),
10523
+ className: "absolute bottom-0 right-0 w-8 h-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center shadow-lg hover:bg-primary/90 transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2",
10524
+ "aria-label": editLabel,
10525
+ type: "button",
10526
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "w-4 h-4" })
10527
+ }
10528
+ )
10529
+ ]
10530
+ }
10531
+ );
10532
+ const mobileEditorSize = isMobile ? Math.min(editorSize + 40, window.innerWidth - 48) : editorSize;
10533
+ const EditorContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
10534
+ /* @__PURE__ */ jsxRuntime.jsx(
10535
+ AvatarEditor,
10536
+ {
10537
+ value: editedValue,
10538
+ onChange: setEditedValue,
10539
+ size: mobileEditorSize,
10540
+ outputSize,
10541
+ controlSize: isMobile ? "large" : "default"
10542
+ }
10543
+ ),
10544
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: feedback && /* @__PURE__ */ jsxRuntime.jsxs(
10545
+ react.motion.div,
10546
+ {
10547
+ initial: { opacity: 0, y: -10 },
10548
+ animate: { opacity: 1, y: 0 },
10549
+ exit: { opacity: 0, y: -10 },
10550
+ className: cn(
10551
+ "flex items-center gap-2 rounded-lg font-medium",
10552
+ isMobile ? "px-5 py-3 text-base" : "px-4 py-2 text-sm",
10553
+ feedback.type === "success" ? "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400" : "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400"
10554
+ ),
10555
+ children: [
10556
+ feedback.type === "success" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: isMobile ? "w-5 h-5" : "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: isMobile ? "w-5 h-5" : "w-4 h-4" }),
10557
+ feedback.message
10558
+ ]
10559
+ }
10560
+ ) })
10561
+ ] });
10562
+ const FooterButtons = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10563
+ isMobile ? /* @__PURE__ */ jsxRuntime.jsx(DrawerClose, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
10564
+ Button,
10565
+ {
10566
+ variant: "outline",
10567
+ disabled: isSaving,
10568
+ size: "lg",
10569
+ className: "flex-1 bg-transparent",
10570
+ children: cancelText
10571
+ }
10572
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", disabled: isSaving, children: cancelText }) }),
10573
+ /* @__PURE__ */ jsxRuntime.jsx(
10574
+ Button,
10575
+ {
10576
+ onClick: handleAccept,
10577
+ disabled: !editedValue || isSaving || feedback?.type === "success",
10578
+ size: isMobile ? "lg" : "default",
10579
+ className: isMobile ? "flex-1" : "",
10580
+ children: isSaving ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10581
+ /* @__PURE__ */ jsxRuntime.jsx(
10582
+ lucideReact.Loader2,
10583
+ {
10584
+ className: cn(
10585
+ "mr-2 animate-spin",
10586
+ isMobile ? "w-5 h-5" : "w-4 h-4"
10587
+ )
10588
+ }
10589
+ ),
10590
+ "Saving..."
10591
+ ] }) : feedback?.type === "success" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10592
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("mr-2", isMobile ? "w-5 h-5" : "w-4 h-4") }),
10593
+ "Saved!"
10594
+ ] }) : acceptText
10595
+ }
10596
+ )
10597
+ ] });
10598
+ if (isMobile) {
10599
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10600
+ AvatarDisplay,
10601
+ /* @__PURE__ */ jsxRuntime.jsx(Drawer, { open: isOpen, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DrawerContent, { className: "max-h-[96vh]", children: [
10602
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerHeader, { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx(DrawerTitle, { className: "text-xl", children: dialogTitle }) }),
10603
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 pb-6 overflow-y-auto", children: EditorContent }),
10604
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerFooter, { className: "flex-row gap-3 px-6 pb-8", children: FooterButtons })
10605
+ ] }) })
10606
+ ] });
10607
+ }
10608
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10609
+ AvatarDisplay,
10610
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isOpen, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-md", children: [
10611
+ /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: dialogTitle }) }),
10612
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: EditorContent }),
10613
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { className: "gap-2 sm:gap-0", children: FooterButtons })
10614
+ ] }) })
10615
+ ] });
10616
+ }
9531
10617
 
10618
+ exports.AvatarEditor = AvatarEditor;
10619
+ exports.AvatarEditorDialog = AvatarEditorDialog;
9532
10620
  exports.Button = Button;
10621
+ exports.Dialog = Dialog;
10622
+ exports.DialogClose = DialogClose;
10623
+ exports.DialogContent = DialogContent;
10624
+ exports.DialogDescription = DialogDescription;
10625
+ exports.DialogFooter = DialogFooter;
10626
+ exports.DialogHeader = DialogHeader;
10627
+ exports.DialogOverlay = DialogOverlay;
10628
+ exports.DialogPortal = DialogPortal;
10629
+ exports.DialogTitle = DialogTitle;
10630
+ exports.DialogTrigger = DialogTrigger;
10631
+ exports.Drawer = Drawer;
10632
+ exports.DrawerClose = DrawerClose;
10633
+ exports.DrawerContent = DrawerContent;
10634
+ exports.DrawerDescription = DrawerDescription;
10635
+ exports.DrawerFooter = DrawerFooter;
10636
+ exports.DrawerHeader = DrawerHeader;
10637
+ exports.DrawerOverlay = DrawerOverlay;
10638
+ exports.DrawerPortal = DrawerPortal;
10639
+ exports.DrawerTitle = DrawerTitle;
10640
+ exports.DrawerTrigger = DrawerTrigger;
9533
10641
  exports.DropdownMenu = DropdownMenu2;
9534
10642
  exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem2;
9535
10643
  exports.DropdownMenuContent = DropdownMenuContent2;
@@ -9546,12 +10654,15 @@ exports.DropdownMenuSubContent = DropdownMenuSubContent2;
9546
10654
  exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger2;
9547
10655
  exports.DropdownMenuTrigger = DropdownMenuTrigger2;
9548
10656
  exports.LanguageSwitcher = LanguageSwitcher;
10657
+ exports.Slider = Slider;
9549
10658
  exports.ThemeSwitcher = ThemeSwitcher;
10659
+ exports.Toggle = Toggle;
9550
10660
  exports.Tooltip = Tooltip2;
9551
10661
  exports.TooltipContent = TooltipContent2;
9552
10662
  exports.TooltipProvider = TooltipProvider2;
9553
10663
  exports.TooltipTrigger = TooltipTrigger2;
9554
10664
  exports.buttonVariants = buttonVariants;
9555
10665
  exports.cn = cn;
10666
+ exports.toggleVariants = toggleVariants;
9556
10667
  //# sourceMappingURL=index.cjs.map
9557
10668
  //# sourceMappingURL=index.cjs.map