@greatapps/common 1.1.789 → 1.1.790

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.
@@ -1,13 +1,32 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
3
4
  import * as DialogPrimitive from "@radix-ui/react-dialog";
4
5
  import { IconX } from "@tabler/icons-react";
5
6
  import { cn } from "../../../infra/utils/clsx";
6
7
  import { OverlayLayerContext, useDialogLayer, useOverlayLayer } from "./layers";
7
8
  function Dialog({
9
+ open,
10
+ defaultOpen,
11
+ onOpenChange,
8
12
  ...props
9
13
  }) {
10
- return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
14
+ const [openState, setOpenState] = React.useState(defaultOpen ?? false);
15
+ const layer = useOverlayLayer(open ?? openState);
16
+ const handleOpenChange = (next) => {
17
+ setOpenState(next);
18
+ onOpenChange?.(next);
19
+ };
20
+ return /* @__PURE__ */ jsx(OverlayLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsx(
21
+ DialogPrimitive.Root,
22
+ {
23
+ "data-slot": "dialog",
24
+ open,
25
+ defaultOpen,
26
+ onOpenChange: handleOpenChange,
27
+ ...props
28
+ }
29
+ ) });
11
30
  }
12
31
  function DialogTrigger({
13
32
  ...props
@@ -50,13 +69,12 @@ function DialogContent({
50
69
  hideOverlay = false,
51
70
  ...props
52
71
  }) {
53
- const { layer, presenceRef } = useOverlayLayer();
54
- return /* @__PURE__ */ jsx(OverlayLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
72
+ const layer = useDialogLayer();
73
+ return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
55
74
  !hideOverlay && /* @__PURE__ */ jsx(DialogOverlay, { className: overlayClassName }),
56
75
  /* @__PURE__ */ jsxs(
57
76
  DialogPrimitive.Content,
58
77
  {
59
- ref: presenceRef,
60
78
  "data-slot": "dialog-content",
61
79
  className: cn(
62
80
  "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%] 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 sm:max-w-lg",
@@ -80,7 +98,7 @@ function DialogContent({
80
98
  ]
81
99
  }
82
100
  )
83
- ] }) });
101
+ ] });
84
102
  }
85
103
  function DialogHeader({ className, ...props }) {
86
104
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/overlay/Dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from '@tabler/icons-react';\nimport { cn } from \"../../../infra/utils/clsx\";\nimport { OverlayLayerContext, useDialogLayer, useOverlayLayer } from \"./layers\";\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n const layer = useDialogLayer();\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"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 bg-black/50\",\n layer.overlay,\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n overlayClassName,\n hideOverlay = false,\n ...props\n}: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n overlayClassName?: string;\n hideOverlay?: boolean;\n}) {\n const { layer, presenceRef } = useOverlayLayer();\n return (\n <OverlayLayerContext.Provider value={layer}>\n <DialogPortal data-slot=\"dialog-portal\">\n {!hideOverlay && <DialogOverlay className={overlayClassName} />}\n <DialogPrimitive.Content\n ref={presenceRef}\n data-slot=\"dialog-content\"\n className={cn(\n \"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%] 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 sm:max-w-lg\",\n layer.content,\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <div className=\"absolute top-0.5 right-0\">\n <div className=\"p-4\">\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none\"\n >\n <IconX className=\"size-[18px]\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </div>\n </div>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n </OverlayLayerContext.Provider>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\n \"p-5 flex flex-col gap-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/overlay/Dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from '@tabler/icons-react';\nimport { cn } from \"../../../infra/utils/clsx\";\nimport { OverlayLayerContext, useDialogLayer, useOverlayLayer } from \"./layers\";\n\nfunction Dialog({\n open,\n defaultOpen,\n onOpenChange,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n const [openState, setOpenState] = React.useState(defaultOpen ?? false);\n const layer = useOverlayLayer(open ?? openState);\n\n const handleOpenChange = (next: boolean) => {\n setOpenState(next);\n onOpenChange?.(next);\n };\n\n return (\n <OverlayLayerContext.Provider value={layer}>\n <DialogPrimitive.Root\n data-slot=\"dialog\"\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n {...props}\n />\n </OverlayLayerContext.Provider>\n );\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n const layer = useDialogLayer();\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"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 bg-black/50\",\n layer.overlay,\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n overlayClassName,\n hideOverlay = false,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n overlayClassName?: string;\n hideOverlay?: boolean;\n}) {\n const layer = useDialogLayer();\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n {!hideOverlay && <DialogOverlay className={overlayClassName} />}\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"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%] 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 sm:max-w-lg\",\n layer.content,\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <div className=\"absolute top-0.5 right-0\">\n <div className=\"p-4\">\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none\"\n >\n <IconX className=\"size-[18px]\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </div>\n </div>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\n \"p-5 flex flex-col gap-2 text-center sm:text-left\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n"],"mappings":"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","names":[]}
@@ -6,13 +6,26 @@ import { IconX } from "@tabler/icons-react";
6
6
  import { cn } from "../../../infra/utils/clsx";
7
7
  import { hideCrisp, showCrisp } from "../../embeds/CrispEmbed";
