ai-design-system 0.1.51 → 0.1.53

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 (34) hide show
  1. package/components/ai-elements/file-tree.tsx +304 -0
  2. package/components/blocks/InboxPanel/InboxPanel.tsx +1 -1
  3. package/components/blocks/SectionLayout/SectionLayout.tsx +2 -0
  4. package/components/blocks/SectionLayout/interfaces.ts +1 -0
  5. package/components/composites/AdjustableLayout/AdjustableLayout.tsx +62 -40
  6. package/components/composites/FileTreeExplorer/FileTreeExplorer.stories.tsx +73 -0
  7. package/components/composites/FileTreeExplorer/FileTreeExplorer.tsx +95 -0
  8. package/components/composites/FileTreeExplorer/index.ts +8 -0
  9. package/components/composites/FormReports/FormReports.stories.tsx +33 -1
  10. package/components/composites/FormReports/FormReports.tsx +113 -0
  11. package/components/composites/FormReports/index.ts +8 -0
  12. package/components/composites/NavigationList/NavigationList.tsx +8 -1
  13. package/components/composites/NavigationList/interfaces.ts +1 -0
  14. package/components/composites/PromptInput/PromptInput.tsx +5 -1
  15. package/components/composites/index.ts +4 -0
  16. package/components/features/AIDocEditor/AIDocEditor.mocks.ts +10 -3
  17. package/components/features/AIDocEditor/AIDocEditor.stories.tsx +1 -0
  18. package/components/features/AIDocEditor/AIDocEditor.tsx +98 -22
  19. package/components/features/AIDocEditor/useAIDocEditor.d.ts +6 -0
  20. package/components/features/AIDocEditor/useAIDocEditor.mock.ts +56 -9
  21. package/components/features/RefinementPanel/RefinementPanel.tsx +7 -6
  22. package/components/features/WorkflowObservabilityFeature/WorkflowObservabilityFeature.tsx +14 -13
  23. package/components/index.ts +1 -1
  24. package/components/ui/collapsible.tsx +1 -1
  25. package/components/ui/command.tsx +2 -2
  26. package/components/ui/input-group.tsx +1 -1
  27. package/components/ui/popover.tsx +1 -1
  28. package/dist/index.cjs +526 -72
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.css +107 -75
  31. package/dist/index.d.ts +65 -19
  32. package/dist/index.js +527 -73
  33. package/dist/index.js.map +1 -1
  34. package/package.json +2 -1
