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

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,12 @@ 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');
13
+ var PopoverPrimitive = require('@radix-ui/react-popover');
14
+ var ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
9
15
 
10
16
  function _interopNamespace(e) {
11
17
  if (e && e.__esModule) return e;
@@ -27,6 +33,11 @@ function _interopNamespace(e) {
27
33
 
28
34
  var React32__namespace = /*#__PURE__*/_interopNamespace(React32);
29
35
  var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
36
+ var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
37
+ var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespace(TogglePrimitive);
38
+ var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
39
+ var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
40
+ var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
30
41
 
31
42
  function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
32
43
  return function handleEvent(event) {
@@ -9528,8 +9539,1553 @@ function LanguageSwitcher({
9528
9539
  }
9529
9540
  );
9530
9541
  }
9542
+ function Slider({
9543
+ className,
9544
+ defaultValue,
9545
+ value,
9546
+ min: min2 = 0,
9547
+ max: max2 = 100,
9548
+ ...props
9549
+ }) {
9550
+ const _values = React32__namespace.useMemo(
9551
+ () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min2, max2],
9552
+ [value, defaultValue, min2, max2]
9553
+ );
9554
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9555
+ SliderPrimitive__namespace.Root,
9556
+ {
9557
+ "data-slot": "slider",
9558
+ defaultValue,
9559
+ value,
9560
+ min: min2,
9561
+ max: max2,
9562
+ className: cn(
9563
+ "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",
9564
+ className
9565
+ ),
9566
+ ...props,
9567
+ children: [
9568
+ /* @__PURE__ */ jsxRuntime.jsx(
9569
+ SliderPrimitive__namespace.Track,
9570
+ {
9571
+ "data-slot": "slider-track",
9572
+ className: cn(
9573
+ "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"
9574
+ ),
9575
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9576
+ SliderPrimitive__namespace.Range,
9577
+ {
9578
+ "data-slot": "slider-range",
9579
+ className: cn(
9580
+ "bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
9581
+ )
9582
+ }
9583
+ )
9584
+ }
9585
+ ),
9586
+ Array.from({ length: _values.length }, (_, index2) => /* @__PURE__ */ jsxRuntime.jsx(
9587
+ SliderPrimitive__namespace.Thumb,
9588
+ {
9589
+ "data-slot": "slider-thumb",
9590
+ 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"
9591
+ },
9592
+ index2
9593
+ ))
9594
+ ]
9595
+ }
9596
+ );
9597
+ }
9598
+ var toggleVariants = cva(
9599
+ "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",
9600
+ {
9601
+ variants: {
9602
+ variant: {
9603
+ default: "bg-transparent",
9604
+ outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
9605
+ },
9606
+ size: {
9607
+ default: "h-9 px-2 min-w-9",
9608
+ sm: "h-8 px-1.5 min-w-8",
9609
+ lg: "h-10 px-2.5 min-w-10"
9610
+ }
9611
+ },
9612
+ defaultVariants: {
9613
+ variant: "default",
9614
+ size: "default"
9615
+ }
9616
+ }
9617
+ );
9618
+ function Toggle({
9619
+ className,
9620
+ variant,
9621
+ size: size4,
9622
+ ...props
9623
+ }) {
9624
+ return /* @__PURE__ */ jsxRuntime.jsx(
9625
+ TogglePrimitive__namespace.Root,
9626
+ {
9627
+ "data-slot": "toggle",
9628
+ className: cn(toggleVariants({ variant, size: size4, className })),
9629
+ ...props
9630
+ }
9631
+ );
9632
+ }
9633
+ function AvatarEditor({
9634
+ value,
9635
+ onChange,
9636
+ size: size4 = 280,
9637
+ showGrid: initialShowGrid = false,
9638
+ outputSize = 256,
9639
+ outputFormat = "png",
9640
+ outputQuality = 0.92,
9641
+ className,
9642
+ controlSize = "default",
9643
+ defaultImage,
9644
+ initials: _initials
9645
+ }) {
9646
+ const canvasRef = React32.useRef(null);
9647
+ const fileInputRef = React32.useRef(null);
9648
+ const containerRef = React32.useRef(null);
9649
+ const imageSource = value ?? defaultImage;
9650
+ const [image, setImage] = React32.useState(null);
9651
+ const [imageLoaded, setImageLoaded] = React32.useState(false);
9652
+ const [zoom, setZoom] = React32.useState(1);
9653
+ const [rotation, setRotation] = React32.useState(0);
9654
+ const [position, setPosition] = React32.useState({ x: 0, y: 0 });
9655
+ const [isDragging, setIsDragging] = React32.useState(false);
9656
+ const [dragStart, setDragStart] = React32.useState({ x: 0, y: 0 });
9657
+ const [showGrid, setShowGrid] = React32.useState(initialShowGrid);
9658
+ React32.useEffect(() => {
9659
+ if (imageSource && !imageSource.startsWith("data:")) {
9660
+ const img = new Image();
9661
+ img.crossOrigin = "anonymous";
9662
+ img.onload = () => {
9663
+ setImage(img);
9664
+ setImageLoaded(true);
9665
+ setZoom(1);
9666
+ setRotation(0);
9667
+ setPosition({ x: 0, y: 0 });
9668
+ };
9669
+ img.src = imageSource;
9670
+ }
9671
+ }, [imageSource]);
9672
+ const generateOutput = React32.useCallback(() => {
9673
+ if (!image) return null;
9674
+ const outputCanvas = document.createElement("canvas");
9675
+ outputCanvas.width = outputSize;
9676
+ outputCanvas.height = outputSize;
9677
+ const ctx = outputCanvas.getContext("2d");
9678
+ if (!ctx) return null;
9679
+ ctx.imageSmoothingEnabled = true;
9680
+ ctx.imageSmoothingQuality = "high";
9681
+ if (outputFormat === "jpeg") {
9682
+ ctx.fillStyle = "#ffffff";
9683
+ ctx.fillRect(0, 0, outputSize, outputSize);
9684
+ }
9685
+ ctx.save();
9686
+ ctx.translate(outputSize / 2, outputSize / 2);
9687
+ ctx.rotate(rotation * Math.PI / 180);
9688
+ const scale = zoom;
9689
+ const imgAspect = image.width / image.height;
9690
+ let drawWidth, drawHeight;
9691
+ if (imgAspect > 1) {
9692
+ drawHeight = outputSize * scale;
9693
+ drawWidth = drawHeight * imgAspect;
9694
+ } else {
9695
+ drawWidth = outputSize * scale;
9696
+ drawHeight = drawWidth / imgAspect;
9697
+ }
9698
+ const positionScale = outputSize / size4;
9699
+ const scaledPosX = position.x * positionScale;
9700
+ const scaledPosY = position.y * positionScale;
9701
+ ctx.drawImage(
9702
+ image,
9703
+ -drawWidth / 2 + scaledPosX,
9704
+ -drawHeight / 2 + scaledPosY,
9705
+ drawWidth,
9706
+ drawHeight
9707
+ );
9708
+ ctx.restore();
9709
+ const mimeType = `image/${outputFormat}`;
9710
+ return outputCanvas.toDataURL(mimeType, outputQuality);
9711
+ }, [
9712
+ image,
9713
+ outputSize,
9714
+ outputFormat,
9715
+ outputQuality,
9716
+ zoom,
9717
+ rotation,
9718
+ position,
9719
+ size4
9720
+ ]);
9721
+ React32.useEffect(() => {
9722
+ if (!canvasRef.current || !image || !imageLoaded) return;
9723
+ const canvas = canvasRef.current;
9724
+ const ctx = canvas.getContext("2d");
9725
+ if (!ctx) return;
9726
+ const displaySize = size4;
9727
+ canvas.width = displaySize;
9728
+ canvas.height = displaySize;
9729
+ ctx.clearRect(0, 0, displaySize, displaySize);
9730
+ ctx.fillStyle = "#1a1a2e";
9731
+ ctx.fillRect(0, 0, displaySize, displaySize);
9732
+ ctx.save();
9733
+ ctx.translate(displaySize / 2, displaySize / 2);
9734
+ ctx.rotate(rotation * Math.PI / 180);
9735
+ const scale = zoom;
9736
+ const imgAspect = image.width / image.height;
9737
+ let drawWidth, drawHeight;
9738
+ if (imgAspect > 1) {
9739
+ drawHeight = displaySize * scale;
9740
+ drawWidth = drawHeight * imgAspect;
9741
+ } else {
9742
+ drawWidth = displaySize * scale;
9743
+ drawHeight = drawWidth / imgAspect;
9744
+ }
9745
+ ctx.drawImage(
9746
+ image,
9747
+ -drawWidth / 2 + position.x,
9748
+ -drawHeight / 2 + position.y,
9749
+ drawWidth,
9750
+ drawHeight
9751
+ );
9752
+ ctx.restore();
9753
+ ctx.globalCompositeOperation = "destination-in";
9754
+ ctx.beginPath();
9755
+ ctx.arc(
9756
+ displaySize / 2,
9757
+ displaySize / 2,
9758
+ displaySize / 2 - 4,
9759
+ 0,
9760
+ Math.PI * 2
9761
+ );
9762
+ ctx.fill();
9763
+ ctx.globalCompositeOperation = "source-over";
9764
+ ctx.strokeStyle = "hsl(var(--primary))";
9765
+ ctx.lineWidth = 3;
9766
+ ctx.beginPath();
9767
+ ctx.arc(
9768
+ displaySize / 2,
9769
+ displaySize / 2,
9770
+ displaySize / 2 - 2,
9771
+ 0,
9772
+ Math.PI * 2
9773
+ );
9774
+ ctx.stroke();
9775
+ const dataUrl = generateOutput();
9776
+ if (dataUrl) {
9777
+ onChange?.(dataUrl);
9778
+ }
9779
+ }, [
9780
+ image,
9781
+ imageLoaded,
9782
+ zoom,
9783
+ rotation,
9784
+ position,
9785
+ size4,
9786
+ generateOutput,
9787
+ onChange
9788
+ ]);
9789
+ const resetTransforms = React32.useCallback(() => {
9790
+ setZoom(1);
9791
+ setRotation(0);
9792
+ setPosition({ x: 0, y: 0 });
9793
+ }, []);
9794
+ const handleFileSelect = React32.useCallback(
9795
+ (e) => {
9796
+ const file = e.target.files?.[0];
9797
+ if (!file) return;
9798
+ const reader = new FileReader();
9799
+ reader.onload = (event) => {
9800
+ const img = new Image();
9801
+ img.crossOrigin = "anonymous";
9802
+ img.onload = () => {
9803
+ setImage(img);
9804
+ setImageLoaded(true);
9805
+ resetTransforms();
9806
+ };
9807
+ img.src = event.target?.result;
9808
+ };
9809
+ reader.readAsDataURL(file);
9810
+ },
9811
+ [resetTransforms]
9812
+ );
9813
+ const handleMouseDown = React32.useCallback(
9814
+ (e) => {
9815
+ if (!imageLoaded) return;
9816
+ setIsDragging(true);
9817
+ setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });
9818
+ },
9819
+ [imageLoaded, position]
9820
+ );
9821
+ const handleMouseMove = React32.useCallback(
9822
+ (e) => {
9823
+ if (!isDragging) return;
9824
+ setPosition({
9825
+ x: e.clientX - dragStart.x,
9826
+ y: e.clientY - dragStart.y
9827
+ });
9828
+ },
9829
+ [isDragging, dragStart]
9830
+ );
9831
+ const handleMouseUp = React32.useCallback(() => {
9832
+ setIsDragging(false);
9833
+ }, []);
9834
+ const handleTouchStart = React32.useCallback(
9835
+ (e) => {
9836
+ if (!imageLoaded) return;
9837
+ const touch = e.touches[0];
9838
+ setIsDragging(true);
9839
+ setDragStart({
9840
+ x: touch.clientX - position.x,
9841
+ y: touch.clientY - position.y
9842
+ });
9843
+ },
9844
+ [imageLoaded, position]
9845
+ );
9846
+ const handleTouchMove = React32.useCallback(
9847
+ (e) => {
9848
+ if (!isDragging) return;
9849
+ const touch = e.touches[0];
9850
+ setPosition({
9851
+ x: touch.clientX - dragStart.x,
9852
+ y: touch.clientY - dragStart.y
9853
+ });
9854
+ },
9855
+ [isDragging, dragStart]
9856
+ );
9857
+ const handleDiscard = React32.useCallback(() => {
9858
+ setImage(null);
9859
+ setImageLoaded(false);
9860
+ resetTransforms();
9861
+ if (fileInputRef.current) {
9862
+ fileInputRef.current.value = "";
9863
+ }
9864
+ onChange?.(null);
9865
+ }, [resetTransforms, onChange]);
9866
+ const handleZoomIn = () => setZoom((z) => Math.min(z + 0.1, 3));
9867
+ const handleZoomOut = () => setZoom((z) => Math.max(z - 0.1, 0.5));
9868
+ const handleRotateLeft = () => setRotation((r2) => r2 - 15);
9869
+ const handleRotateRight = () => setRotation((r2) => r2 + 15);
9870
+ const isLarge = controlSize === "large";
9871
+ const buttonSize = isLarge ? "h-12 w-12" : "h-8 w-8";
9872
+ const iconSize = isLarge ? "w-6 h-6" : "w-4 h-4";
9873
+ const smallIconSize = isLarge ? "w-5 h-5" : "w-3 h-3";
9874
+ const textSize = isLarge ? "text-sm" : "text-xs";
9875
+ const uploadIconSize = isLarge ? "w-12 h-12" : "w-8 h-8";
9876
+ const uploadContainerSize = isLarge ? "w-24 h-24" : "w-16 h-16";
9877
+ const gapSize = isLarge ? "gap-6" : "gap-4";
9878
+ const controlGap = isLarge ? "gap-3" : "gap-2";
9879
+ const sliderHeight = isLarge ? "[&_[role=slider]]:h-6 [&_[role=slider]]:w-6" : "";
9880
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9881
+ "div",
9882
+ {
9883
+ className: cn("flex flex-col", gapSize, className),
9884
+ style: { width: size4 },
9885
+ children: [
9886
+ /* @__PURE__ */ jsxRuntime.jsxs(
9887
+ "div",
9888
+ {
9889
+ ref: containerRef,
9890
+ className: "relative bg-muted rounded-2xl overflow-hidden",
9891
+ style: { width: size4, height: size4 },
9892
+ children: [
9893
+ !imageLoaded && /* @__PURE__ */ jsxRuntime.jsxs(
9894
+ "button",
9895
+ {
9896
+ onClick: () => fileInputRef.current?.click(),
9897
+ className: cn(
9898
+ "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",
9899
+ isLarge ? "gap-4" : "gap-3"
9900
+ ),
9901
+ "aria-label": "Upload image",
9902
+ type: "button",
9903
+ children: [
9904
+ /* @__PURE__ */ jsxRuntime.jsx(
9905
+ "div",
9906
+ {
9907
+ className: cn(
9908
+ "rounded-full bg-primary/10 flex items-center justify-center",
9909
+ uploadContainerSize
9910
+ ),
9911
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { className: cn("text-primary", uploadIconSize) })
9912
+ }
9913
+ ),
9914
+ /* @__PURE__ */ jsxRuntime.jsx(
9915
+ "span",
9916
+ {
9917
+ className: cn("font-medium", isLarge ? "text-base" : "text-sm"),
9918
+ children: "Click to upload"
9919
+ }
9920
+ ),
9921
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-muted-foreground", textSize), children: "PNG, JPG up to 10MB" })
9922
+ ]
9923
+ }
9924
+ ),
9925
+ /* @__PURE__ */ jsxRuntime.jsx(
9926
+ "canvas",
9927
+ {
9928
+ ref: canvasRef,
9929
+ className: cn(
9930
+ "absolute inset-0",
9931
+ imageLoaded ? "cursor-move" : "pointer-events-none opacity-0"
9932
+ ),
9933
+ style: { width: size4, height: size4 },
9934
+ onMouseDown: handleMouseDown,
9935
+ onMouseMove: handleMouseMove,
9936
+ onMouseUp: handleMouseUp,
9937
+ onMouseLeave: handleMouseUp,
9938
+ onTouchStart: handleTouchStart,
9939
+ onTouchMove: handleTouchMove,
9940
+ onTouchEnd: handleMouseUp
9941
+ }
9942
+ ),
9943
+ showGrid && imageLoaded && /* @__PURE__ */ jsxRuntime.jsx(
9944
+ "div",
9945
+ {
9946
+ className: "absolute inset-0 pointer-events-none",
9947
+ style: { width: size4, height: size4 },
9948
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: size4, height: size4, className: "opacity-30", children: [
9949
+ /* @__PURE__ */ jsxRuntime.jsx(
9950
+ "line",
9951
+ {
9952
+ x1: size4 / 3,
9953
+ y1: 0,
9954
+ x2: size4 / 3,
9955
+ y2: size4,
9956
+ stroke: "white",
9957
+ strokeWidth: "1"
9958
+ }
9959
+ ),
9960
+ /* @__PURE__ */ jsxRuntime.jsx(
9961
+ "line",
9962
+ {
9963
+ x1: size4 * 2 / 3,
9964
+ y1: 0,
9965
+ x2: size4 * 2 / 3,
9966
+ y2: size4,
9967
+ stroke: "white",
9968
+ strokeWidth: "1"
9969
+ }
9970
+ ),
9971
+ /* @__PURE__ */ jsxRuntime.jsx(
9972
+ "line",
9973
+ {
9974
+ x1: 0,
9975
+ y1: size4 / 3,
9976
+ x2: size4,
9977
+ y2: size4 / 3,
9978
+ stroke: "white",
9979
+ strokeWidth: "1"
9980
+ }
9981
+ ),
9982
+ /* @__PURE__ */ jsxRuntime.jsx(
9983
+ "line",
9984
+ {
9985
+ x1: 0,
9986
+ y1: size4 * 2 / 3,
9987
+ x2: size4,
9988
+ y2: size4 * 2 / 3,
9989
+ stroke: "white",
9990
+ strokeWidth: "1"
9991
+ }
9992
+ ),
9993
+ /* @__PURE__ */ jsxRuntime.jsx(
9994
+ "line",
9995
+ {
9996
+ x1: size4 / 2 - 10,
9997
+ y1: size4 / 2,
9998
+ x2: size4 / 2 + 10,
9999
+ y2: size4 / 2,
10000
+ stroke: "white",
10001
+ strokeWidth: "1"
10002
+ }
10003
+ ),
10004
+ /* @__PURE__ */ jsxRuntime.jsx(
10005
+ "line",
10006
+ {
10007
+ x1: size4 / 2,
10008
+ y1: size4 / 2 - 10,
10009
+ x2: size4 / 2,
10010
+ y2: size4 / 2 + 10,
10011
+ stroke: "white",
10012
+ strokeWidth: "1"
10013
+ }
10014
+ )
10015
+ ] })
10016
+ }
10017
+ ),
10018
+ imageLoaded && isDragging && /* @__PURE__ */ jsxRuntime.jsxs(
10019
+ "div",
10020
+ {
10021
+ className: cn(
10022
+ "absolute top-2 left-1/2 -translate-x-1/2 bg-black/60 rounded text-white flex items-center",
10023
+ isLarge ? "px-3 py-2 text-sm gap-2" : "px-2 py-1 text-xs gap-1"
10024
+ ),
10025
+ children: [
10026
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Move, { className: smallIconSize }),
10027
+ "Dragging"
10028
+ ]
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ ),
10034
+ imageLoaded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4", isLarge && "space-y-5"), children: [
10035
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center", controlGap), children: [
10036
+ /* @__PURE__ */ jsxRuntime.jsx(
10037
+ Button,
10038
+ {
10039
+ variant: "ghost",
10040
+ size: "icon",
10041
+ className: cn(buttonSize, "shrink-0"),
10042
+ onClick: handleZoomOut,
10043
+ "aria-label": "Zoom out",
10044
+ type: "button",
10045
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { className: iconSize })
10046
+ }
10047
+ ),
10048
+ /* @__PURE__ */ jsxRuntime.jsx(
10049
+ Slider,
10050
+ {
10051
+ value: [zoom],
10052
+ onValueChange: ([v]) => setZoom(v),
10053
+ min: 0.5,
10054
+ max: 3,
10055
+ step: 0.01,
10056
+ className: cn("flex-1", sliderHeight),
10057
+ "aria-label": "Zoom level"
10058
+ }
10059
+ ),
10060
+ /* @__PURE__ */ jsxRuntime.jsx(
10061
+ Button,
10062
+ {
10063
+ variant: "ghost",
10064
+ size: "icon",
10065
+ className: cn(buttonSize, "shrink-0"),
10066
+ onClick: handleZoomIn,
10067
+ "aria-label": "Zoom in",
10068
+ type: "button",
10069
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { className: iconSize })
10070
+ }
10071
+ )
10072
+ ] }),
10073
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center justify-between", controlGap), children: [
10074
+ /* @__PURE__ */ jsxRuntime.jsxs(
10075
+ "div",
10076
+ {
10077
+ className: cn("flex items-center", isLarge ? "gap-2" : "gap-1"),
10078
+ children: [
10079
+ /* @__PURE__ */ jsxRuntime.jsx(
10080
+ Button,
10081
+ {
10082
+ variant: "ghost",
10083
+ size: "icon",
10084
+ className: buttonSize,
10085
+ onClick: handleRotateLeft,
10086
+ "aria-label": "Rotate left 15 degrees",
10087
+ type: "button",
10088
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: iconSize })
10089
+ }
10090
+ ),
10091
+ /* @__PURE__ */ jsxRuntime.jsxs(
10092
+ "span",
10093
+ {
10094
+ className: cn(
10095
+ "text-muted-foreground text-center tabular-nums",
10096
+ textSize,
10097
+ isLarge ? "w-16" : "w-12"
10098
+ ),
10099
+ children: [
10100
+ rotation,
10101
+ "\xB0"
10102
+ ]
10103
+ }
10104
+ ),
10105
+ /* @__PURE__ */ jsxRuntime.jsx(
10106
+ Button,
10107
+ {
10108
+ variant: "ghost",
10109
+ size: "icon",
10110
+ className: buttonSize,
10111
+ onClick: handleRotateRight,
10112
+ "aria-label": "Rotate right 15 degrees",
10113
+ type: "button",
10114
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCw, { className: iconSize })
10115
+ }
10116
+ )
10117
+ ]
10118
+ }
10119
+ ),
10120
+ /* @__PURE__ */ jsxRuntime.jsxs(
10121
+ "div",
10122
+ {
10123
+ className: cn("flex items-center", isLarge ? "gap-2" : "gap-1"),
10124
+ children: [
10125
+ /* @__PURE__ */ jsxRuntime.jsx(
10126
+ Toggle,
10127
+ {
10128
+ pressed: showGrid,
10129
+ onPressedChange: setShowGrid,
10130
+ size: "sm",
10131
+ className: cn(buttonSize, "p-0"),
10132
+ "aria-label": "Toggle grid overlay",
10133
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Grid3X3, { className: iconSize })
10134
+ }
10135
+ ),
10136
+ /* @__PURE__ */ jsxRuntime.jsx(
10137
+ Button,
10138
+ {
10139
+ variant: "ghost",
10140
+ size: "icon",
10141
+ className: buttonSize,
10142
+ onClick: resetTransforms,
10143
+ "aria-label": "Reset all transforms",
10144
+ type: "button",
10145
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: iconSize })
10146
+ }
10147
+ ),
10148
+ /* @__PURE__ */ jsxRuntime.jsx(
10149
+ Button,
10150
+ {
10151
+ variant: "ghost",
10152
+ size: "icon",
10153
+ className: buttonSize,
10154
+ onClick: () => fileInputRef.current?.click(),
10155
+ "aria-label": "Upload new image",
10156
+ type: "button",
10157
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { className: iconSize })
10158
+ }
10159
+ ),
10160
+ /* @__PURE__ */ jsxRuntime.jsx(
10161
+ Button,
10162
+ {
10163
+ variant: "ghost",
10164
+ size: "icon",
10165
+ className: cn(
10166
+ buttonSize,
10167
+ "text-destructive hover:text-destructive hover:bg-destructive/10"
10168
+ ),
10169
+ onClick: handleDiscard,
10170
+ "aria-label": "Discard image",
10171
+ type: "button",
10172
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: iconSize })
10173
+ }
10174
+ )
10175
+ ]
10176
+ }
10177
+ )
10178
+ ] })
10179
+ ] }),
10180
+ /* @__PURE__ */ jsxRuntime.jsx(
10181
+ "input",
10182
+ {
10183
+ ref: fileInputRef,
10184
+ type: "file",
10185
+ accept: "image/*",
10186
+ onChange: handleFileSelect,
10187
+ className: "hidden",
10188
+ "aria-hidden": "true"
10189
+ }
10190
+ )
10191
+ ]
10192
+ }
10193
+ );
10194
+ }
10195
+ function Dialog({
10196
+ ...props
10197
+ }) {
10198
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
10199
+ }
10200
+ function DialogTrigger({
10201
+ ...props
10202
+ }) {
10203
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Trigger, { "data-slot": "dialog-trigger", ...props });
10204
+ }
10205
+ function DialogPortal({
10206
+ ...props
10207
+ }) {
10208
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
10209
+ }
10210
+ function DialogClose({
10211
+ ...props
10212
+ }) {
10213
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { "data-slot": "dialog-close", ...props });
10214
+ }
10215
+ function DialogOverlay({
10216
+ className,
10217
+ ...props
10218
+ }) {
10219
+ return /* @__PURE__ */ jsxRuntime.jsx(
10220
+ DialogPrimitive__namespace.Overlay,
10221
+ {
10222
+ "data-slot": "dialog-overlay",
10223
+ className: cn(
10224
+ "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",
10225
+ className
10226
+ ),
10227
+ ...props
10228
+ }
10229
+ );
10230
+ }
10231
+ function DialogContent({
10232
+ className,
10233
+ children,
10234
+ showCloseButton = true,
10235
+ ...props
10236
+ }) {
10237
+ return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
10238
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
10239
+ /* @__PURE__ */ jsxRuntime.jsxs(
10240
+ DialogPrimitive__namespace.Content,
10241
+ {
10242
+ "data-slot": "dialog-content",
10243
+ className: cn(
10244
+ "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",
10245
+ className
10246
+ ),
10247
+ ...props,
10248
+ children: [
10249
+ children,
10250
+ showCloseButton && /* @__PURE__ */ jsxRuntime.jsxs(
10251
+ DialogPrimitive__namespace.Close,
10252
+ {
10253
+ "data-slot": "dialog-close",
10254
+ 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",
10255
+ children: [
10256
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
10257
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
10258
+ ]
10259
+ }
10260
+ )
10261
+ ]
10262
+ }
10263
+ )
10264
+ ] });
10265
+ }
10266
+ function DialogHeader({ className, ...props }) {
10267
+ return /* @__PURE__ */ jsxRuntime.jsx(
10268
+ "div",
10269
+ {
10270
+ "data-slot": "dialog-header",
10271
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
10272
+ ...props
10273
+ }
10274
+ );
10275
+ }
10276
+ function DialogFooter({ className, ...props }) {
10277
+ return /* @__PURE__ */ jsxRuntime.jsx(
10278
+ "div",
10279
+ {
10280
+ "data-slot": "dialog-footer",
10281
+ className: cn(
10282
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
10283
+ className
10284
+ ),
10285
+ ...props
10286
+ }
10287
+ );
10288
+ }
10289
+ function DialogTitle({
10290
+ className,
10291
+ ...props
10292
+ }) {
10293
+ return /* @__PURE__ */ jsxRuntime.jsx(
10294
+ DialogPrimitive__namespace.Title,
10295
+ {
10296
+ "data-slot": "dialog-title",
10297
+ className: cn("text-lg leading-none font-semibold", className),
10298
+ ...props
10299
+ }
10300
+ );
10301
+ }
10302
+ function DialogDescription({
10303
+ className,
10304
+ ...props
10305
+ }) {
10306
+ return /* @__PURE__ */ jsxRuntime.jsx(
10307
+ DialogPrimitive__namespace.Description,
10308
+ {
10309
+ "data-slot": "dialog-description",
10310
+ className: cn("text-muted-foreground text-sm", className),
10311
+ ...props
10312
+ }
10313
+ );
10314
+ }
10315
+ function Drawer({
10316
+ ...props
10317
+ }) {
10318
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Root, { "data-slot": "drawer", ...props });
10319
+ }
10320
+ function DrawerTrigger({
10321
+ ...props
10322
+ }) {
10323
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Trigger, { "data-slot": "drawer-trigger", ...props });
10324
+ }
10325
+ function DrawerPortal({
10326
+ ...props
10327
+ }) {
10328
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Portal, { "data-slot": "drawer-portal", ...props });
10329
+ }
10330
+ function DrawerClose({
10331
+ ...props
10332
+ }) {
10333
+ return /* @__PURE__ */ jsxRuntime.jsx(vaul.Drawer.Close, { "data-slot": "drawer-close", ...props });
10334
+ }
10335
+ function DrawerOverlay({
10336
+ className,
10337
+ ...props
10338
+ }) {
10339
+ return /* @__PURE__ */ jsxRuntime.jsx(
10340
+ vaul.Drawer.Overlay,
10341
+ {
10342
+ "data-slot": "drawer-overlay",
10343
+ className: cn(
10344
+ "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",
10345
+ className
10346
+ ),
10347
+ ...props
10348
+ }
10349
+ );
10350
+ }
10351
+ function DrawerContent({
10352
+ className,
10353
+ children,
10354
+ ...props
10355
+ }) {
10356
+ return /* @__PURE__ */ jsxRuntime.jsxs(DrawerPortal, { "data-slot": "drawer-portal", children: [
10357
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerOverlay, {}),
10358
+ /* @__PURE__ */ jsxRuntime.jsxs(
10359
+ vaul.Drawer.Content,
10360
+ {
10361
+ "data-slot": "drawer-content",
10362
+ className: cn(
10363
+ "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
10364
+ "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",
10365
+ "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",
10366
+ "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",
10367
+ "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",
10368
+ className
10369
+ ),
10370
+ ...props,
10371
+ children: [
10372
+ /* @__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" }),
10373
+ children
10374
+ ]
10375
+ }
10376
+ )
10377
+ ] });
10378
+ }
10379
+ function DrawerHeader({ className, ...props }) {
10380
+ return /* @__PURE__ */ jsxRuntime.jsx(
10381
+ "div",
10382
+ {
10383
+ "data-slot": "drawer-header",
10384
+ className: cn(
10385
+ "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",
10386
+ className
10387
+ ),
10388
+ ...props
10389
+ }
10390
+ );
10391
+ }
10392
+ function DrawerFooter({ className, ...props }) {
10393
+ return /* @__PURE__ */ jsxRuntime.jsx(
10394
+ "div",
10395
+ {
10396
+ "data-slot": "drawer-footer",
10397
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
10398
+ ...props
10399
+ }
10400
+ );
10401
+ }
10402
+ function DrawerTitle({
10403
+ className,
10404
+ ...props
10405
+ }) {
10406
+ return /* @__PURE__ */ jsxRuntime.jsx(
10407
+ vaul.Drawer.Title,
10408
+ {
10409
+ "data-slot": "drawer-title",
10410
+ className: cn("text-foreground font-semibold", className),
10411
+ ...props
10412
+ }
10413
+ );
10414
+ }
10415
+ function DrawerDescription({
10416
+ className,
10417
+ ...props
10418
+ }) {
10419
+ return /* @__PURE__ */ jsxRuntime.jsx(
10420
+ vaul.Drawer.Description,
10421
+ {
10422
+ "data-slot": "drawer-description",
10423
+ className: cn("text-muted-foreground text-sm", className),
10424
+ ...props
10425
+ }
10426
+ );
10427
+ }
10428
+ function useMediaQuery(query) {
10429
+ const [matches, setMatches] = React32.useState(false);
10430
+ React32.useEffect(() => {
10431
+ const media = window.matchMedia(query);
10432
+ if (media.matches !== matches) {
10433
+ setMatches(media.matches);
10434
+ }
10435
+ const listener = () => setMatches(media.matches);
10436
+ media.addEventListener("change", listener);
10437
+ return () => media.removeEventListener("change", listener);
10438
+ }, [matches, query]);
10439
+ return matches;
10440
+ }
10441
+ function AvatarEditorDialog({
10442
+ value,
10443
+ onChange,
10444
+ onSave,
10445
+ displaySize = 120,
10446
+ editorSize = 280,
10447
+ outputSize = 256,
10448
+ placeholder: _placeholder = "Add Photo",
10449
+ editLabel = "Edit avatar",
10450
+ dialogTitle = "Edit Avatar",
10451
+ acceptText = "Accept",
10452
+ cancelText = "Cancel",
10453
+ successMessage = "Avatar saved successfully!",
10454
+ errorMessage = "Failed to save avatar. Please try again.",
10455
+ className
10456
+ }) {
10457
+ const [isOpen, setIsOpen] = React32.useState(false);
10458
+ const [editedValue, setEditedValue] = React32.useState(value ?? null);
10459
+ const [isSaving, setIsSaving] = React32.useState(false);
10460
+ const [feedback, setFeedback] = React32.useState(null);
10461
+ const isMobile = useMediaQuery("(max-width: 640px)");
10462
+ const handleOpenChange = React32.useCallback(
10463
+ (open) => {
10464
+ if (open) {
10465
+ setEditedValue(value ?? null);
10466
+ setFeedback(null);
10467
+ }
10468
+ setIsOpen(open);
10469
+ },
10470
+ [value]
10471
+ );
10472
+ const handleAccept = React32.useCallback(async () => {
10473
+ if (!editedValue) return;
10474
+ setIsSaving(true);
10475
+ setFeedback(null);
10476
+ try {
10477
+ if (onSave) {
10478
+ const result = await onSave(editedValue);
10479
+ if (result) {
10480
+ setFeedback({ type: "success", message: successMessage });
10481
+ setTimeout(() => {
10482
+ setIsOpen(false);
10483
+ setFeedback(null);
10484
+ }, 1500);
10485
+ } else {
10486
+ setFeedback({ type: "error", message: errorMessage });
10487
+ }
10488
+ } else {
10489
+ onChange?.(editedValue);
10490
+ setFeedback({ type: "success", message: successMessage });
10491
+ setTimeout(() => {
10492
+ setIsOpen(false);
10493
+ setFeedback(null);
10494
+ }, 1500);
10495
+ }
10496
+ } catch {
10497
+ setFeedback({ type: "error", message: errorMessage });
10498
+ } finally {
10499
+ setIsSaving(false);
10500
+ }
10501
+ }, [editedValue, onChange, onSave, successMessage, errorMessage]);
10502
+ const AvatarDisplay = /* @__PURE__ */ jsxRuntime.jsxs(
10503
+ "div",
10504
+ {
10505
+ className: cn("relative group", className),
10506
+ style: { width: displaySize, height: displaySize },
10507
+ children: [
10508
+ /* @__PURE__ */ jsxRuntime.jsx(
10509
+ "div",
10510
+ {
10511
+ className: "w-full h-full rounded-full overflow-hidden bg-muted border-2 border-border flex items-center justify-center",
10512
+ style: { width: displaySize, height: displaySize },
10513
+ children: value ? /* @__PURE__ */ jsxRuntime.jsx(
10514
+ "img",
10515
+ {
10516
+ src: value || "/placeholder.svg",
10517
+ alt: "Avatar",
10518
+ className: "w-full h-full object-cover"
10519
+ }
10520
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-10 h-10" }) })
10521
+ }
10522
+ ),
10523
+ /* @__PURE__ */ jsxRuntime.jsx(
10524
+ "button",
10525
+ {
10526
+ onClick: () => handleOpenChange(true),
10527
+ 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",
10528
+ "aria-label": editLabel,
10529
+ type: "button",
10530
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "w-4 h-4" })
10531
+ }
10532
+ )
10533
+ ]
10534
+ }
10535
+ );
10536
+ const mobileEditorSize = isMobile ? Math.min(editorSize + 40, window.innerWidth - 48) : editorSize;
10537
+ const EditorContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
10538
+ /* @__PURE__ */ jsxRuntime.jsx(
10539
+ AvatarEditor,
10540
+ {
10541
+ value: editedValue,
10542
+ onChange: setEditedValue,
10543
+ size: mobileEditorSize,
10544
+ outputSize,
10545
+ controlSize: isMobile ? "large" : "default"
10546
+ }
10547
+ ),
10548
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: feedback && /* @__PURE__ */ jsxRuntime.jsxs(
10549
+ react.motion.div,
10550
+ {
10551
+ initial: { opacity: 0, y: -10 },
10552
+ animate: { opacity: 1, y: 0 },
10553
+ exit: { opacity: 0, y: -10 },
10554
+ className: cn(
10555
+ "flex items-center gap-2 rounded-lg font-medium",
10556
+ isMobile ? "px-5 py-3 text-base" : "px-4 py-2 text-sm",
10557
+ 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"
10558
+ ),
10559
+ children: [
10560
+ 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" }),
10561
+ feedback.message
10562
+ ]
10563
+ }
10564
+ ) })
10565
+ ] });
10566
+ const FooterButtons = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10567
+ isMobile ? /* @__PURE__ */ jsxRuntime.jsx(DrawerClose, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
10568
+ Button,
10569
+ {
10570
+ variant: "outline",
10571
+ disabled: isSaving,
10572
+ size: "lg",
10573
+ className: "flex-1 bg-transparent",
10574
+ children: cancelText
10575
+ }
10576
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", disabled: isSaving, children: cancelText }) }),
10577
+ /* @__PURE__ */ jsxRuntime.jsx(
10578
+ Button,
10579
+ {
10580
+ onClick: handleAccept,
10581
+ disabled: !editedValue || isSaving || feedback?.type === "success",
10582
+ size: isMobile ? "lg" : "default",
10583
+ className: isMobile ? "flex-1" : "",
10584
+ children: isSaving ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10585
+ /* @__PURE__ */ jsxRuntime.jsx(
10586
+ lucideReact.Loader2,
10587
+ {
10588
+ className: cn(
10589
+ "mr-2 animate-spin",
10590
+ isMobile ? "w-5 h-5" : "w-4 h-4"
10591
+ )
10592
+ }
10593
+ ),
10594
+ "Saving..."
10595
+ ] }) : feedback?.type === "success" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10596
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("mr-2", isMobile ? "w-5 h-5" : "w-4 h-4") }),
10597
+ "Saved!"
10598
+ ] }) : acceptText
10599
+ }
10600
+ )
10601
+ ] });
10602
+ if (isMobile) {
10603
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10604
+ AvatarDisplay,
10605
+ /* @__PURE__ */ jsxRuntime.jsx(Drawer, { open: isOpen, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DrawerContent, { className: "max-h-[96vh]", children: [
10606
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerHeader, { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx(DrawerTitle, { className: "text-xl", children: dialogTitle }) }),
10607
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 pb-6 overflow-y-auto", children: EditorContent }),
10608
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerFooter, { className: "flex-row gap-3 px-6 pb-8", children: FooterButtons })
10609
+ ] }) })
10610
+ ] });
10611
+ }
10612
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10613
+ AvatarDisplay,
10614
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: isOpen, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-md", children: [
10615
+ /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: dialogTitle }) }),
10616
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: EditorContent }),
10617
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { className: "gap-2 sm:gap-0", children: FooterButtons })
10618
+ ] }) })
10619
+ ] });
10620
+ }
10621
+ function Popover({
10622
+ ...props
10623
+ }) {
10624
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Root, { "data-slot": "popover", ...props });
10625
+ }
10626
+ function PopoverTrigger({
10627
+ ...props
10628
+ }) {
10629
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Trigger, { "data-slot": "popover-trigger", ...props });
10630
+ }
10631
+ function PopoverContent({
10632
+ className,
10633
+ align = "center",
10634
+ sideOffset = 4,
10635
+ ...props
10636
+ }) {
10637
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
10638
+ PopoverPrimitive__namespace.Content,
10639
+ {
10640
+ "data-slot": "popover-content",
10641
+ align,
10642
+ sideOffset,
10643
+ className: cn(
10644
+ "bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
10645
+ className
10646
+ ),
10647
+ ...props
10648
+ }
10649
+ ) });
10650
+ }
10651
+ function PopoverAnchor({
10652
+ ...props
10653
+ }) {
10654
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Anchor, { "data-slot": "popover-anchor", ...props });
10655
+ }
10656
+ function ScrollArea({
10657
+ className,
10658
+ children,
10659
+ ...props
10660
+ }) {
10661
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10662
+ ScrollAreaPrimitive__namespace.Root,
10663
+ {
10664
+ "data-slot": "scroll-area",
10665
+ className: cn("relative overflow-hidden", className),
10666
+ ...props,
10667
+ children: [
10668
+ /* @__PURE__ */ jsxRuntime.jsx(
10669
+ ScrollAreaPrimitive__namespace.Viewport,
10670
+ {
10671
+ "data-slot": "scroll-area-viewport",
10672
+ className: "h-full w-full rounded-[inherit]",
10673
+ children
10674
+ }
10675
+ ),
10676
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, {}),
10677
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollAreaPrimitive__namespace.Corner, {})
10678
+ ]
10679
+ }
10680
+ );
10681
+ }
10682
+ function ScrollBar({
10683
+ className,
10684
+ orientation = "vertical",
10685
+ ...props
10686
+ }) {
10687
+ return /* @__PURE__ */ jsxRuntime.jsx(
10688
+ ScrollAreaPrimitive__namespace.ScrollAreaScrollbar,
10689
+ {
10690
+ "data-slot": "scroll-bar",
10691
+ orientation,
10692
+ className: cn(
10693
+ "flex touch-none select-none transition-colors",
10694
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
10695
+ orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
10696
+ className
10697
+ ),
10698
+ ...props,
10699
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10700
+ ScrollAreaPrimitive__namespace.ScrollAreaThumb,
10701
+ {
10702
+ "data-slot": "scroll-thumb",
10703
+ className: "relative flex-1 rounded-full bg-border"
10704
+ }
10705
+ )
10706
+ }
10707
+ );
10708
+ }
10709
+ var sizeConfig = {
10710
+ sm: {
10711
+ button: "h-8 w-8",
10712
+ icon: "w-4 h-4",
10713
+ badge: "min-w-[16px] h-4 text-[10px] -top-1 -right-1",
10714
+ dot: "w-2.5 h-2.5 -top-0.5 -right-0.5"
10715
+ },
10716
+ md: {
10717
+ button: "h-9 w-9",
10718
+ icon: "w-5 h-5",
10719
+ badge: "min-w-[18px] h-[18px] text-[11px] -top-1 -right-1",
10720
+ dot: "w-3 h-3 -top-0.5 -right-0.5"
10721
+ },
10722
+ lg: {
10723
+ button: "h-10 w-10",
10724
+ icon: "w-6 h-6",
10725
+ badge: "min-w-[20px] h-5 text-xs -top-1.5 -right-1.5",
10726
+ dot: "w-3.5 h-3.5 -top-0.5 -right-0.5"
10727
+ }
10728
+ };
10729
+ var typeConfig = {
10730
+ info: {
10731
+ icon: lucideReact.Info,
10732
+ color: "text-blue-500",
10733
+ bg: "bg-blue-500/10"
10734
+ },
10735
+ success: {
10736
+ icon: lucideReact.CheckCircle,
10737
+ color: "text-green-500",
10738
+ bg: "bg-green-500/10"
10739
+ },
10740
+ warning: {
10741
+ icon: lucideReact.AlertTriangle,
10742
+ color: "text-amber-500",
10743
+ bg: "bg-amber-500/10"
10744
+ },
10745
+ error: {
10746
+ icon: lucideReact.XCircle,
10747
+ color: "text-red-500",
10748
+ bg: "bg-red-500/10"
10749
+ }
10750
+ };
10751
+ var dotColorConfig = {
10752
+ red: "bg-red-500",
10753
+ blue: "bg-blue-500",
10754
+ green: "bg-green-500",
10755
+ amber: "bg-amber-500",
10756
+ purple: "bg-purple-500",
10757
+ primary: "bg-primary"
10758
+ };
10759
+ var soundConfig = {
10760
+ chime: {
10761
+ frequencies: [880, 1100],
10762
+ durations: [0.1, 0.2],
10763
+ gain: 0.3
10764
+ },
10765
+ bell: {
10766
+ frequencies: [523, 659, 784],
10767
+ durations: [0.15, 0.15, 0.2],
10768
+ gain: 0.25
10769
+ },
10770
+ pop: {
10771
+ frequencies: [400, 600],
10772
+ durations: [0.05, 0.08],
10773
+ gain: 0.4
10774
+ },
10775
+ ding: {
10776
+ frequencies: [1200],
10777
+ durations: [0.15],
10778
+ gain: 0.2
10779
+ }
10780
+ };
10781
+ var pulseVariants = {
10782
+ ring: {
10783
+ animate: { scale: [1, 1.8], opacity: [0.6, 0] },
10784
+ transition: {
10785
+ duration: 1.2,
10786
+ repeat: Number.POSITIVE_INFINITY,
10787
+ ease: "easeOut"
10788
+ }
10789
+ },
10790
+ glow: {
10791
+ animate: { scale: [1, 1.3, 1], opacity: [0.8, 0.4, 0.8] },
10792
+ transition: {
10793
+ duration: 1.5,
10794
+ repeat: Number.POSITIVE_INFINITY,
10795
+ ease: "easeInOut"
10796
+ }
10797
+ },
10798
+ bounce: {
10799
+ animate: { scale: [1, 1.2, 1], y: [0, -2, 0] },
10800
+ transition: {
10801
+ duration: 0.6,
10802
+ repeat: Number.POSITIVE_INFINITY,
10803
+ ease: "easeInOut"
10804
+ }
10805
+ }
10806
+ };
10807
+ function formatTimeAgo(date) {
10808
+ const now = /* @__PURE__ */ new Date();
10809
+ const diffMs = now.getTime() - date.getTime();
10810
+ const diffSecs = Math.floor(diffMs / 1e3);
10811
+ const diffMins = Math.floor(diffSecs / 60);
10812
+ const diffHours = Math.floor(diffMins / 60);
10813
+ const diffDays = Math.floor(diffHours / 24);
10814
+ if (diffSecs < 60) return "just now";
10815
+ if (diffMins < 60) return `${diffMins}m ago`;
10816
+ if (diffHours < 24) return `${diffHours}h ago`;
10817
+ if (diffDays < 7) return `${diffDays}d ago`;
10818
+ return date.toLocaleDateString();
10819
+ }
10820
+ function playNotificationSound(soundType = "chime", soundUrl) {
10821
+ if (typeof window === "undefined" || soundType === "none") return;
10822
+ if (soundUrl) {
10823
+ const audio = new Audio(soundUrl);
10824
+ audio.volume = 0.5;
10825
+ audio.play().catch(() => {
10826
+ });
10827
+ return;
10828
+ }
10829
+ const config = soundConfig[soundType];
10830
+ if (!config) return;
10831
+ try {
10832
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
10833
+ let currentTime = audioContext.currentTime;
10834
+ config.frequencies.forEach((freq, i) => {
10835
+ const oscillator = audioContext.createOscillator();
10836
+ const gainNode = audioContext.createGain();
10837
+ oscillator.connect(gainNode);
10838
+ gainNode.connect(audioContext.destination);
10839
+ oscillator.frequency.setValueAtTime(freq, currentTime);
10840
+ gainNode.gain.setValueAtTime(config.gain, currentTime);
10841
+ gainNode.gain.exponentialRampToValueAtTime(
10842
+ 0.01,
10843
+ currentTime + config.durations[i]
10844
+ );
10845
+ oscillator.start(currentTime);
10846
+ oscillator.stop(currentTime + config.durations[i]);
10847
+ currentTime += config.durations[i] * 0.7;
10848
+ });
10849
+ } catch {
10850
+ }
10851
+ }
10852
+ function NotificationsWidget({
10853
+ notifications,
10854
+ onMarkAsRead,
10855
+ onMarkAllAsRead,
10856
+ onDismiss,
10857
+ onClearAll,
10858
+ onNotificationClick,
10859
+ size: size4 = "md",
10860
+ maxVisible = 5,
10861
+ playSound: _playSound = true,
10862
+ soundUrl,
10863
+ className,
10864
+ emptyMessage = "No notifications",
10865
+ title = "Notifications",
10866
+ dotColor = "red",
10867
+ showPulse = true,
10868
+ soundType = "chime",
10869
+ pulseStyle = "ring",
10870
+ soundCooldown = 2e3
10871
+ }) {
10872
+ const [isOpen, setIsOpen] = React32__namespace.useState(false);
10873
+ const [prevCount, setPrevCount] = React32__namespace.useState(0);
10874
+ const lastSoundPlayedRef = React32__namespace.useRef(0);
10875
+ const styles = sizeConfig[size4];
10876
+ const dotBgColor = dotColorConfig[dotColor];
10877
+ const unreadCount = notifications.filter((n) => !n.read).length;
10878
+ const visibleNotifications = notifications.slice(0, maxVisible);
10879
+ const hasMore = notifications.length > maxVisible;
10880
+ React32__namespace.useEffect(() => {
10881
+ if (soundType !== "none" && unreadCount > prevCount && prevCount > 0) {
10882
+ const now = Date.now();
10883
+ if (now - lastSoundPlayedRef.current >= soundCooldown) {
10884
+ playNotificationSound(soundType, soundUrl);
10885
+ lastSoundPlayedRef.current = now;
10886
+ }
10887
+ }
10888
+ setPrevCount(unreadCount);
10889
+ }, [unreadCount, prevCount, soundType, soundUrl, soundCooldown]);
10890
+ React32__namespace.useEffect(() => {
10891
+ if (isOpen && onMarkAsRead) {
10892
+ visibleNotifications.forEach((notification) => {
10893
+ if (!notification.read) {
10894
+ onMarkAsRead(notification.id);
10895
+ }
10896
+ });
10897
+ }
10898
+ }, [isOpen, onMarkAsRead, visibleNotifications]);
10899
+ const handleNotificationClick = (notification) => {
10900
+ if (notification.href) {
10901
+ onNotificationClick?.(notification);
10902
+ }
10903
+ };
10904
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
10905
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
10906
+ react.motion.button,
10907
+ {
10908
+ className: cn(
10909
+ "relative inline-flex items-center justify-center rounded-lg",
10910
+ "bg-muted/50 border border-border/50 hover:bg-muted/70 transition-colors",
10911
+ styles.button,
10912
+ className
10913
+ ),
10914
+ whileTap: { scale: 0.95 },
10915
+ "aria-label": `Notifications${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
10916
+ children: [
10917
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className: cn(styles.icon, "text-muted-foreground") }),
10918
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
10919
+ react.motion.div,
10920
+ {
10921
+ initial: { scale: 0, opacity: 0 },
10922
+ animate: { scale: 1, opacity: 1 },
10923
+ exit: { scale: 0, opacity: 0 },
10924
+ className: cn(
10925
+ "absolute flex items-center justify-center rounded-full",
10926
+ dotBgColor,
10927
+ "text-white font-medium",
10928
+ unreadCount > 9 ? styles.badge : styles.dot,
10929
+ unreadCount > 9 && "px-1"
10930
+ ),
10931
+ children: unreadCount > 9 ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: unreadCount > 99 ? "99+" : unreadCount }) : null
10932
+ }
10933
+ ) }),
10934
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: unreadCount > 0 && showPulse && pulseStyle !== "none" && /* @__PURE__ */ jsxRuntime.jsx(
10935
+ react.motion.div,
10936
+ {
10937
+ initial: { scale: 1, opacity: 0.5 },
10938
+ animate: pulseVariants[pulseStyle].animate,
10939
+ transition: pulseVariants[pulseStyle].transition,
10940
+ className: cn("absolute rounded-full", dotBgColor, styles.dot)
10941
+ }
10942
+ ) })
10943
+ ]
10944
+ }
10945
+ ) }),
10946
+ /* @__PURE__ */ jsxRuntime.jsxs(
10947
+ PopoverContent,
10948
+ {
10949
+ side: "bottom",
10950
+ align: "end",
10951
+ className: "w-80 p-0 overflow-hidden",
10952
+ children: [
10953
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-border", children: [
10954
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10955
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-sm", children: title }),
10956
+ unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-2 py-0.5 text-xs font-medium rounded-full bg-primary/10 text-primary", children: [
10957
+ unreadCount,
10958
+ " new"
10959
+ ] })
10960
+ ] }),
10961
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: unreadCount > 0 && onMarkAllAsRead && /* @__PURE__ */ jsxRuntime.jsxs(
10962
+ Button,
10963
+ {
10964
+ variant: "ghost",
10965
+ size: "sm",
10966
+ className: "h-7 px-2 text-xs",
10967
+ onClick: () => onMarkAllAsRead(),
10968
+ children: [
10969
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCheck, { className: "w-3.5 h-3.5 mr-1" }),
10970
+ "Mark all read"
10971
+ ]
10972
+ }
10973
+ ) })
10974
+ ] }),
10975
+ notifications.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-8 px-4 text-center", children: [
10976
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-full bg-muted flex items-center justify-center mb-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className: "w-6 h-6 text-muted-foreground" }) }),
10977
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage })
10978
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10979
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-[320px]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border", children: visibleNotifications.map((notification) => {
10980
+ const config = typeConfig[notification.type || "info"];
10981
+ const Icon = config.icon;
10982
+ const hasLink = !!notification.href;
10983
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10984
+ react.motion.div,
10985
+ {
10986
+ initial: { opacity: 0, y: -10 },
10987
+ animate: { opacity: 1, y: 0 },
10988
+ className: cn(
10989
+ "relative flex gap-3 px-4 py-3 transition-colors group",
10990
+ hasLink && "cursor-pointer hover:bg-muted/50",
10991
+ !hasLink && "cursor-default",
10992
+ !notification.read && "bg-primary/5"
10993
+ ),
10994
+ onClick: () => handleNotificationClick(notification),
10995
+ children: [
10996
+ /* @__PURE__ */ jsxRuntime.jsx(
10997
+ "div",
10998
+ {
10999
+ className: cn(
11000
+ "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center",
11001
+ config.bg
11002
+ ),
11003
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: cn("w-4 h-4", config.color) })
11004
+ }
11005
+ ),
11006
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
11007
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
11008
+ "p",
11009
+ {
11010
+ className: cn(
11011
+ "text-sm line-clamp-1",
11012
+ !notification.read ? "font-semibold" : "font-medium",
11013
+ hasLink && "group-hover:underline"
11014
+ ),
11015
+ children: notification.title
11016
+ }
11017
+ ) }),
11018
+ notification.message && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground line-clamp-2 mt-0.5", children: notification.message }),
11019
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground/70 mt-1", children: formatTimeAgo(notification.timestamp) })
11020
+ ] }),
11021
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 flex items-start gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
11022
+ Button,
11023
+ {
11024
+ variant: "ghost",
11025
+ size: "icon",
11026
+ className: "h-6 w-6 text-muted-foreground hover:text-destructive",
11027
+ onClick: (e) => {
11028
+ e.stopPropagation();
11029
+ onDismiss(notification.id);
11030
+ },
11031
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-3 h-3" })
11032
+ }
11033
+ ) })
11034
+ ]
11035
+ },
11036
+ notification.id
11037
+ );
11038
+ }) }) }),
11039
+ (hasMore || onClearAll) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-2 border-t border-border bg-muted/30", children: [
11040
+ hasMore && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
11041
+ "+",
11042
+ notifications.length - maxVisible,
11043
+ " more"
11044
+ ] }),
11045
+ onClearAll && notifications.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
11046
+ Button,
11047
+ {
11048
+ variant: "ghost",
11049
+ size: "sm",
11050
+ className: "h-7 px-2 text-xs text-muted-foreground hover:text-destructive",
11051
+ onClick: () => onClearAll(),
11052
+ children: [
11053
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-3 h-3 mr-1" }),
11054
+ "Clear all"
11055
+ ]
11056
+ }
11057
+ )
11058
+ ] })
11059
+ ] })
11060
+ ]
11061
+ }
11062
+ )
11063
+ ] });
11064
+ }
9531
11065
 
11066
+ exports.AvatarEditor = AvatarEditor;
11067
+ exports.AvatarEditorDialog = AvatarEditorDialog;
9532
11068
  exports.Button = Button;
11069
+ exports.Dialog = Dialog;
11070
+ exports.DialogClose = DialogClose;
11071
+ exports.DialogContent = DialogContent;
11072
+ exports.DialogDescription = DialogDescription;
11073
+ exports.DialogFooter = DialogFooter;
11074
+ exports.DialogHeader = DialogHeader;
11075
+ exports.DialogOverlay = DialogOverlay;
11076
+ exports.DialogPortal = DialogPortal;
11077
+ exports.DialogTitle = DialogTitle;
11078
+ exports.DialogTrigger = DialogTrigger;
11079
+ exports.Drawer = Drawer;
11080
+ exports.DrawerClose = DrawerClose;
11081
+ exports.DrawerContent = DrawerContent;
11082
+ exports.DrawerDescription = DrawerDescription;
11083
+ exports.DrawerFooter = DrawerFooter;
11084
+ exports.DrawerHeader = DrawerHeader;
11085
+ exports.DrawerOverlay = DrawerOverlay;
11086
+ exports.DrawerPortal = DrawerPortal;
11087
+ exports.DrawerTitle = DrawerTitle;
11088
+ exports.DrawerTrigger = DrawerTrigger;
9533
11089
  exports.DropdownMenu = DropdownMenu2;
9534
11090
  exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem2;
9535
11091
  exports.DropdownMenuContent = DropdownMenuContent2;
@@ -9546,12 +11102,22 @@ exports.DropdownMenuSubContent = DropdownMenuSubContent2;
9546
11102
  exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger2;
9547
11103
  exports.DropdownMenuTrigger = DropdownMenuTrigger2;
9548
11104
  exports.LanguageSwitcher = LanguageSwitcher;
11105
+ exports.NotificationsWidget = NotificationsWidget;
11106
+ exports.Popover = Popover;
11107
+ exports.PopoverAnchor = PopoverAnchor;
11108
+ exports.PopoverContent = PopoverContent;
11109
+ exports.PopoverTrigger = PopoverTrigger;
11110
+ exports.ScrollArea = ScrollArea;
11111
+ exports.ScrollBar = ScrollBar;
11112
+ exports.Slider = Slider;
9549
11113
  exports.ThemeSwitcher = ThemeSwitcher;
11114
+ exports.Toggle = Toggle;
9550
11115
  exports.Tooltip = Tooltip2;
9551
11116
  exports.TooltipContent = TooltipContent2;
9552
11117
  exports.TooltipProvider = TooltipProvider2;
9553
11118
  exports.TooltipTrigger = TooltipTrigger2;
9554
11119
  exports.buttonVariants = buttonVariants;
9555
11120
  exports.cn = cn;
11121
+ exports.toggleVariants = toggleVariants;
9556
11122
  //# sourceMappingURL=index.cjs.map
9557
11123
  //# sourceMappingURL=index.cjs.map