8
8
  import { OverlayLayerContext, useDialogLayer, useOverlayLayer } from "./layers";
9
- function Sheet({ onOpenChange, modal = false, ...props }) {
10
- const handleOpenChange = React.useCallback((open) => {
11
- if (open) hideCrisp();
9
+ function Sheet({ open, defaultOpen, onOpenChange, modal = false, ...props }) {
10
+ const [openState, setOpenState] = React.useState(defaultOpen ?? false);
11
+ const layer = useOverlayLayer(open ?? openState);
12
+ const handleOpenChange = React.useCallback((next) => {
13
+ if (next) hideCrisp();
12
14
  else showCrisp();
13
- onOpenChange?.(open);
15
+ setOpenState(next);
16
+ onOpenChange?.(next);
14
17
  }, [onOpenChange]);
15
- return /* @__PURE__ */ jsx(SheetPrimitive.Root, { "data-slot": "sheet", modal, onOpenChange: handleOpenChange, ...props });
18
+ return /* @__PURE__ */ jsx(OverlayLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsx(
19
+ SheetPrimitive.Root,
20
+ {
21
+ "data-slot": "sheet",
22
+ modal,
23
+ open,
24
+ defaultOpen,
25
+ onOpenChange: handleOpenChange,
26
+ ...props
27
+ }
28
+ ) });
16
29
  }
17
30
  function SheetTrigger({
18
31
  ...props
@@ -55,13 +68,12 @@ function SheetContent({
55
68
  noAnimation = false,
56
69
  ...props
57
70
  }) {
58
- const { layer, presenceRef } = useOverlayLayer();
59
- return /* @__PURE__ */ jsx(OverlayLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsxs(SheetPortal, { children: [
71
+ const layer = useDialogLayer();
72
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
60
73
  /* @__PURE__ */ jsx(SheetOverlay, { className: noAnimation ? "!animate-none" : void 0 }),
61
74
  /* @__PURE__ */ jsxs(
62
75
  SheetPrimitive.Content,
63
76
  {
64
- ref: presenceRef,
65
77
  "data-slot": "sheet-content",
66
78
  onInteractOutside: (e) => e.preventDefault(),
67
79
  onPointerDownOutside: (e) => e.preventDefault(),
@@ -96,7 +108,7 @@ function SheetContent({
96
108
  ]
97
109
  }
98
110
  )
99
- ] }) });
111
+ ] });
100
112
  }
101
113
  function SheetHeader({ className, ...props }) {
102
114
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/overlay/Sheet.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from '@tabler/icons-react';\nimport { cn } from \"../../../infra/utils/clsx\";\nimport { hideCrisp, showCrisp } from \"../../embeds/CrispEmbed\";\nimport { OverlayLayerContext, useDialogLayer, useOverlayLayer } from \"./layers\";\n\nfunction Sheet({ onOpenChange, modal = false, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n const handleOpenChange = React.useCallback((open: boolean) => {\n if (open) hideCrisp();\n else showCrisp();\n onOpenChange?.(open);\n }, [onOpenChange]);\n\n return <SheetPrimitive.Root data-slot=\"sheet\" modal={modal} onOpenChange={handleOpenChange} {...props} />;\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n const layer = useDialogLayer();\n return (\n <SheetPrimitive.Close tabIndex={-1} asChild>\n <div\n data-slot=\"sheet-overlay\"\n className={cn(\n \"animate-in fade-in-0 fixed inset-0 bg-black/50 cursor-default\",\n layer.overlay,\n className,\n )}\n {...props}\n />\n </SheetPrimitive.Close>\n );\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n noAnimation = false,\n ...props\n}: React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n showCloseButton?: boolean;\n noAnimation?: boolean;\n}) {\n const { layer, presenceRef } = useOverlayLayer();\n return (\n <OverlayLayerContext.Provider value={layer}>\n <SheetPortal>\n <SheetOverlay className={noAnimation ? \"!animate-none\" : undefined} />\n <SheetPrimitive.Content\n ref={presenceRef}\n data-slot=\"sheet-content\"\n onInteractOutside={(e) => e.preventDefault()}\n onPointerDownOutside={(e) => e.preventDefault()}\n className={cn(\n \"bg-background fixed flex flex-col gap-4 shadow-lg\",\n layer.content,\n !noAnimation &&\n \"data-[state=open]:animate-in data-[state=closed]:animate-out transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n !noAnimation &&\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right\",\n !noAnimation &&\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left\",\n !noAnimation &&\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n !noAnimation &&\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n side === \"right\" &&\n \"inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" && \"inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" && \"inset-x-0 bottom-0 h-auto border-t\",\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className=\"absolute top-3 right-3 hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none\"\n >\n <IconX className=\"size-[18px]\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n </OverlayLayerContext.Provider>\n );\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/overlay/Sheet.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from '@tabler/icons-react';\nimport { cn } from \"../../../infra/utils/clsx\";\nimport { hideCrisp, showCrisp } from \"../../embeds/CrispEmbed\";\nimport { OverlayLayerContext, useDialogLayer, useOverlayLayer } from \"./layers\";\n\nfunction Sheet({ open, defaultOpen, onOpenChange, modal = false, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n const [openState, setOpenState] = React.useState(defaultOpen ?? false);\n const layer = useOverlayLayer(open ?? openState);\n\n const handleOpenChange = React.useCallback((next: boolean) => {\n if (next) hideCrisp();\n else showCrisp();\n setOpenState(next);\n onOpenChange?.(next);\n }, [onOpenChange]);\n\n return (\n <OverlayLayerContext.Provider value={layer}>\n <SheetPrimitive.Root\n data-slot=\"sheet\"\n modal={modal}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n {...props}\n />\n </OverlayLayerContext.Provider>\n );\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n const layer = useDialogLayer();\n return (\n <SheetPrimitive.Close tabIndex={-1} asChild>\n <div\n data-slot=\"sheet-overlay\"\n className={cn(\n \"animate-in fade-in-0 fixed inset-0 bg-black/50 cursor-default\",\n layer.overlay,\n className,\n )}\n {...props}\n />\n </SheetPrimitive.Close>\n );\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n noAnimation = false,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n showCloseButton?: boolean;\n noAnimation?: boolean;\n}) {\n const layer = useDialogLayer();\n return (\n <SheetPortal>\n <SheetOverlay className={noAnimation ? \"!animate-none\" : undefined} />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n onInteractOutside={(e) => e.preventDefault()}\n onPointerDownOutside={(e) => e.preventDefault()}\n className={cn(\n \"bg-background fixed flex flex-col gap-4 shadow-lg\",\n layer.content,\n !noAnimation &&\n \"data-[state=open]:animate-in data-[state=closed]:animate-out transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n !noAnimation &&\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right\",\n !noAnimation &&\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left\",\n !noAnimation &&\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top\",\n !noAnimation &&\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom\",\n side === \"right\" &&\n \"inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" && \"inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" && \"inset-x-0 bottom-0 h-auto border-t\",\n className,\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className=\"absolute top-3 right-3 hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none\"\n >\n <IconX className=\"size-[18px]\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n );\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n};\n"],"mappings":"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","names":[]}
@@ -14,35 +14,34 @@ const ROOT_LAYER = { overlay: "z-[1000]", content: "z-[1001]", popover: "z-[1002
14
14
  const openOverlays = /* @__PURE__ */ new Set();
15
15
  const overlayListeners = /* @__PURE__ */ new Set();
16
16
  let saturationWarned = false;
17
- function subscribeOverlays(onStoreChange) {
18
- overlayListeners.add(onStoreChange);
19
- return () => {
20
- overlayListeners.delete(onStoreChange);
21
- };
17
+ function notifyOverlays() {
18
+ overlayListeners.forEach((listener) => listener());
22
19
  }
23
- const OverlayLayerContext = React.createContext(ROOT_LAYER);
24
- function useOverlayLayer() {
25
- const token = React.useRef({});
26
- const rank = React.useSyncExternalStore(
27
- subscribeOverlays,
28
- () => Math.max(Array.from(openOverlays).indexOf(token.current), 0),
29
- () => 0
20
+ function warnOnSaturation() {
21
+ if (process.env.NODE_ENV === "production" || saturationWarned || openOverlays.size <= OVERLAY_LAYERS.length) return;
22
+ saturationWarned = true;
23
+ console.warn(
24
+ `[great-lib-common] ${openOverlays.size} overlays visiveis, mas a escala de z so tem ${OVERLAY_LAYERS.length} faixas. Deste nivel em diante todos dividem a ultima faixa e o overlay de cima cai sob o conteudo de baixo. Se o empilhamento for legitimo, adicione uma faixa em ui/overlay/layers.tsx.`
30
25
  );
31
- const presenceRef = React.useCallback(() => {
32
- openOverlays.add(token.current);
33
- overlayListeners.forEach((notify) => notify());
34
- if (process.env.NODE_ENV !== "production" && openOverlays.size > OVERLAY_LAYERS.length && !saturationWarned) {
35
- saturationWarned = true;
36
- console.warn(
37
- `[great-lib-common] ${openOverlays.size} overlays visiveis, mas a escala de z so tem ${OVERLAY_LAYERS.length} faixas. Deste nivel em diante todos dividem a ultima faixa e o overlay de cima cai sob o conteudo de baixo. Se o empilhamento for legitimo, adicione uma faixa em ui/overlay/layers.tsx.`
38
- );
39
- }
26
+ }
27
+ const OverlayLayerContext = React.createContext(ROOT_LAYER);
28
+ function useOverlayLayer(open) {
29
+ const [rank, setRank] = React.useState(0);
30
+ React.useLayoutEffect(() => {
31
+ if (!open) return;
32
+ const token = {};
33
+ const sync = () => setRank(Math.max(Array.from(openOverlays).indexOf(token), 0));
34
+ overlayListeners.add(sync);
35
+ openOverlays.add(token);
36
+ notifyOverlays();
37
+ warnOnSaturation();
40
38
  return () => {
41
- openOverlays.delete(token.current);
42
- overlayListeners.forEach((notify) => notify());
39
+ overlayListeners.delete(sync);
40
+ openOverlays.delete(token);
41
+ notifyOverlays();
43
42
  };
44
- }, []);
45
- return { layer: OVERLAY_LAYERS[Math.min(rank, OVERLAY_LAYERS.length - 1)], presenceRef };
43
+ }, [open]);
44
+ return OVERLAY_LAYERS[Math.min(rank, OVERLAY_LAYERS.length - 1)];
46
45
  }
47
46
  function useDialogLayer() {
48
47
  return React.useContext(OverlayLayerContext);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/overlay/layers.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nexport const OVERLAY_LAYERS = [\n { overlay: \"z-[1000]\", content: \"z-[1001]\", popover: \"z-[1002]\", tooltip: \"z-[1003]\" },\n { overlay: \"z-[1010]\", content: \"z-[1011]\", popover: \"z-[1012]\", tooltip: \"z-[1013]\" },\n { overlay: \"z-[1020]\", content: \"z-[1021]\", popover: \"z-[1022]\", tooltip: \"z-[1023]\" },\n { overlay: \"z-[1030]\", content: \"z-[1031]\", popover: \"z-[1032]\", tooltip: \"z-[1033]\" },\n { overlay: \"z-[1040]\", content: \"z-[1041]\", popover: \"z-[1042]\", tooltip: \"z-[1043]\" },\n { overlay: \"z-[1050]\", content: \"z-[1051]\", popover: \"z-[1052]\", tooltip: \"z-[1053]\" },\n { overlay: \"z-[1060]\", content: \"z-[1061]\", popover: \"z-[1062]\", tooltip: \"z-[1063]\" },\n { overlay: \"z-[1070]\", content: \"z-[1071]\", popover: \"z-[1072]\", tooltip: \"z-[1073]\" },\n] as const;\n\nexport const ROOT_LAYER = { overlay: \"z-[1000]\", content: \"z-[1001]\", popover: \"z-[1002]\", tooltip: \"z-50\" } as const;\n\nexport type DialogLayerClasses = (typeof OVERLAY_LAYERS)[number] | typeof ROOT_LAYER;\n\nconst openOverlays = new Set<object>();\nconst overlayListeners = new Set<() => void>();\nlet saturationWarned = false;\n\nfunction subscribeOverlays(onStoreChange: () => void) {\n overlayListeners.add(onStoreChange);\n return () => {\n overlayListeners.delete(onStoreChange);\n };\n}\n\nexport const OverlayLayerContext = React.createContext<DialogLayerClasses>(ROOT_LAYER);\n\nexport function useOverlayLayer() {\n const token = React.useRef({});\n const rank = React.useSyncExternalStore(\n subscribeOverlays,\n () => Math.max(Array.from(openOverlays).indexOf(token.current), 0),\n () => 0,\n );\n\n const presenceRef = React.useCallback(() => {\n openOverlays.add(token.current);\n overlayListeners.forEach((notify) => notify());\n if (process.env.NODE_ENV !== \"production\" && openOverlays.size > OVERLAY_LAYERS.length && !saturationWarned) {\n saturationWarned = true;\n console.warn(\n `[great-lib-common] ${openOverlays.size} overlays visiveis, mas a escala de z so tem ${OVERLAY_LAYERS.length} faixas. ` +\n `Deste nivel em diante todos dividem a ultima faixa e o overlay de cima cai sob o conteudo de baixo. ` +\n `Se o empilhamento for legitimo, adicione uma faixa em ui/overlay/layers.tsx.`,\n );\n }\n return () => {\n openOverlays.delete(token.current);\n overlayListeners.forEach((notify) => notify());\n };\n }, []);\n\n return { layer: OVERLAY_LAYERS[Math.min(rank, OVERLAY_LAYERS.length - 1)], presenceRef };\n}\n\nexport function useDialogLayer(): DialogLayerClasses {\n return React.useContext(OverlayLayerContext);\n}\n\nexport function DialogLayer({ children }: { children: React.ReactNode }) {\n return children;\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAEhB,MAAM,iBAAiB;AAAA,EAC5B,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AACvF;AAEO,MAAM,aAAa,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,OAAO;AAI3G,MAAM,eAAe,oBAAI,IAAY;AACrC,MAAM,mBAAmB,oBAAI,IAAgB;AAC7C,IAAI,mBAAmB;AAEvB,SAAS,kBAAkB,eAA2B;AACpD,mBAAiB,IAAI,aAAa;AAClC,SAAO,MAAM;AACX,qBAAiB,OAAO,aAAa;AAAA,EACvC;AACF;AAEO,MAAM,sBAAsB,MAAM,cAAkC,UAAU;AAE9E,SAAS,kBAAkB;AAChC,QAAM,QAAQ,MAAM,OAAO,CAAC,CAAC;AAC7B,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA,MAAM,KAAK,IAAI,MAAM,KAAK,YAAY,EAAE,QAAQ,MAAM,OAAO,GAAG,CAAC;AAAA,IACjE,MAAM;AAAA,EACR;AAEA,QAAM,cAAc,MAAM,YAAY,MAAM;AAC1C,iBAAa,IAAI,MAAM,OAAO;AAC9B,qBAAiB,QAAQ,CAAC,WAAW,OAAO,CAAC;AAC7C,QAAI,QAAQ,IAAI,aAAa,gBAAgB,aAAa,OAAO,eAAe,UAAU,CAAC,kBAAkB;AAC3G,yBAAmB;AACnB,cAAQ;AAAA,QACN,sBAAsB,aAAa,IAAI,gDAAgD,eAAe,MAAM;AAAA,MAG9G;AAAA,IACF;AACA,WAAO,MAAM;AACX,mBAAa,OAAO,MAAM,OAAO;AACjC,uBAAiB,QAAQ,CAAC,WAAW,OAAO,CAAC;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,EAAE,OAAO,eAAe,KAAK,IAAI,MAAM,eAAe,SAAS,CAAC,CAAC,GAAG,YAAY;AACzF;AAEO,SAAS,iBAAqC;AACnD,SAAO,MAAM,WAAW,mBAAmB;AAC7C;AAEO,SAAS,YAAY,EAAE,SAAS,GAAkC;AACvE,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/ui/overlay/layers.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nexport const OVERLAY_LAYERS = [\n { overlay: \"z-[1000]\", content: \"z-[1001]\", popover: \"z-[1002]\", tooltip: \"z-[1003]\" },\n { overlay: \"z-[1010]\", content: \"z-[1011]\", popover: \"z-[1012]\", tooltip: \"z-[1013]\" },\n { overlay: \"z-[1020]\", content: \"z-[1021]\", popover: \"z-[1022]\", tooltip: \"z-[1023]\" },\n { overlay: \"z-[1030]\", content: \"z-[1031]\", popover: \"z-[1032]\", tooltip: \"z-[1033]\" },\n { overlay: \"z-[1040]\", content: \"z-[1041]\", popover: \"z-[1042]\", tooltip: \"z-[1043]\" },\n { overlay: \"z-[1050]\", content: \"z-[1051]\", popover: \"z-[1052]\", tooltip: \"z-[1053]\" },\n { overlay: \"z-[1060]\", content: \"z-[1061]\", popover: \"z-[1062]\", tooltip: \"z-[1063]\" },\n { overlay: \"z-[1070]\", content: \"z-[1071]\", popover: \"z-[1072]\", tooltip: \"z-[1073]\" },\n] as const;\n\nexport const ROOT_LAYER = { overlay: \"z-[1000]\", content: \"z-[1001]\", popover: \"z-[1002]\", tooltip: \"z-50\" } as const;\n\nexport type DialogLayerClasses = (typeof OVERLAY_LAYERS)[number] | typeof ROOT_LAYER;\n\nconst openOverlays = new Set<object>();\nconst overlayListeners = new Set<() => void>();\nlet saturationWarned = false;\n\nfunction notifyOverlays() {\n overlayListeners.forEach((listener) => listener());\n}\n\nfunction warnOnSaturation() {\n if (process.env.NODE_ENV === \"production\" || saturationWarned || openOverlays.size <= OVERLAY_LAYERS.length) return;\n saturationWarned = true;\n console.warn(\n `[great-lib-common] ${openOverlays.size} overlays visiveis, mas a escala de z so tem ${OVERLAY_LAYERS.length} faixas. ` +\n `Deste nivel em diante todos dividem a ultima faixa e o overlay de cima cai sob o conteudo de baixo. ` +\n `Se o empilhamento for legitimo, adicione uma faixa em ui/overlay/layers.tsx.`,\n );\n}\n\nexport const OverlayLayerContext = React.createContext<DialogLayerClasses>(ROOT_LAYER);\n\nexport function useOverlayLayer(open: boolean): DialogLayerClasses {\n const [rank, setRank] = React.useState(0);\n\n React.useLayoutEffect(() => {\n if (!open) return;\n\n const token = {};\n const sync = () => setRank(Math.max(Array.from(openOverlays).indexOf(token), 0));\n\n overlayListeners.add(sync);\n openOverlays.add(token);\n notifyOverlays();\n warnOnSaturation();\n\n return () => {\n overlayListeners.delete(sync);\n openOverlays.delete(token);\n notifyOverlays();\n };\n }, [open]);\n\n return OVERLAY_LAYERS[Math.min(rank, OVERLAY_LAYERS.length - 1)];\n}\n\nexport function useDialogLayer(): DialogLayerClasses {\n return React.useContext(OverlayLayerContext);\n}\n\nexport function DialogLayer({ children }: { children: React.ReactNode }) {\n return children;\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAEhB,MAAM,iBAAiB;AAAA,EAC5B,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AAAA,EACrF,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,WAAW;AACvF;AAEO,MAAM,aAAa,EAAE,SAAS,YAAY,SAAS,YAAY,SAAS,YAAY,SAAS,OAAO;AAI3G,MAAM,eAAe,oBAAI,IAAY;AACrC,MAAM,mBAAmB,oBAAI,IAAgB;AAC7C,IAAI,mBAAmB;AAEvB,SAAS,iBAAiB;AACxB,mBAAiB,QAAQ,CAAC,aAAa,SAAS,CAAC;AACnD;AAEA,SAAS,mBAAmB;AAC1B,MAAI,QAAQ,IAAI,aAAa,gBAAgB,oBAAoB,aAAa,QAAQ,eAAe,OAAQ;AAC7G,qBAAmB;AACnB,UAAQ;AAAA,IACN,sBAAsB,aAAa,IAAI,gDAAgD,eAAe,MAAM;AAAA,EAG9G;AACF;AAEO,MAAM,sBAAsB,MAAM,cAAkC,UAAU;AAE9E,SAAS,gBAAgB,MAAmC;AACjE,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,CAAC;AAExC,QAAM,gBAAgB,MAAM;AAC1B,QAAI,CAAC,KAAM;AAEX,UAAM,QAAQ,CAAC;AACf,UAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,YAAY,EAAE,QAAQ,KAAK,GAAG,CAAC,CAAC;AAE/E,qBAAiB,IAAI,IAAI;AACzB,iBAAa,IAAI,KAAK;AACtB,mBAAe;AACf,qBAAiB;AAEjB,WAAO,MAAM;AACX,uBAAiB,OAAO,IAAI;AAC5B,mBAAa,OAAO,KAAK;AACzB,qBAAe;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,SAAO,eAAe,KAAK,IAAI,MAAM,eAAe,SAAS,CAAC,CAAC;AACjE;AAEO,SAAS,iBAAqC;AACnD,SAAO,MAAM,WAAW,mBAAmB;AAC7C;AAEO,SAAS,YAAY,EAAE,SAAS,GAAkC;AACvE,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.789",
3
+ "version": "1.1.790",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -46,12 +46,6 @@
46
46
  "dist",
47
47
  "src"
48
48
  ],
49
- "scripts": {
50
- "build": "tsup",
51
- "dev": "tsup --watch",
52
- "typecheck": "tsc --noEmit",
53
- "prepublishOnly": "npm run build"
54
- },
55
49
  "keywords": [],
56
50
  "author": "",
57
51
  "license": "ISC",
@@ -137,5 +131,10 @@
137
131
  "@faker-js/faker": {
138
132
  "optional": true
139
133
  }
134
+ },
135
+ "scripts": {
136
+ "build": "tsup",
137
+ "dev": "tsup --watch",
138
+ "typecheck": "tsc --noEmit"
140
139
  }
141
- }
140
+ }
@@ -7,9 +7,30 @@ import { cn } from "../../../infra/utils/clsx";
7
7
  import { OverlayLayerContext, useDialogLayer, useOverlayLayer } from "./layers";
8
8
 
9
9
  function Dialog({
10
+ open,
11
+ defaultOpen,
12
+ onOpenChange,
10
13
  ...props
11
14
  }: React.ComponentProps<typeof DialogPrimitive.Root>) {
12
- return <DialogPrimitive.Root data-slot="dialog" {...props} />;
15
+ const [openState, setOpenState] = React.useState(defaultOpen ?? false);
16
+ const layer = useOverlayLayer(open ?? openState);
17
+
18
+ const handleOpenChange = (next: boolean) => {
19
+ setOpenState(next);
20
+ onOpenChange?.(next);
21
+ };
22
+
23
+ return (
24
+ <OverlayLayerContext.Provider value={layer}>
25
+ <DialogPrimitive.Root
26
+ data-slot="dialog"
27
+ open={open}
28
+ defaultOpen={defaultOpen}
29
+ onOpenChange={handleOpenChange}
30
+ {...props}
31
+ />
32
+ </OverlayLayerContext.Provider>
33
+ );
13
34
  }
14
35
 
15
36
  function DialogTrigger({
@@ -55,43 +76,40 @@ function DialogContent({
55
76
  overlayClassName,
56
77
  hideOverlay = false,
57
78
  ...props
58
- }: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
79
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
59
80
  showCloseButton?: boolean;
60
81
  overlayClassName?: string;
61
82
  hideOverlay?: boolean;
62
83
  }) {
63
- const { layer, presenceRef } = useOverlayLayer();
84
+ const layer = useDialogLayer();
64
85
  return (
65
- <OverlayLayerContext.Provider value={layer}>
66
- <DialogPortal data-slot="dialog-portal">
67
- {!hideOverlay && <DialogOverlay className={overlayClassName} />}
68
- <DialogPrimitive.Content
69
- ref={presenceRef}
70
- data-slot="dialog-content"
71
- className={cn(
72
- "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%] 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 sm:max-w-lg",
73
- layer.content,
74
- className,
75
- )}
76
- {...props}
77
- >
78
- {children}
79
- {showCloseButton && (
80
- <div className="absolute top-0.5 right-0">
81
- <div className="p-4">
82
- <DialogPrimitive.Close
83
- data-slot="dialog-close"
84
- className="hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none"
85
- >
86
- <IconX className="size-[18px]" />
87
- <span className="sr-only">Close</span>
88
- </DialogPrimitive.Close>
89
- </div>
86
+ <DialogPortal data-slot="dialog-portal">
87
+ {!hideOverlay && <DialogOverlay className={overlayClassName} />}
88
+ <DialogPrimitive.Content
89
+ data-slot="dialog-content"
90
+ className={cn(
91
+ "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%] 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 sm:max-w-lg",
92
+ layer.content,
93
+ className,
94
+ )}
95
+ {...props}
96
+ >
97
+ {children}
98
+ {showCloseButton && (
99
+ <div className="absolute top-0.5 right-0">
100
+ <div className="p-4">
101
+ <DialogPrimitive.Close
102
+ data-slot="dialog-close"
103
+ className="hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none"
104
+ >
105
+ <IconX className="size-[18px]" />
106
+ <span className="sr-only">Close</span>
107
+ </DialogPrimitive.Close>
90
108
  </div>
91
- )}
92
- </DialogPrimitive.Content>
93
- </DialogPortal>
94
- </OverlayLayerContext.Provider>
109
+ </div>
110
+ )}
111
+ </DialogPrimitive.Content>
112
+ </DialogPortal>
95
113
  );
96
114
  }
97
115
 
@@ -7,14 +7,29 @@ import { cn } from "../../../infra/utils/clsx";
7
7
  import { hideCrisp, showCrisp } from "../../embeds/CrispEmbed";
8
8
  import { OverlayLayerContext, useDialogLayer, useOverlayLayer } from "./layers";
9
9
 
10
- function Sheet({ onOpenChange, modal = false, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
11
- const handleOpenChange = React.useCallback((open: boolean) => {
12
- if (open) hideCrisp();
10
+ function Sheet({ open, defaultOpen, onOpenChange, modal = false, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
11
+ const [openState, setOpenState] = React.useState(defaultOpen ?? false);
12
+ const layer = useOverlayLayer(open ?? openState);
13
+
14
+ const handleOpenChange = React.useCallback((next: boolean) => {
15
+ if (next) hideCrisp();
13
16
  else showCrisp();
14
- onOpenChange?.(open);
17
+ setOpenState(next);
18
+ onOpenChange?.(next);
15
19
  }, [onOpenChange]);
16
20
 
17
- return <SheetPrimitive.Root data-slot="sheet" modal={modal} onOpenChange={handleOpenChange} {...props} />;
21
+ return (
22
+ <OverlayLayerContext.Provider value={layer}>
23
+ <SheetPrimitive.Root
24
+ data-slot="sheet"
25
+ modal={modal}
26
+ open={open}
27
+ defaultOpen={defaultOpen}
28
+ onOpenChange={handleOpenChange}
29
+ {...props}
30
+ />
31
+ </OverlayLayerContext.Provider>
32
+ );
18
33
  }
19
34
 
20
35
  function SheetTrigger({
@@ -62,61 +77,58 @@ function SheetContent({
62
77
  showCloseButton = true,
63
78
  noAnimation = false,
64
79
  ...props
65
- }: React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content> & {
80
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
66
81
  side?: "top" | "right" | "bottom" | "left";
67
82
  showCloseButton?: boolean;
68
83
  noAnimation?: boolean;
69
84
  }) {
70
- const { layer, presenceRef } = useOverlayLayer();
85
+ const layer = useDialogLayer();
71
86
  return (
72
- <OverlayLayerContext.Provider value={layer}>
73
- <SheetPortal>
74
- <SheetOverlay className={noAnimation ? "!animate-none" : undefined} />
75
- <SheetPrimitive.Content
76
- ref={presenceRef}
77
- data-slot="sheet-content"
78
- onInteractOutside={(e) => e.preventDefault()}
79
- onPointerDownOutside={(e) => e.preventDefault()}
80
- className={cn(
81
- "bg-background fixed flex flex-col gap-4 shadow-lg",
82
- layer.content,
83
- !noAnimation &&
84
- "data-[state=open]:animate-in data-[state=closed]:animate-out transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
85
- !noAnimation &&
86
- side === "right" &&
87
- "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
88
- !noAnimation &&
89
- side === "left" &&
90
- "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
91
- !noAnimation &&
92
- side === "top" &&
93
- "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
94
- !noAnimation &&
95
- side === "bottom" &&
96
- "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
87
+ <SheetPortal>
88
+ <SheetOverlay className={noAnimation ? "!animate-none" : undefined} />
89
+ <SheetPrimitive.Content
90
+ data-slot="sheet-content"
91
+ onInteractOutside={(e) => e.preventDefault()}
92
+ onPointerDownOutside={(e) => e.preventDefault()}
93
+ className={cn(
94
+ "bg-background fixed flex flex-col gap-4 shadow-lg",
95
+ layer.content,
96
+ !noAnimation &&
97
+ "data-[state=open]:animate-in data-[state=closed]:animate-out transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
98
+ !noAnimation &&
97
99
  side === "right" &&
98
- "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
100
+ "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
101
+ !noAnimation &&
99
102
  side === "left" &&
100
- "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
101
- side === "top" && "inset-x-0 top-0 h-auto border-b",
102
- side === "bottom" && "inset-x-0 bottom-0 h-auto border-t",
103
- className,
104
- )}
105
- {...props}
106
- >
107
- {children}
108
- {showCloseButton && (
109
- <SheetPrimitive.Close
110
- data-slot="sheet-close"
111
- className="absolute top-3 right-3 hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none"
112
- >
113
- <IconX className="size-[18px]" />
114
- <span className="sr-only">Close</span>
115
- </SheetPrimitive.Close>
116
- )}
117
- </SheetPrimitive.Content>
118
- </SheetPortal>
119
- </OverlayLayerContext.Provider>
103
+ "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
104
+ !noAnimation &&
105
+ side === "top" &&
106
+ "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
107
+ !noAnimation &&
108
+ side === "bottom" &&
109
+ "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
110
+ side === "right" &&
111
+ "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
112
+ side === "left" &&
113
+ "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
114
+ side === "top" && "inset-x-0 top-0 h-auto border-b",
115
+ side === "bottom" && "inset-x-0 bottom-0 h-auto border-t",
116
+ className,
117
+ )}
118
+ {...props}
119
+ >
120
+ {children}
121
+ {showCloseButton && (
122
+ <SheetPrimitive.Close
123
+ data-slot="sheet-close"
124
+ className="absolute top-3 right-3 hover:cursor-pointer flex size-8 items-center justify-center rounded-lg p-2 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-950 focus:outline-none"
125
+ >
126
+ <IconX className="size-[18px]" />
127
+ <span className="sr-only">Close</span>
128
+ </SheetPrimitive.Close>
129
+ )}
130
+ </SheetPrimitive.Content>
131
+ </SheetPortal>
120
132
  );
121
133
  }
122
134
 
@@ -21,41 +21,44 @@ const openOverlays = new Set<object>();
21
21
  const overlayListeners = new Set<() => void>();
22
22
  let saturationWarned = false;
23
23
 
24
- function subscribeOverlays(onStoreChange: () => void) {
25
- overlayListeners.add(onStoreChange);
26
- return () => {
27
- overlayListeners.delete(onStoreChange);
28
- };
24
+ function notifyOverlays() {
25
+ overlayListeners.forEach((listener) => listener());
26
+ }
27
+
28
+ function warnOnSaturation() {
29
+ if (process.env.NODE_ENV === "production" || saturationWarned || openOverlays.size <= OVERLAY_LAYERS.length) return;
30
+ saturationWarned = true;
31
+ console.warn(
32
+ `[great-lib-common] ${openOverlays.size} overlays visiveis, mas a escala de z so tem ${OVERLAY_LAYERS.length} faixas. ` +
33
+ `Deste nivel em diante todos dividem a ultima faixa e o overlay de cima cai sob o conteudo de baixo. ` +
34
+ `Se o empilhamento for legitimo, adicione uma faixa em ui/overlay/layers.tsx.`,
35
+ );
29
36
  }
30
37
 
31
38
  export const OverlayLayerContext = React.createContext<DialogLayerClasses>(ROOT_LAYER);
32
39
 
33
- export function useOverlayLayer() {
34
- const token = React.useRef({});
35
- const rank = React.useSyncExternalStore(
36
- subscribeOverlays,
37
- () => Math.max(Array.from(openOverlays).indexOf(token.current), 0),
38
- () => 0,
39
- );
40
+ export function useOverlayLayer(open: boolean): DialogLayerClasses {
41
+ const [rank, setRank] = React.useState(0);
42
+
43
+ React.useLayoutEffect(() => {
44
+ if (!open) return;
45
+
46
+ const token = {};
47
+ const sync = () => setRank(Math.max(Array.from(openOverlays).indexOf(token), 0));
48
+
49
+ overlayListeners.add(sync);
50
+ openOverlays.add(token);
51
+ notifyOverlays();
52
+ warnOnSaturation();
40
53
 
41
- const presenceRef = React.useCallback(() => {
42
- openOverlays.add(token.current);
43
- overlayListeners.forEach((notify) => notify());
44
- if (process.env.NODE_ENV !== "production" && openOverlays.size > OVERLAY_LAYERS.length && !saturationWarned) {
45
- saturationWarned = true;
46
- console.warn(
47
- `[great-lib-common] ${openOverlays.size} overlays visiveis, mas a escala de z so tem ${OVERLAY_LAYERS.length} faixas. ` +
48
- `Deste nivel em diante todos dividem a ultima faixa e o overlay de cima cai sob o conteudo de baixo. ` +
49
- `Se o empilhamento for legitimo, adicione uma faixa em ui/overlay/layers.tsx.`,
50
- );
51
- }
52
54
  return () => {
53
- openOverlays.delete(token.current);
54
- overlayListeners.forEach((notify) => notify());
55
+ overlayListeners.delete(sync);
56
+ openOverlays.delete(token);
57
+ notifyOverlays();
55
58
  };
56
- }, []);
59
+ }, [open]);
57
60
 
58
- return { layer: OVERLAY_LAYERS[Math.min(rank, OVERLAY_LAYERS.length - 1)], presenceRef };
61
+ return OVERLAY_LAYERS[Math.min(rank, OVERLAY_LAYERS.length - 1)];
59
62
  }
60
63
 
61
64
  export function useDialogLayer(): DialogLayerClasses {