@@ -0,0 +1,304 @@
1
+ "use client";
2
+
3
+ import {
4
+ Collapsible,
5
+ CollapsibleContent,
6
+ CollapsibleTrigger,
7
+ } from "@/components/ui/collapsible";
8
+ import { cn } from "@/lib/utils";
9
+ import {
10
+ ChevronRightIcon,
11
+ FileIcon,
12
+ FolderIcon,
13
+ FolderOpenIcon,
14
+ } from "lucide-react";
15
+ import type { HTMLAttributes, ReactNode } from "react";
16
+ import {
17
+ createContext,
18
+ useCallback,
19
+ useContext,
20
+ useMemo,
21
+ useState,
22
+ } from "react";
23
+
24
+ interface FileTreeContextType {
25
+ expandedPaths: Set<string>;
26
+ togglePath: (path: string) => void;
27
+ selectedPath?: string;
28
+ onSelect?: (path: string) => void;
29
+ }
30
+
31
+ // Default noop for context default value
32
+ // oxlint-disable-next-line eslint(no-empty-function)
33
+ const noop = () => {};
34
+
35
+ const FileTreeContext = createContext<FileTreeContextType>({
36
+ // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)
37
+ expandedPaths: new Set(),
38
+ togglePath: noop,
39
+ });
40
+
41
+ export type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> & {
42
+ expanded?: Set<string>;
43
+ defaultExpanded?: Set<string>;
44
+ selectedPath?: string;
45
+ onSelect?: (path: string) => void;
46
+ onExpandedChange?: (expanded: Set<string>) => void;
47
+ };
48
+
49
+ export const FileTree = ({
50
+ expanded: controlledExpanded,
51
+ defaultExpanded = new Set(),
52
+ selectedPath,
53
+ onSelect,
54
+ onExpandedChange,
55
+ className,
56
+ children,
57
+ ...props
58
+ }: FileTreeProps) => {
59
+ const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
60
+ const expandedPaths = controlledExpanded ?? internalExpanded;
61
+
62
+ const togglePath = useCallback(
63
+ (path: string) => {
64
+ const newExpanded = new Set(expandedPaths);
65
+ if (newExpanded.has(path)) {
66
+ newExpanded.delete(path);
67
+ } else {
68
+ newExpanded.add(path);
69
+ }
70
+ setInternalExpanded(newExpanded);
71
+ onExpandedChange?.(newExpanded);
72
+ },
73
+ [expandedPaths, onExpandedChange]
74
+ );
75
+
76
+ const contextValue = useMemo(
77
+ () => ({ expandedPaths, onSelect, selectedPath, togglePath }),
78
+ [expandedPaths, onSelect, selectedPath, togglePath]
79
+ );
80
+
81
+ return (
82
+ <FileTreeContext.Provider value={contextValue}>
83
+ <div
84
+ className={cn(
85
+ "rounded-lg border bg-background font-mono text-sm",
86
+ className
87
+ )}
88
+ role="tree"
89
+ {...props}
90
+ >
91
+ <div className="p-2">{children}</div>
92
+ </div>
93
+ </FileTreeContext.Provider>
94
+ );
95
+ };
96
+
97
+ export type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>;
98
+
99
+ export const FileTreeIcon = ({
100
+ className,
101
+ children,
102
+ ...props
103
+ }: FileTreeIconProps) => (
104
+ <span className={cn("shrink-0", className)} {...props}>
105
+ {children}
106
+ </span>
107
+ );
108
+
109
+ export type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>;
110
+
111
+ export const FileTreeName = ({
112
+ className,
113
+ children,
114
+ ...props
115
+ }: FileTreeNameProps) => (
116
+ <span className={cn("truncate", className)} {...props}>
117
+ {children}
118
+ </span>
119
+ );
120
+
121
+ interface FileTreeFolderContextType {
122
+ path: string;
123
+ name: string;
124
+ isExpanded: boolean;
125
+ }
126
+
127
+ const FileTreeFolderContext = createContext<FileTreeFolderContextType>({
128
+ isExpanded: false,
129
+ name: "",
130
+ path: "",
131
+ });
132
+
133
+ export type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {
134
+ path: string;
135
+ name: string;
136
+ };
137
+
138
+ export const FileTreeFolder = ({
139
+ path,
140
+ name,
141
+ className,
142
+ children,
143
+ ...props
144
+ }: FileTreeFolderProps) => {
145
+ const { expandedPaths, togglePath, selectedPath, onSelect } =
146
+ useContext(FileTreeContext);
147
+ const isExpanded = expandedPaths.has(path);
148
+ const isSelected = selectedPath === path;
149
+
150
+ const handleOpenChange = useCallback(() => {
151
+ togglePath(path);
152
+ }, [togglePath, path]);
153
+
154
+ const handleSelect = useCallback(() => {
155
+ onSelect?.(path);
156
+ }, [onSelect, path]);
157
+
158
+ const folderContextValue = useMemo(
159
+ () => ({ isExpanded, name, path }),
160
+ [isExpanded, name, path]
161
+ );
162
+
163
+ return (
164
+ <FileTreeFolderContext.Provider value={folderContextValue}>
165
+ <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>
166
+ <div
167
+ className={cn("", className)}
168
+ role="treeitem"
169
+ tabIndex={0}
170
+ {...props}
171
+ >
172
+ <div
173
+ className={cn(
174
+ "flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50",
175
+ isSelected && "bg-muted"
176
+ )}
177
+ >
178
+ <CollapsibleTrigger asChild>
179
+ <button
180
+ className="flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0"
181
+ type="button"
182
+ >
183
+ <ChevronRightIcon
184
+ className={cn(
185
+ "size-4 shrink-0 text-muted-foreground transition-transform",
186
+ isExpanded && "rotate-90"
187
+ )}
188
+ />
189
+ </button>
190
+ </CollapsibleTrigger>
191
+ <button
192
+ className="flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left"
193
+ onClick={handleSelect}
194
+ type="button"
195
+ >
196
+ <FileTreeIcon>
197
+ {isExpanded ? (
198
+ <FolderOpenIcon className="size-4 text-blue-500" />
199
+ ) : (
200
+ <FolderIcon className="size-4 text-blue-500" />
201
+ )}
202
+ </FileTreeIcon>
203
+ <FileTreeName>{name}</FileTreeName>
204
+ </button>
205
+ </div>
206
+ <CollapsibleContent>
207
+ <div className="ml-4 border-l pl-2">{children}</div>
208
+ </CollapsibleContent>
209
+ </div>
210
+ </Collapsible>
211
+ </FileTreeFolderContext.Provider>
212
+ );
213
+ };
214
+
215
+ interface FileTreeFileContextType {
216
+ path: string;
217
+ name: string;
218
+ }
219
+
220
+ const FileTreeFileContext = createContext<FileTreeFileContextType>({
221
+ name: "",
222
+ path: "",
223
+ });
224
+
225
+ export type FileTreeFileProps = HTMLAttributes<HTMLDivElement> & {
226
+ path: string;
227
+ name: string;
228
+ icon?: ReactNode;
229
+ };
230
+
231
+ export const FileTreeFile = ({
232
+ path,
233
+ name,
234
+ icon,
235
+ className,
236
+ children,
237
+ ...props
238
+ }: FileTreeFileProps) => {
239
+ const { selectedPath, onSelect } = useContext(FileTreeContext);
240
+ const isSelected = selectedPath === path;
241
+
242
+ const handleClick = useCallback(() => {
243
+ onSelect?.(path);
244
+ }, [onSelect, path]);
245
+
246
+ const handleKeyDown = useCallback(
247
+ (e: React.KeyboardEvent) => {
248
+ if (e.key === "Enter" || e.key === " ") {
249
+ onSelect?.(path);
250
+ }
251
+ },
252
+ [onSelect, path]
253
+ );
254
+
255
+ const fileContextValue = useMemo(() => ({ name, path }), [name, path]);
256
+
257
+ return (
258
+ <FileTreeFileContext.Provider value={fileContextValue}>
259
+ <div
260
+ className={cn(
261
+ "flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors hover:bg-muted/50",
262
+ isSelected && "bg-muted",
263
+ className
264
+ )}
265
+ onClick={handleClick}
266
+ onKeyDown={handleKeyDown}
267
+ role="treeitem"
268
+ tabIndex={0}
269
+ {...props}
270
+ >
271
+ {children ?? (
272
+ <>
273
+ {/* Spacer for alignment */}
274
+ <span className="size-4 shrink-0" />
275
+ <FileTreeIcon>
276
+ {icon ?? <FileIcon className="size-4 text-muted-foreground" />}
277
+ </FileTreeIcon>
278
+ <FileTreeName>{name}</FileTreeName>
279
+ </>
280
+ )}
281
+ </div>
282
+ </FileTreeFileContext.Provider>
283
+ );
284
+ };
285
+
286
+ export type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>;
287
+
288
+ const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
289
+
290
+ export const FileTreeActions = ({
291
+ className,
292
+ children,
293
+ ...props
294
+ }: FileTreeActionsProps) => (
295
+ <div
296
+ className={cn("ml-auto flex items-center gap-1", className)}
297
+ onClick={stopPropagation}
298
+ onKeyDown={stopPropagation}
299
+ role="group"
300
+ {...props}
301
+ >
302
+ {children}
303
+ </div>
304
+ );
@@ -40,7 +40,7 @@ export const InboxPanel = React.memo<InboxPanelProps>(
40
40
  </div>
41
41
  ) : null}
