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