@foresthubai/workflow-builder 0.4.2 → 0.4.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.
Files changed (123) hide show
  1. package/LICENSE +661 -661
  2. package/NOTICE +16 -16
  3. package/README.md +110 -110
  4. package/dist/components/ui/command.d.ts +2 -2
  5. package/dist/components/ui/input.d.ts +1 -1
  6. package/dist/components/ui/resizable.d.ts +1 -1
  7. package/dist/components/ui/textarea.d.ts +1 -1
  8. package/dist/graph/BaseNode.js +10 -10
  9. package/dist/graph/reactFlowRegistry.d.ts.map +1 -1
  10. package/dist/hooks/useWorkflowSerialization.d.ts.map +1 -1
  11. package/dist/hooks/useWorkflowSerialization.js +8 -11
  12. package/dist/hooks/useWorkflowSerialization.js.map +1 -1
  13. package/package.json +2 -2
  14. package/src/BuilderLayout.tsx +345 -345
  15. package/src/Canvas.tsx +261 -261
  16. package/src/CanvasEditor.tsx +142 -142
  17. package/src/CanvasTabsToolbar.tsx +176 -176
  18. package/src/RightConfigPanel.tsx +266 -266
  19. package/src/WorkflowBuilder.tsx +408 -408
  20. package/src/cn.ts +6 -6
  21. package/src/components/ui/add-button.tsx +39 -39
  22. package/src/components/ui/alert-dialog.tsx +141 -141
  23. package/src/components/ui/alert.tsx +59 -59
  24. package/src/components/ui/badge.tsx +36 -36
  25. package/src/components/ui/button.tsx +85 -85
  26. package/src/components/ui/card.tsx +79 -79
  27. package/src/components/ui/checkbox.tsx +28 -28
  28. package/src/components/ui/collapsible.tsx +9 -9
  29. package/src/components/ui/command.tsx +153 -153
  30. package/src/components/ui/delete-button.tsx +23 -23
  31. package/src/components/ui/dialog.tsx +125 -125
  32. package/src/components/ui/dropdown-menu.tsx +198 -198
  33. package/src/components/ui/input.tsx +55 -55
  34. package/src/components/ui/label.tsx +24 -24
  35. package/src/components/ui/readonly-banner.tsx +15 -15
  36. package/src/components/ui/resizable.tsx +43 -43
  37. package/src/components/ui/scroll-area.tsx +102 -102
  38. package/src/components/ui/select.tsx +160 -160
  39. package/src/components/ui/separator.tsx +29 -29
  40. package/src/components/ui/switch.tsx +27 -27
  41. package/src/components/ui/textarea.tsx +51 -51
  42. package/src/components/ui/toast.tsx +127 -127
  43. package/src/components/ui/toaster.tsx +33 -33
  44. package/src/components/ui/toggle-group.tsx +59 -59
  45. package/src/components/ui/toggle.tsx +43 -43
  46. package/src/components/ui/tooltip.tsx +32 -32
  47. package/src/dialogs/NodePickerDialog.tsx +84 -84
  48. package/src/dialogs/ValidationDialog.tsx +184 -184
  49. package/src/graph/BaseNode.tsx +557 -557
  50. package/src/graph/CustomEdge.tsx +185 -185
  51. package/src/graph/CustomNode.tsx +16 -16
  52. package/src/graph/FunctionCallNode.tsx +30 -30
  53. package/src/graph/PortHandle.tsx +189 -189
  54. package/src/graph/reactFlowRegistry.ts +26 -26
  55. package/src/hooks/use-toast.ts +125 -125
  56. package/src/hooks/useAvailableVariables.ts +20 -20
  57. package/src/hooks/useCanvasHistory.ts +22 -22
  58. package/src/hooks/useCanvasTabs.ts +168 -168
  59. package/src/hooks/useFunctionDiagnosticsSync.ts +40 -40
  60. package/src/hooks/useFunctionRegistry.ts +26 -26
  61. package/src/hooks/useFunctions.ts +44 -44
  62. package/src/hooks/useGraph.ts +161 -161
  63. package/src/hooks/useNodeDefinitions.ts +82 -82
  64. package/src/hooks/useParamErrors.ts +26 -26
  65. package/src/hooks/useResolvedTheme.ts +30 -30
  66. package/src/hooks/useResourceDiagnosticsSync.ts +58 -58
  67. package/src/hooks/useSuppressThemeTransition.ts +79 -79
  68. package/src/hooks/useWorkflowSerialization.ts +141 -144
  69. package/src/i18n/index.ts +53 -53
  70. package/src/i18n/locales/de.json +501 -501
  71. package/src/i18n/locales/en.json +557 -557
  72. package/src/index.ts +27 -27
  73. package/src/inputs/ExpressionInput.tsx +297 -297
  74. package/src/inputs/ParameterEditor.tsx +515 -515
  75. package/src/inputs/PortSection.tsx +144 -144
  76. package/src/panels/BuilderSidebar.tsx +301 -301
  77. package/src/panels/ChannelConfigPanel.tsx +49 -49
  78. package/src/panels/ChannelsPanel.tsx +28 -28
  79. package/src/panels/DebugConsolePanel.tsx +73 -73
  80. package/src/panels/DebugContextPanel.tsx +77 -77
  81. package/src/panels/DebugExternalIOPanel.tsx +180 -180
  82. package/src/panels/DiagnosticsPanel.tsx +170 -170
  83. package/src/panels/EdgeConfigPanel.tsx +104 -104
  84. package/src/panels/FunctionConfigPanel.tsx +179 -179
  85. package/src/panels/FunctionListPanel.tsx +45 -45
  86. package/src/panels/MemoryConfigPanel.tsx +55 -55
  87. package/src/panels/MemoryPanel.tsx +40 -40
  88. package/src/panels/ModelConfigPanel.tsx +41 -41
  89. package/src/panels/ModelsPanel.tsx +36 -36
  90. package/src/panels/NodeConfigPanel.tsx +630 -630
  91. package/src/panels/NodeLibrary.tsx +288 -288
  92. package/src/panels/ResourceConfigPanel.tsx +132 -132
  93. package/src/panels/ResourceListPanel.tsx +113 -113
  94. package/src/panels/VariableConfigPanel.tsx +161 -161
  95. package/src/panels/VariablesPanel.tsx +145 -145
  96. package/src/stores/canvasStore.test.ts +44 -44
  97. package/src/stores/canvasStore.ts +245 -245
  98. package/src/stores/debugStore.ts +74 -74
  99. package/src/stores/diagnosticsStore.ts +130 -130
  100. package/src/stores/editorStore.ts +190 -190
  101. package/src/styles/index.css +526 -526
  102. package/src/utils/categoryConstants.ts +26 -26
  103. package/src/utils/channelOperations.ts +86 -86
  104. package/src/utils/connectionRules.ts +137 -137
  105. package/src/utils/functionOperations.ts +179 -179
  106. package/src/utils/graphOperations.ts +550 -550
  107. package/src/utils/history.ts +207 -207
  108. package/src/utils/memoryOperations.ts +57 -57
  109. package/src/utils/migrateFunctionNodes.ts +107 -107
  110. package/src/utils/modelOperations.ts +55 -55
  111. package/src/utils/paramDisplay.ts +71 -71
  112. package/src/utils/resourceHelpers.ts +32 -32
  113. package/src/utils/translation.ts +28 -28
  114. package/src/utils/variableOperations.ts +75 -75
  115. package/tailwind-preset.ts +166 -166
  116. package/dist/lib/utils.d.ts +0 -3
  117. package/dist/lib/utils.d.ts.map +0 -1
  118. package/dist/lib/utils.js +0 -6
  119. package/dist/lib/utils.js.map +0 -1
  120. package/dist/toolbars/CanvasTabsToolbar.d.ts +0 -11
  121. package/dist/toolbars/CanvasTabsToolbar.d.ts.map +0 -1
  122. package/dist/toolbars/CanvasTabsToolbar.js +0 -101
  123. package/dist/toolbars/CanvasTabsToolbar.js.map +0 -1
