@foresthubai/workflow-builder 0.3.0 → 0.4.0

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 (120) hide show
  1. package/LICENSE +661 -661
  2. package/NOTICE +16 -16
  3. package/README.md +110 -93
  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/lib/utils.d.ts +3 -0
  11. package/dist/lib/utils.d.ts.map +1 -0
  12. package/dist/lib/utils.js +6 -0
  13. package/dist/lib/utils.js.map +1 -0
  14. package/dist/toolbars/CanvasTabsToolbar.d.ts +11 -0
  15. package/dist/toolbars/CanvasTabsToolbar.d.ts.map +1 -0
  16. package/dist/toolbars/CanvasTabsToolbar.js +101 -0
  17. package/dist/toolbars/CanvasTabsToolbar.js.map +1 -0
  18. package/package.json +2 -2
  19. package/src/BuilderLayout.tsx +345 -345
  20. package/src/Canvas.tsx +261 -261
  21. package/src/CanvasEditor.tsx +142 -142
  22. package/src/CanvasTabsToolbar.tsx +176 -176
  23. package/src/RightConfigPanel.tsx +266 -266
  24. package/src/WorkflowBuilder.tsx +412 -412
  25. package/src/cn.ts +6 -6
  26. package/src/components/ui/add-button.tsx +39 -39
  27. package/src/components/ui/alert-dialog.tsx +141 -141
  28. package/src/components/ui/alert.tsx +59 -59
  29. package/src/components/ui/badge.tsx +36 -36
  30. package/src/components/ui/button.tsx +85 -85
  31. package/src/components/ui/card.tsx +79 -79
  32. package/src/components/ui/checkbox.tsx +28 -28
  33. package/src/components/ui/collapsible.tsx +9 -9
  34. package/src/components/ui/command.tsx +153 -153
  35. package/src/components/ui/delete-button.tsx +23 -23
  36. package/src/components/ui/dialog.tsx +125 -125
  37. package/src/components/ui/dropdown-menu.tsx +198 -198
  38. package/src/components/ui/input.tsx +55 -55
  39. package/src/components/ui/label.tsx +24 -24
  40. package/src/components/ui/readonly-banner.tsx +15 -15
  41. package/src/components/ui/resizable.tsx +43 -43
  42. package/src/components/ui/scroll-area.tsx +102 -102
  43. package/src/components/ui/select.tsx +160 -160
  44. package/src/components/ui/separator.tsx +29 -29
  45. package/src/components/ui/switch.tsx +27 -27
  46. package/src/components/ui/textarea.tsx +51 -51
  47. package/src/components/ui/toast.tsx +127 -127
  48. package/src/components/ui/toaster.tsx +33 -33
  49. package/src/components/ui/toggle-group.tsx +59 -59
  50. package/src/components/ui/toggle.tsx +43 -43
  51. package/src/components/ui/tooltip.tsx +32 -32
  52. package/src/dialogs/NodePickerDialog.tsx +84 -84
  53. package/src/dialogs/ValidationDialog.tsx +184 -184
  54. package/src/graph/BaseNode.tsx +557 -557
  55. package/src/graph/CustomEdge.tsx +185 -185
  56. package/src/graph/CustomNode.tsx +16 -16
  57. package/src/graph/FunctionCallNode.tsx +30 -30
  58. package/src/graph/PortHandle.tsx +189 -189
  59. package/src/graph/reactFlowRegistry.ts +26 -26
  60. package/src/hooks/use-toast.ts +125 -125
  61. package/src/hooks/useAvailableVariables.ts +20 -20
  62. package/src/hooks/useCanvasHistory.ts +22 -22
  63. package/src/hooks/useCanvasTabs.ts +168 -168
  64. package/src/hooks/useFunctionDiagnosticsSync.ts +40 -40
  65. package/src/hooks/useFunctionRegistry.ts +26 -26
  66. package/src/hooks/useFunctions.ts +44 -44
  67. package/src/hooks/useGraph.ts +161 -161
  68. package/src/hooks/useNodeDefinitions.ts +82 -82
  69. package/src/hooks/useParamErrors.ts +26 -26
  70. package/src/hooks/useResolvedTheme.ts +30 -30
  71. package/src/hooks/useResourceDiagnosticsSync.ts +58 -58
  72. package/src/hooks/useSuppressThemeTransition.ts +79 -79
  73. package/src/hooks/useWorkflowSerialization.ts +127 -127
  74. package/src/i18n/index.ts +53 -53
  75. package/src/i18n/locales/de.json +501 -501
  76. package/src/i18n/locales/en.json +557 -557
  77. package/src/index.ts +27 -27
  78. package/src/inputs/ExpressionInput.tsx +297 -297
  79. package/src/inputs/ParameterEditor.tsx +515 -515
  80. package/src/inputs/PortSection.tsx +144 -144
  81. package/src/panels/BuilderSidebar.tsx +301 -301
  82. package/src/panels/ChannelConfigPanel.tsx +49 -49
  83. package/src/panels/ChannelsPanel.tsx +28 -28
  84. package/src/panels/DebugConsolePanel.tsx +73 -73
  85. package/src/panels/DebugContextPanel.tsx +77 -77
  86. package/src/panels/DebugExternalIOPanel.tsx +180 -180
  87. package/src/panels/DiagnosticsPanel.tsx +170 -170
  88. package/src/panels/EdgeConfigPanel.tsx +104 -104
  89. package/src/panels/FunctionConfigPanel.tsx +179 -179
  90. package/src/panels/FunctionListPanel.tsx +45 -45
  91. package/src/panels/MemoryConfigPanel.tsx +55 -55
  92. package/src/panels/MemoryPanel.tsx +40 -40
  93. package/src/panels/ModelConfigPanel.tsx +41 -41
  94. package/src/panels/ModelsPanel.tsx +36 -36
  95. package/src/panels/NodeConfigPanel.tsx +630 -630
  96. package/src/panels/NodeLibrary.tsx +288 -288
  97. package/src/panels/ResourceConfigPanel.tsx +132 -132
  98. package/src/panels/ResourceListPanel.tsx +113 -113
  99. package/src/panels/VariableConfigPanel.tsx +161 -161
  100. package/src/panels/VariablesPanel.tsx +145 -145
  101. package/src/stores/canvasStore.test.ts +44 -44
  102. package/src/stores/canvasStore.ts +245 -245
  103. package/src/stores/debugStore.ts +74 -74
  104. package/src/stores/diagnosticsStore.ts +130 -130
  105. package/src/stores/editorStore.ts +202 -202
  106. package/src/styles/index.css +526 -526
  107. package/src/utils/categoryConstants.ts +26 -26
  108. package/src/utils/channelOperations.ts +86 -86
  109. package/src/utils/connectionRules.ts +137 -137
  110. package/src/utils/functionOperations.ts +179 -179
  111. package/src/utils/graphOperations.ts +550 -550
  112. package/src/utils/history.ts +207 -207
  113. package/src/utils/memoryOperations.ts +57 -57
  114. package/src/utils/migrateFunctionNodes.ts +107 -107
  115. package/src/utils/modelOperations.ts +55 -55
  116. package/src/utils/paramDisplay.ts +71 -71
  117. package/src/utils/resourceHelpers.ts +32 -32
  118. package/src/utils/translation.ts +28 -28
  119. package/src/utils/variableOperations.ts +75 -75
  120. package/tailwind-preset.ts +166 -166
@@ -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
+ }