42
42
 
43
- <div className="px-4 pb-2">
43
+ <div className="px-4 pt-4 pb-2">
44
44
  <Input
45
45
  aria-label="Search inbox items"
46
46
  className="h-8"
@@ -21,6 +21,7 @@ export const SectionLayout = React.memo<SectionLayoutProps>(
21
21
  resizable = true,
22
22
  dragHandleColor = "border",
23
23
  className,
24
+ padded = true,
24
25
  ...props
25
26
  }) => {
26
27
  // Transform sections to include headers
@@ -47,6 +48,7 @@ export const SectionLayout = React.memo<SectionLayoutProps>(
47
48
  onSectionResize={onSectionResize}
48
49
  dragHandleColor={dragHandleColor}
49
50
  className={className}
51
+ padded={padded}
50
52
  {...props}
51
53
  />
52
54
  )
@@ -20,4 +20,5 @@ export interface SectionLayoutProps extends React.ComponentPropsWithoutRef<"div"
20
20
  onSectionResize?: (sectionId: string, newSize: number) => void;
21
21
  resizable?: boolean;
22
22
  dragHandleColor?: "primary" | "secondary" | "accent" | "border" | "muted";
23
+ padded?: boolean;
23
24
  }
@@ -18,6 +18,7 @@ export interface AdjustableLayoutProps extends React.ComponentPropsWithoutRef<"d
18
18
  storageKey?: string // localStorage key for persistence