@@ -1,153 +1,153 @@
1
- import * as React from "react"
2
- import { type DialogProps } from "@radix-ui/react-dialog"
3
- import { Command as CommandPrimitive } from "cmdk"
4
- import { Search } from "lucide-react"
5
-
6
- import { cn } from "../../cn"
7
- import { Dialog, DialogContent } from "./dialog"
8
-
9
- const Command = React.forwardRef<
10
- React.ElementRef<typeof CommandPrimitive>,
11
- React.ComponentPropsWithoutRef<typeof CommandPrimitive>
12
- >(({ className, ...props }, ref) => (
13
- <CommandPrimitive
14
- ref={ref}
15
- className={cn(
16
- "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
17
- className
18
- )}
19
- {...props}
20
- />
21
- ))
22
- Command.displayName = CommandPrimitive.displayName
23
-
24
- type CommandDialogProps = DialogProps;
25
-
26
- const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
27
- return (
28
- <Dialog {...props}>
29
- <DialogContent className="overflow-hidden p-0 shadow-lg">
30
- <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
31
- {children}
32
- </Command>
33
- </DialogContent>
34
- </Dialog>
35
- )
36
- }
37
-
38
- const CommandInput = React.forwardRef<
39
- React.ElementRef<typeof CommandPrimitive.Input>,
40
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
41
- >(({ className, ...props }, ref) => (
42
- <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
43
- <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
44
- <CommandPrimitive.Input
45
- ref={ref}
46
- className={cn(
47
- "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
48
- className
49
- )}
50
- {...props}
51
- />
52
- </div>
53
- ))
54
-
55
- CommandInput.displayName = CommandPrimitive.Input.displayName
56
-
57
- const CommandList = React.forwardRef<
58
- React.ElementRef<typeof CommandPrimitive.List>,
59
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
60
- >(({ className, ...props }, ref) => (
61
- <CommandPrimitive.List
62
- ref={ref}
63
- className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
64
- {...props}
65
- />
66
- ))
67
-
68
- CommandList.displayName = CommandPrimitive.List.displayName
69
-
70
- const CommandEmpty = React.forwardRef<
71
- React.ElementRef<typeof CommandPrimitive.Empty>,
72
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73
- >((props, ref) => (
74
- <CommandPrimitive.Empty
75
- ref={ref}
76
- className="py-6 text-center text-sm"
77
- {...props}
78
- />
79
- ))
80
-
81
- CommandEmpty.displayName = CommandPrimitive.Empty.displayName
82
-
83
- const CommandGroup = React.forwardRef<
84
- React.ElementRef<typeof CommandPrimitive.Group>,
85
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
86
- >(({ className, ...props }, ref) => (
87
- <CommandPrimitive.Group
88
- ref={ref}
89
- className={cn(
90
- "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
91
- className
92
- )}
93
- {...props}
94
- />
95
- ))
96
-
97
- CommandGroup.displayName = CommandPrimitive.Group.displayName
98
-
99
- const CommandSeparator = React.forwardRef<
100
- React.ElementRef<typeof CommandPrimitive.Separator>,
101
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
102
- >(({ className, ...props }, ref) => (
103
- <CommandPrimitive.Separator
104
- ref={ref}
105
- className={cn("-mx-1 h-px bg-border", className)}
106
- {...props}
107
- />
108
- ))
109
- CommandSeparator.displayName = CommandPrimitive.Separator.displayName
110
-
111
- const CommandItem = React.forwardRef<
112
- React.ElementRef<typeof CommandPrimitive.Item>,
113
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
114
- >(({ className, ...props }, ref) => (
115
- <CommandPrimitive.Item
116
- ref={ref}
117
- className={cn(
118
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-primary data-[disabled=true]:opacity-50",
119
- className
120
- )}
121
- {...props}
122
- />
123
- ))
124
-
125
- CommandItem.displayName = CommandPrimitive.Item.displayName
126
-
127
- const CommandShortcut = ({
128
- className,
129
- ...props
130
- }: React.HTMLAttributes<HTMLSpanElement>) => {
131
- return (
132
- <span
133
- className={cn(
134
- "ml-auto text-xs tracking-widest text-muted-foreground",
135
- className
136
- )}
137
- {...props}
138
- />
139
- )
140
- }
141
- CommandShortcut.displayName = "CommandShortcut"
142
-
143
- export {
144
- Command,
145
- CommandDialog,
146
- CommandInput,
147
- CommandList,
148
- CommandEmpty,
149
- CommandGroup,
150
- CommandItem,
151
- CommandShortcut,
152
- CommandSeparator,
153
- }
1
+ import * as React from "react"
2
+ import { type DialogProps } from "@radix-ui/react-dialog"
3
+ import { Command as CommandPrimitive } from "cmdk"
4
+ import { Search } from "lucide-react"
5
+
6
+ import { cn } from "../../cn"
7
+ import { Dialog, DialogContent } from "./dialog"
8
+
9
+ const Command = React.forwardRef<
10
+ React.ElementRef<typeof CommandPrimitive>,
11
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
12
+ >(({ className, ...props }, ref) => (
13
+ <CommandPrimitive
14
+ ref={ref}
15
+ className={cn(
16
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ ))
22
+ Command.displayName = CommandPrimitive.displayName
23
+
24
+ type CommandDialogProps = DialogProps;
25
+
26
+ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
27
+ return (
28
+ <Dialog {...props}>
29
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
30
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
31
+ {children}
32
+ </Command>
33
+ </DialogContent>
34
+ </Dialog>
35
+ )
36
+ }
37
+
38
+ const CommandInput = React.forwardRef<
39
+ React.ElementRef<typeof CommandPrimitive.Input>,
40
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
41
+ >(({ className, ...props }, ref) => (
42
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
43
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
44
+ <CommandPrimitive.Input
45
+ ref={ref}
46
+ className={cn(
47
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ </div>
53
+ ))
54
+
55
+ CommandInput.displayName = CommandPrimitive.Input.displayName
56
+
57
+ const CommandList = React.forwardRef<
58
+ React.ElementRef<typeof CommandPrimitive.List>,
59
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
60
+ >(({ className, ...props }, ref) => (
61
+ <CommandPrimitive.List
62
+ ref={ref}
63
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
64
+ {...props}
65
+ />
66
+ ))
67
+
68
+ CommandList.displayName = CommandPrimitive.List.displayName
69
+
70
+ const CommandEmpty = React.forwardRef<
71
+ React.ElementRef<typeof CommandPrimitive.Empty>,
72
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73
+ >((props, ref) => (
74
+ <CommandPrimitive.Empty
75
+ ref={ref}
76
+ className="py-6 text-center text-sm"
77
+ {...props}
78
+ />
79
+ ))
80
+
81
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName
82
+
83
+ const CommandGroup = React.forwardRef<
84
+ React.ElementRef<typeof CommandPrimitive.Group>,
85
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
86
+ >(({ className, ...props }, ref) => (
87
+ <CommandPrimitive.Group
88
+ ref={ref}
89
+ className={cn(
90
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
91
+ className
92
+ )}
93
+ {...props}
94
+ />
95
+ ))
96
+
97
+ CommandGroup.displayName = CommandPrimitive.Group.displayName
98
+
99
+ const CommandSeparator = React.forwardRef<
100
+ React.ElementRef<typeof CommandPrimitive.Separator>,
101
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
102
+ >(({ className, ...props }, ref) => (
103
+ <CommandPrimitive.Separator
104
+ ref={ref}
105
+ className={cn("-mx-1 h-px bg-border", className)}
106
+ {...props}
107
+ />
108
+ ))
109
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
110
+
111
+ const CommandItem = React.forwardRef<
112
+ React.ElementRef<typeof CommandPrimitive.Item>,
113
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
114
+ >(({ className, ...props }, ref) => (
115
+ <CommandPrimitive.Item
116
+ ref={ref}
117
+ className={cn(
118
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-primary data-[disabled=true]:opacity-50",
119
+ className
120
+ )}
121
+ {...props}
122
+ />
123
+ ))
124
+
125
+ CommandItem.displayName = CommandPrimitive.Item.displayName
126
+
127
+ const CommandShortcut = ({
128
+ className,
129
+ ...props
130
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
131
+ return (
132
+ <span
133
+ className={cn(
134
+ "ml-auto text-xs tracking-widest text-muted-foreground",
135
+ className
136
+ )}
137
+ {...props}
138
+ />
139
+ )
140
+ }
141
+ CommandShortcut.displayName = "CommandShortcut"
142
+
143
+ export {
144
+ Command,
145
+ CommandDialog,
146
+ CommandInput,
147
+ CommandList,
148
+ CommandEmpty,
149
+ CommandGroup,
150
+ CommandItem,
151
+ CommandShortcut,
152
+ CommandSeparator,
153
+ }
@@ -1,23 +1,23 @@
1
- import * as React from "react";
2
- import { Trash2 } from "lucide-react";
3
- import { Button, type ButtonProps } from "./button";
4
- import { cn } from "../../cn";
5
-
6
- type DeleteButtonProps = Omit<ButtonProps, "variant">;
7
-
8
- /**
9
- * The canonical full-width destructive delete button (trash icon + label) used at
10
- * the bottom of config panels. Spreads props (and forwards its ref) so it works
11
- * both with a direct `onClick` and as an `<AlertDialogTrigger asChild>` child.
12
- */
13
- const DeleteButton = React.forwardRef<HTMLButtonElement, DeleteButtonProps>(
14
- ({ className, children, ...props }, ref) => (
15
- <Button ref={ref} variant="destructive" className={cn("w-full", className)} {...props}>
16
- <Trash2 className="w-4 h-4 mr-2" />
17
- {children}
18
- </Button>
19
- ),
20
- );
21
- DeleteButton.displayName = "DeleteButton";
22
-
23
- export { DeleteButton };
1
+ import * as React from "react";
2
+ import { Trash2 } from "lucide-react";
3
+ import { Button, type ButtonProps } from "./button";
4
+ import { cn } from "../../cn";
5
+
6
+ type DeleteButtonProps = Omit<ButtonProps, "variant">;
7
+
8
+ /**
9
+ * The canonical full-width destructive delete button (trash icon + label) used at
10
+ * the bottom of config panels. Spreads props (and forwards its ref) so it works
11
+ * both with a direct `onClick` and as an `<AlertDialogTrigger asChild>` child.
12
+ */
13
+ const DeleteButton = React.forwardRef<HTMLButtonElement, DeleteButtonProps>(
14
+ ({ className, children, ...props }, ref) => (
15
+ <Button ref={ref} variant="destructive" className={cn("w-full", className)} {...props}>
16
+ <Trash2 className="w-4 h-4 mr-2" />
17
+ {children}
18
+ </Button>
19
+ ),
20
+ );
21
+ DeleteButton.displayName = "DeleteButton";
22
+
23
+ export { DeleteButton };
@@ -1,125 +1,125 @@
1
- import * as React from "react"
2
- import * as DialogPrimitive from "@radix-ui/react-dialog"
3
- import { X } from "lucide-react"
4
-
5
- import { cn } from "../../cn"
6
-
7
- const Dialog = DialogPrimitive.Root
8
-
9
- const DialogTrigger = DialogPrimitive.Trigger
10
-
11
- const DialogPortal = DialogPrimitive.Portal
12
-
13
- const DialogClose = DialogPrimitive.Close
14
-
15
- const DialogOverlay = React.forwardRef<
16
- React.ElementRef<typeof DialogPrimitive.Overlay>,
17
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
- >(({ className, ...props }, ref) => (
19
- <DialogPrimitive.Overlay
20
- ref={ref}
21
- className={cn(
22
- "fixed inset-0 z-50 bg-[hsl(var(--overlay))] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23
- className
24
- )}
25
- {...props}
26
- />
27
- ))
28
- DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
29
-
30
- const DialogContent = React.forwardRef<
31
- React.ElementRef<typeof DialogPrimitive.Content>,
32
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & { variant?: "surface" | "glass" | "inset" }
33
- >(({ className, children, variant = "surface", ...props }, ref) => (
34
- <DialogPortal>
35
- <DialogOverlay />
36
- <DialogPrimitive.Content
37
- ref={ref}
38
- className={cn(
39
- // font-sans + fh-builder-portal: portal content mounts on <body>, outside
40
- // .fh-builder, so it can't inherit the root font or pick up the
41
- // builder's themed scrollbar — pin both via explicit class markers.
42
- "fh-builder-portal font-sans fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
43
- variant === "glass" && "bg-background/80 backdrop-blur-md",
44
- variant === "inset" && "border-border/60",
45
- className
46
- )}
47
- {...props}
48
- >
49
- {children}
50
- <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
51
- <X className="h-4 w-4" />
52
- <span className="sr-only">Close</span>
53
- </DialogPrimitive.Close>
54
- </DialogPrimitive.Content>
55
- </DialogPortal>
56
- ))
57
- DialogContent.displayName = DialogPrimitive.Content.displayName
58
-
59
- const DialogHeader = ({
60
- className,
61
- ...props
62
- }: React.HTMLAttributes<HTMLDivElement>) => (
63
- <div
64
- className={cn(
65
- "flex flex-col space-y-1.5 text-center sm:text-left",
66
- className
67
- )}
68
- {...props}
69
- />
70
- )
71
- DialogHeader.displayName = "DialogHeader"
72
-
73
- const DialogFooter = ({
74
- className,
75
- ...props
76
- }: React.HTMLAttributes<HTMLDivElement>) => (
77
- <div
78
- className={cn(
79
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
80
- className
81
- )}
82
- {...props}
83
- />
84
- )
85
- DialogFooter.displayName = "DialogFooter"
86
-
87
- const DialogTitle = React.forwardRef<
88
- React.ElementRef<typeof DialogPrimitive.Title>,
89
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
90
- >(({ className, ...props }, ref) => (
91
- <DialogPrimitive.Title
92
- ref={ref}
93
- className={cn(
94
- "font-heading text-lg font-semibold leading-none tracking-tight",
95
- className
96
- )}
97
- {...props}
98
- />
99
- ))
100
- DialogTitle.displayName = DialogPrimitive.Title.displayName
101
-
102
- const DialogDescription = React.forwardRef<
103
- React.ElementRef<typeof DialogPrimitive.Description>,
104
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
105
- >(({ className, ...props }, ref) => (
106
- <DialogPrimitive.Description
107
- ref={ref}
108
- className={cn("text-sm text-muted-foreground", className)}
109
- {...props}
110
- />
111
- ))
112
- DialogDescription.displayName = DialogPrimitive.Description.displayName
113
-
114
- export {
115
- Dialog,
116
- DialogPortal,
117
- DialogOverlay,
118
- DialogClose,
119
- DialogTrigger,
120
- DialogContent,
121
- DialogHeader,
122
- DialogFooter,
123
- DialogTitle,
124
- DialogDescription,
125
- }
1
+ import * as React from "react"
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
3
+ import { X } from "lucide-react"
4
+
5
+ import { cn } from "../../cn"
6
+
7
+ const Dialog = DialogPrimitive.Root
8
+
9
+ const DialogTrigger = DialogPrimitive.Trigger
10
+
11
+ const DialogPortal = DialogPrimitive.Portal
12
+
13
+ const DialogClose = DialogPrimitive.Close
14
+
15
+ const DialogOverlay = React.forwardRef<
16
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => (
19
+ <DialogPrimitive.Overlay
20
+ ref={ref}
21
+ className={cn(
22
+ "fixed inset-0 z-50 bg-[hsl(var(--overlay))] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ ))
28
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
29
+
30
+ const DialogContent = React.forwardRef<
31
+ React.ElementRef<typeof DialogPrimitive.Content>,
32
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & { variant?: "surface" | "glass" | "inset" }
33
+ >(({ className, children, variant = "surface", ...props }, ref) => (
34
+ <DialogPortal>
35
+ <DialogOverlay />
36
+ <DialogPrimitive.Content
37
+ ref={ref}
38
+ className={cn(
39
+ // font-sans + fh-builder-portal: portal content mounts on <body>, outside
40
+ // .fh-builder, so it can't inherit the root font or pick up the
41
+ // builder's themed scrollbar — pin both via explicit class markers.
42
+ "fh-builder-portal font-sans fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
43
+ variant === "glass" && "bg-background/80 backdrop-blur-md",
44
+ variant === "inset" && "border-border/60",
45
+ className
46
+ )}
47
+ {...props}
48
+ >
49
+ {children}
50
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
51
+ <X className="h-4 w-4" />
52
+ <span className="sr-only">Close</span>
53
+ </DialogPrimitive.Close>
54
+ </DialogPrimitive.Content>
55
+ </DialogPortal>
56
+ ))
57
+ DialogContent.displayName = DialogPrimitive.Content.displayName
58
+
59
+ const DialogHeader = ({
60
+ className,
61
+ ...props
62
+ }: React.HTMLAttributes<HTMLDivElement>) => (
63
+ <div
64
+ className={cn(
65
+ "flex flex-col space-y-1.5 text-center sm:text-left",
66
+ className
67
+ )}
68
+ {...props}
69
+ />
70
+ )
71
+ DialogHeader.displayName = "DialogHeader"
72
+
73
+ const DialogFooter = ({
74
+ className,
75
+ ...props
76
+ }: React.HTMLAttributes<HTMLDivElement>) => (
77
+ <div
78
+ className={cn(
79
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
80
+ className
81
+ )}
82
+ {...props}
83
+ />
84
+ )
85
+ DialogFooter.displayName = "DialogFooter"
86
+
87
+ const DialogTitle = React.forwardRef<
88
+ React.ElementRef<typeof DialogPrimitive.Title>,
89
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
90
+ >(({ className, ...props }, ref) => (
91
+ <DialogPrimitive.Title
92
+ ref={ref}
93
+ className={cn(
94
+ "font-heading text-lg font-semibold leading-none tracking-tight",
95
+ className
96
+ )}
97
+ {...props}
98
+ />
99
+ ))
100
+ DialogTitle.displayName = DialogPrimitive.Title.displayName
101
+
102
+ const DialogDescription = React.forwardRef<
103
+ React.ElementRef<typeof DialogPrimitive.Description>,
104
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
105
+ >(({ className, ...props }, ref) => (
106
+ <DialogPrimitive.Description
107
+ ref={ref}
108
+ className={cn("text-sm text-muted-foreground", className)}
109
+ {...props}
110
+ />
111
+ ))
112
+ DialogDescription.displayName = DialogPrimitive.Description.displayName
113
+
114
+ export {
115
+ Dialog,
116
+ DialogPortal,
117
+ DialogOverlay,
118
+ DialogClose,
119
+ DialogTrigger,
120
+ DialogContent,
121
+ DialogHeader,
122
+ DialogFooter,
123
+ DialogTitle,
124
+ DialogDescription,
125
+ }