19
19
  onSectionResize?: (sectionId: string, newSize: number) => void
20
20
  dragHandleColor?: "primary" | "secondary" | "accent" | "border" | "muted"
21
+ padded?: boolean
21
22
  }
22
23
 
23
24
  /**
@@ -28,19 +29,20 @@ export interface AdjustableLayoutProps extends React.ComponentPropsWithoutRef<"d
28
29
  * Supports localStorage persistence and responsive behavior.
29
30
  */
30
31
  export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
31
- ({
32
- sections,
33
- orientation = "horizontal",
32
+ ({
33
+ sections,
34
+ orientation = "horizontal",
34
35
  storageKey,
35
36
  onSectionResize,
36
37
  dragHandleColor = "border",
37
38
  className,
38
- ...props
39
+ padded = false,
40
+ ...props
39
41
  }) => {
40
42
  // Color mapping for drag handles
41
43
  const colorMap = {
42
44
  primary: "bg-primary hover:bg-primary/90",
43
- secondary: "bg-secondary hover:bg-secondary/80",
45
+ secondary: "bg-secondary hover:bg-secondary/80",
44
46
  accent: "bg-accent hover:bg-accent/80",
45
47
  border: "bg-border hover:bg-border/80",
46
48
  muted: "bg-muted hover:bg-muted/80"
@@ -49,7 +51,7 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
49
51
  const hoverColorMap = {
50
52
  primary: "group-hover:bg-primary/30",
51
53
  secondary: "group-hover:bg-secondary/30",
52
- accent: "group-hover:bg-accent/30",
54
+ accent: "group-hover:bg-accent/30",
53
55
  border: "group-hover:bg-border/30",
54
56
  muted: "group-hover:bg-muted/30"
55
57
  }
@@ -77,7 +79,7 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
77
79
  } catch {
78
80
  // ignore malformed storage
79
81
  }
80
- // eslint-disable-next-line react-hooks/exhaustive-deps
82
+ // eslint-disable-next-line react-hooks/exhaustive-deps
81
83
  }, [storageKey])
82
84
 
83
85
  const [draggingIndex, setDraggingIndex] = React.useState<number | null>(null)
@@ -119,33 +121,33 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
119
121
 
120
122
  const currentX = orientation === "horizontal" ? e.clientX : e.clientY
121
123
  const deltaX = currentX - startX
122
-
124
+
123
125
  const deltaPercent = (deltaX / containerSize) * 100
124
-
126
+
125
127
  const p1 = sections[draggingIndex]
126
128
  const p2 = sections[draggingIndex + 1]
127
-
129
+
128
130
  const p1Start = startSizes[draggingIndex]
129
131
  const p2Start = startSizes[draggingIndex + 1]
130
-
132
+
131
133
  const p1Min = p1.minSize ?? 10
132
134
  const p1Max = p1.maxSize ?? 80
133
135
  const p2Min = p2.minSize ?? 10
134
136
  const p2Max = p2.maxSize ?? 80
135
-
137
+
136
138
  // Calculate how much we can actually change panel 1
137
139
  // If deltaPercent > 0, we are growing p1 and shrinking p2
138
140
  const maxPositiveDelta = Math.max(0, Math.min(
139
141
  p1Max - p1Start, // Space p1 has to grow
140
142
  p2Start - p2Min // Space p2 has to shrink
141
143
  ))
142
-
144
+
143
145
  // If deltaPercent < 0, we are shrinking p1 and growing p2
144
146
  const maxNegativeDelta = Math.min(0, Math.max(
145
147
  p1Min - p1Start, // Space p1 has to shrink (negative)
146
148
  p2Start - p2Max // Space p2 has to grow (negative)
147
149
  ))
148
-
150
+
149
151
  // Clamp the delta
150
152
  let clampedDelta = deltaPercent
151
153
  if (clampedDelta > 0) {
@@ -153,17 +155,17 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
153
155
  } else {
154
156
  clampedDelta = Math.max(clampedDelta, maxNegativeDelta)
155
157
  }
156
-
158
+
157
159
  const newSizes = [...startSizes]
158
160
  newSizes[draggingIndex] = p1Start + clampedDelta
159
161
  newSizes[draggingIndex + 1] = p2Start - clampedDelta
160
-
162
+
161
163
  // Normalize to 100% just in case of floating point drift
162
164
  const total = newSizes.reduce((sum, size) => sum + size, 0)
163
165
  const normalizedSizes = newSizes.map(size => (size / total) * 100)
164
-
166
+
165
167
  setSizes(normalizedSizes)
166
-
168
+
167
169
  // Notify parent
168
170
  if (onSectionResize) {
169
171
  onSectionResize(sections[draggingIndex].id, normalizedSizes[draggingIndex])
@@ -201,12 +203,12 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
201
203
  ? { flex: `0 0 ${section.fixedSize}`, width: section.fixedSize, minWidth: section.fixedSize }
202
204
  : { flex: `0 0 ${section.fixedSize}`, height: section.fixedSize, minHeight: section.fixedSize }
203
205
  : null
204
-
206
+
205
207
  return (
206
208
  <React.Fragment key={section.id}>
207
209
  <div
208
210
  className={cn(
209
- "min-h-0 overflow-hidden bg-card border border-border rounded-md",
211
+ "min-h-0 overflow-hidden bg-card border border-border rounded-xl",
210
212
  section.className
211
213
  )}
212
214
  style={{
@@ -217,27 +219,46 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
217
219
  >
218
220
  {section.content}
219
221
  </div>
220
-
221
- {/* Show drag handle after this panel if it's not the last one */}
222
- {isResizable && (
223
- <div
224
- className={cn(
225
- `${colorMap[dragHandleColor]} flex-shrink-0 transition-colors duration-200 relative group`,
226
- orientation === "vertical"
227
- ? "cursor-row-resize h-1 w-full"
228
- : "cursor-col-resize w-1 h-full"
229
- )}
230
- onMouseDown={(e) => handleMouseDown(index, e)}
231
- >
232
- <div
222
+
223
+ {/* Show drag handle or spacer after this panel if it's not the last one */}
224
+ {index < sections.length - 1 && (
225
+ isResizable ? (
226
+ <div
227
+ className={cn(
228
+ "flex-shrink-0 flex items-center justify-center relative group",
229
+ orientation === "vertical"
230
+ ? "cursor-row-resize h-2 w-full"
231
+ : "cursor-col-resize w-2 h-full"
232
+ )}
233
+ onMouseDown={(e) => handleMouseDown(index, e)}
234
+ >
235
+ {/* Visible pill */}
236
+ <div
237
+ className={cn(
238
+ `${colorMap[dragHandleColor]} transition-colors duration-200 rounded-full`,
239
+ orientation === "vertical"
240
+ ? "h-1 w-8"
241
+ : "w-1 h-8"
242
+ )}
243
+ />
244
+ {/* Invisible large hit area */}
245
+ <div
246
+ className={cn(
247
+ "absolute z-10",
248
+ orientation === "vertical"
249
+ ? "inset-x-0 -top-2 -bottom-2"
250
+ : "inset-y-0 -left-2 -right-2"
251
+ )}
252
+ />
253
+ </div>
254
+ ) : (
255
+ <div
233
256
  className={cn(
234
- `absolute inset-0 ${hoverColorMap[dragHandleColor]}`,
235
- orientation === "vertical"
236
- ? "h-3 -translate-y-1"
237
- : "w-3 -translate-x-1"
238
- )}
257
+ "flex-shrink-0",
258
+ orientation === "vertical" ? "h-2 w-full" : "w-2 h-full"
259
+ )}
239
260
  />
240
- </div>
261
+ )
241
262
  )}
242
263
  </React.Fragment>
243
264
  )
@@ -248,12 +269,13 @@ export const AdjustableLayout = React.memo<AdjustableLayoutProps>(
248
269
  ref={containerRef}
249
270
  className={cn(
250
271
  "flex overflow-hidden h-full gap-1 min-w-0",
272
+ padded && "p-4",
251
273
  orientation === "horizontal" ? "flex-row" : "flex-col",
252
274
  className
253
275
  )}
254
276
  {...props}
255
277
  >
256
- {sections.map((section, index) =>
278
+ {sections.map((section, index) =>
257
279
  renderPanel(section, sizes[index], index)
258
280
  )}
259
281
  </div>
@@ -0,0 +1,73 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { fn } from '@storybook/test'
3
+ import { FileTreeExplorer } from './FileTreeExplorer'
4
+
5
+ const sampleTree = [
6
+ {
7
+ name: 'src',
8
+ path: 'src',
9
+ type: 'folder' as const,
10
+ children: [
11
+ {
12
+ name: 'components',
13
+ path: 'src/components',
14
+ type: 'folder' as const,
15
+ children: [
16
+ { name: 'Button.tsx', path: 'src/components/Button.tsx', type: 'file' as const },
17
+ { name: 'Input.tsx', path: 'src/components/Input.tsx', type: 'file' as const },
18
+ ],
19
+ },
20
+ {
21
+ name: 'hooks',
22
+ path: 'src/hooks',
23
+ type: 'folder' as const,
24
+ children: [
25
+ { name: 'use-toast.ts', path: 'src/hooks/use-toast.ts', type: 'file' as const },
26
+ ],
27
+ },
28
+ { name: 'index.ts', path: 'src/index.ts', type: 'file' as const },
29
+ ],
30
+ },
31
+ { name: 'package.json', path: 'package.json', type: 'file' as const },
32
+ ]
33
+
34
+ const meta = {
35
+ title: 'Composites/FileTreeExplorer',
36
+ component: FileTreeExplorer,
37
+ tags: ['autodocs'],
38
+ parameters: {
39
+ layout: 'padded',
40
+ },
41
+ } satisfies Meta<typeof FileTreeExplorer>
42
+
43
+ export default meta
44
+ type Story = StoryObj<typeof meta>
45
+
46
+ export const Default: Story = {
47
+ args: {
48
+ tree: sampleTree,
49
+ defaultExpanded: new Set(['src', 'src/components']),
50
+ selectedPath: 'src/components/Button.tsx',
51
+ onSelect: fn(),
52
+ createButtonLabel: 'New File',
53
+ },
54
+ }
55
+
56
+ export const Empty: Story = {
57
+ args: {
58
+ tree: [],
59
+ createButtonLabel: 'New File',
60
+ },
61
+ }
62
+
63
+ export const DarkMode: Story = {
64
+ args: {
65
+ tree: sampleTree,
66
+ defaultExpanded: new Set(['src']),
67
+ selectedPath: 'src/index.ts',
68
+ onSelect: fn(),
69
+ },
70
+ parameters: {
71
+ backgrounds: { disable: true },
72
+ },
73
+ }