@inferencesh/ui 0.0.0-stage → 0.1.1

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 (165) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +68 -2
  3. package/components.json +22 -0
  4. package/package.json +231 -4
  5. package/src/components/audio-player.tsx +549 -0
  6. package/src/components/button.tsx +13 -0
  7. package/src/components/chart.tsx +403 -0
  8. package/src/components/circuit.tsx +276 -0
  9. package/src/components/code-block/code-block.tsx +260 -0
  10. package/src/components/code-block/index.ts +18 -0
  11. package/src/components/code-block/languages.ts +311 -0
  12. package/src/components/code-block/styles.ts +39 -0
  13. package/src/components/code-block/tokenizer.ts +290 -0
  14. package/src/components/code-block/types.ts +38 -0
  15. package/src/components/code-block/utils.ts +39 -0
  16. package/src/components/code.tsx +48 -0
  17. package/src/components/cookie-consent.tsx +137 -0
  18. package/src/components/copy-button.tsx +44 -0
  19. package/src/components/country-dropdown.tsx +188 -0
  20. package/src/components/glow-loader-fast.tsx +32 -0
  21. package/src/components/glow-loader-mono.tsx +33 -0
  22. package/src/components/glow-loader-sm-fast.tsx +32 -0
  23. package/src/components/glow-loader-sm-mono.tsx +34 -0
  24. package/src/components/glow-loader-sm.tsx +32 -0
  25. package/src/components/glow-loader.tsx +32 -0
  26. package/src/components/glow-logo.tsx +32 -0
  27. package/src/components/gradient.tsx +80 -0
  28. package/src/components/index.ts +45 -0
  29. package/src/components/inline-sidebar.tsx +351 -0
  30. package/src/components/input-color.tsx +349 -0
  31. package/src/components/logo-base.tsx +213 -0
  32. package/src/components/logo-color.tsx +23 -0
  33. package/src/components/logo-full.tsx +71 -0
  34. package/src/components/logo-svg.tsx +23 -0
  35. package/src/components/menu-navigation.tsx +359 -0
  36. package/src/components/multi-select.tsx +721 -0
  37. package/src/components/pastel-gradient.tsx +25 -0
  38. package/src/components/pixel-symmetry.tsx +151 -0
  39. package/src/components/progress.tsx +28 -0
  40. package/src/components/scroll-more.tsx +131 -0
  41. package/src/components/select.tsx +85 -0
  42. package/src/components/shimmering-text.tsx +108 -0
  43. package/src/components/sidebar-light.tsx +102 -0
  44. package/src/components/sonner.tsx +38 -0
  45. package/src/components/theme-switcher-sidebar.tsx +56 -0
  46. package/src/components/theme-switcher-simple.tsx +110 -0
  47. package/src/components/theme-switcher.tsx +47 -0
  48. package/src/components/toggle-group.tsx +55 -0
  49. package/src/components/tooltip-button.tsx +91 -0
  50. package/src/components/tooltip.tsx +71 -0
  51. package/src/components/tree-view.tsx +499 -0
  52. package/src/components/unglow-loader.tsx +33 -0
  53. package/src/components/waveform.tsx +1632 -0
  54. package/src/components/zoomable-image.tsx +76 -0
  55. package/src/docs/api-docs.tsx +763 -0
  56. package/src/docs/callout.tsx +160 -0
  57. package/src/docs/code-group.tsx +215 -0
  58. package/src/docs/copy-menu.tsx +143 -0
  59. package/src/docs/doc-tabs.tsx +84 -0
  60. package/src/docs/index.ts +16 -0
  61. package/src/docs/steps.tsx +105 -0
  62. package/src/docs/table-of-contents.tsx +174 -0
  63. package/src/examples/guide-markdown.ts +129 -0
  64. package/src/examples/index.ts +1153 -0
  65. package/src/global.d.ts +1 -0
  66. package/src/hooks/use-copy-to-clipboard.ts +36 -0
  67. package/src/hooks/use-mobile.ts +19 -0
  68. package/src/lib/display-name.ts +15 -0
  69. package/src/lib/example-input.ts +130 -0
  70. package/src/lib/plans.ts +44 -0
  71. package/src/lib/safe-content.ts +137 -0
  72. package/src/lib/schema.ts +320 -0
  73. package/src/lib/storage.ts +108 -0
  74. package/src/markdown/docs-markdown-renderer.tsx +518 -0
  75. package/src/markdown/helpers.ts +95 -0
  76. package/src/markdown/index.ts +24 -0
  77. package/src/markdown/markdown-renderer.tsx +232 -0
  78. package/src/markdown/youtube-embed.tsx +43 -0
  79. package/src/og/image.ts +312 -0
  80. package/src/og/index.tsx +430 -0
  81. package/src/og/query.ts +26 -0
  82. package/src/shadcn/accordion.tsx +71 -0
  83. package/src/shadcn/alert-dialog.tsx +187 -0
  84. package/src/shadcn/alert.tsx +75 -0
  85. package/src/shadcn/aspect-ratio.tsx +22 -0
  86. package/src/shadcn/attachment.tsx +207 -0
  87. package/src/shadcn/avatar.tsx +106 -0
  88. package/src/shadcn/badge.tsx +51 -0
  89. package/src/shadcn/breadcrumb.tsx +124 -0
  90. package/src/shadcn/bubble.tsx +127 -0
  91. package/src/shadcn/button-group.tsx +87 -0
  92. package/src/shadcn/button.tsx +57 -0
  93. package/src/shadcn/calendar.tsx +219 -0
  94. package/src/shadcn/card.tsx +102 -0
  95. package/src/shadcn/carousel.tsx +242 -0
  96. package/src/shadcn/chart.tsx +372 -0
  97. package/src/shadcn/checkbox.tsx +28 -0
  98. package/src/shadcn/collapsible.tsx +19 -0
  99. package/src/shadcn/combobox.tsx +297 -0
  100. package/src/shadcn/command.tsx +194 -0
  101. package/src/shadcn/context-menu.tsx +270 -0
  102. package/src/shadcn/dialog.tsx +158 -0
  103. package/src/shadcn/direction.tsx +4 -0
  104. package/src/shadcn/drawer.tsx +227 -0
  105. package/src/shadcn/dropdown-menu.tsx +265 -0
  106. package/src/shadcn/empty.tsx +103 -0
  107. package/src/shadcn/field.tsx +238 -0
  108. package/src/shadcn/form.tsx +173 -0
  109. package/src/shadcn/hover-card.tsx +50 -0
  110. package/src/shadcn/index.ts +53 -0
  111. package/src/shadcn/input-group.tsx +156 -0
  112. package/src/shadcn/input-otp.tsx +84 -0
  113. package/src/shadcn/input.tsx +19 -0
  114. package/src/shadcn/item.tsx +201 -0
  115. package/src/shadcn/kbd.tsx +26 -0
  116. package/src/shadcn/label.tsx +19 -0
  117. package/src/shadcn/marker.tsx +70 -0
  118. package/src/shadcn/menubar.tsx +278 -0
  119. package/src/shadcn/message-scroller.tsx +131 -0
  120. package/src/shadcn/message.tsx +91 -0
  121. package/src/shadcn/native-select.tsx +60 -0
  122. package/src/shadcn/navigation-menu.tsx +167 -0
  123. package/src/shadcn/pagination.tsx +130 -0
  124. package/src/shadcn/popover.tsx +87 -0
  125. package/src/shadcn/progress.tsx +82 -0
  126. package/src/shadcn/radio-group.tsx +35 -0
  127. package/src/shadcn/resizable.tsx +49 -0
  128. package/src/shadcn/scroll-area.tsx +52 -0
  129. package/src/shadcn/select.tsx +200 -0
  130. package/src/shadcn/separator.tsx +22 -0
  131. package/src/shadcn/sheet.tsx +136 -0
  132. package/src/shadcn/sidebar.tsx +721 -0
  133. package/src/shadcn/skeleton.tsx +13 -0
  134. package/src/shadcn/slider.tsx +51 -0
  135. package/src/shadcn/sonner.tsx +49 -0
  136. package/src/shadcn/spinner.tsx +10 -0
  137. package/src/shadcn/switch.tsx +29 -0
  138. package/src/shadcn/table.tsx +115 -0
  139. package/src/shadcn/tabs.tsx +79 -0
  140. package/src/shadcn/textarea.tsx +17 -0
  141. package/src/shadcn/toggle-group.tsx +89 -0
  142. package/src/shadcn/toggle.tsx +44 -0
  143. package/src/shadcn/tooltip.tsx +63 -0
  144. package/src/theme/config.ts +48 -0
  145. package/src/theme/css/base.css +92 -0
  146. package/src/theme/css/bitboy.css +75 -0
  147. package/src/theme/css/dark.css +47 -0
  148. package/src/theme/css/designer.css +122 -0
  149. package/src/theme/css/fonts.css +33 -0
  150. package/src/theme/css/globals.css +14 -0
  151. package/src/theme/css/hackintosh.css +57 -0
  152. package/src/theme/css/llama.css +103 -0
  153. package/src/theme/css/safelist.css +39 -0
  154. package/src/theme/css/shadcn.css +77 -0
  155. package/src/theme/css/theme.css +216 -0
  156. package/src/theme/embed-theme.ts +146 -0
  157. package/src/theme/fonts/FiraCode-VF.woff2 +0 -0
  158. package/src/theme/fonts/Hack-Regular.woff2 +0 -0
  159. package/src/theme/fonts/LICENSE-FiraCode.txt +93 -0
  160. package/src/theme/fonts/LICENSE-Hack.txt +45 -0
  161. package/src/theme/fonts/LICENSE-MonaSans.txt +93 -0
  162. package/src/theme/fonts/Mona-Sans.woff2 +0 -0
  163. package/src/theme/index.ts +15 -0
  164. package/src/utils/cn.ts +3 -0
  165. package/src/utils/index.ts +2 -0
@@ -0,0 +1,499 @@
1
+ 'use client'
2
+
3
+ import { cn } from "cn"
4
+ import { Accordion as AccordionPrimitive } from '@base-ui/react/accordion'
5
+ import { cva } from 'class-variance-authority'
6
+ import { ChevronRight } from 'lucide-react'
7
+ import React from 'react'
8
+
9
+ const treeVariants = cva(
10
+ 'group cursor-pointer hover:before:opacity-100 before:absolute before:rounded-lg before:left-0 px-4 before:w-full before:opacity-0 before:bg-accent/70 before:h-[2rem] before:-z-10'
11
+ )
12
+
13
+ const selectedTreeVariants = cva(
14
+ 'before:opacity-100 before:bg-accent/70 text-accent-foreground'
15
+ )
16
+
17
+ const dragOverVariants = cva(
18
+ 'before:opacity-100 before:bg-primary/20 text-primary-foreground'
19
+ )
20
+
21
+ type TreeIcon = React.ComponentType<{ className?: string }>
22
+
23
+ interface TreeDataItem {
24
+ id: string
25
+ name: string
26
+ icon?: TreeIcon
27
+ selectedIcon?: TreeIcon
28
+ openIcon?: TreeIcon
29
+ children?: TreeDataItem[]
30
+ actions?: React.ReactNode
31
+ onClick?: () => void
32
+ draggable?: boolean
33
+ droppable?: boolean
34
+ disabled?: boolean
35
+ }
36
+
37
+ type TreeProps = React.HTMLAttributes<HTMLDivElement> & {
38
+ data: TreeDataItem[] | TreeDataItem
39
+ initialSelectedItemId?: string
40
+ onSelectChange?: (item: TreeDataItem | undefined) => void
41
+ expandAll?: boolean
42
+ defaultNodeIcon?: TreeIcon
43
+ defaultLeafIcon?: TreeIcon
44
+ onDocumentDrag?: (sourceItem: TreeDataItem, targetItem: TreeDataItem) => void
45
+ selectedClassName?: string
46
+ }
47
+
48
+ const TreeView = React.forwardRef<HTMLDivElement, TreeProps>(
49
+ (
50
+ {
51
+ data,
52
+ initialSelectedItemId,
53
+ onSelectChange,
54
+ expandAll,
55
+ defaultLeafIcon,
56
+ defaultNodeIcon,
57
+ className,
58
+ onDocumentDrag,
59
+ selectedClassName,
60
+ ...props
61
+ },
62
+ ref
63
+ ) => {
64
+ const [selectedItemId, setSelectedItemId] = React.useState<
65
+ string | undefined
66
+ >(initialSelectedItemId)
67
+
68
+ const [draggedItem, setDraggedItem] = React.useState<TreeDataItem | null>(null)
69
+
70
+ const handleSelectChange = React.useCallback(
71
+ (item: TreeDataItem | undefined) => {
72
+ setSelectedItemId(item?.id)
73
+ if (onSelectChange) {
74
+ onSelectChange(item)
75
+ }
76
+ },
77
+ [onSelectChange]
78
+ )
79
+
80
+ const handleDragStart = React.useCallback((item: TreeDataItem) => {
81
+ setDraggedItem(item)
82
+ }, [])
83
+
84
+ const handleDrop = React.useCallback((targetItem: TreeDataItem) => {
85
+ if (draggedItem && onDocumentDrag && draggedItem.id !== targetItem.id) {
86
+ onDocumentDrag(draggedItem, targetItem)
87
+ }
88
+ setDraggedItem(null)
89
+ }, [draggedItem, onDocumentDrag])
90
+
91
+ const expandedItemIds = React.useMemo(() => {
92
+ if (!initialSelectedItemId) {
93
+ return [] as string[]
94
+ }
95
+
96
+ const ids: string[] = []
97
+
98
+ function walkTreeItems(
99
+ items: TreeDataItem[] | TreeDataItem,
100
+ targetId: string
101
+ ) {
102
+ if (items instanceof Array) {
103
+ for (let i = 0; i < items.length; i++) {
104
+ ids.push(items[i]!.id)
105
+ if (walkTreeItems(items[i]!, targetId) && !expandAll) {
106
+ return true
107
+ }
108
+ if (!expandAll) ids.pop()
109
+ }
110
+ } else if (!expandAll && items.id === targetId) {
111
+ return true
112
+ } else if (items.children) {
113
+ return walkTreeItems(items.children, targetId)
114
+ }
115
+ }
116
+
117
+ walkTreeItems(data, initialSelectedItemId)
118
+ return ids
119
+ }, [data, expandAll, initialSelectedItemId])
120
+
121
+ return (
122
+ <div className={cn('overflow-hidden relative', className)}>
123
+ <TreeItem
124
+ data={data}
125
+ ref={ref}
126
+ selectedItemId={selectedItemId}
127
+ handleSelectChange={handleSelectChange}
128
+ expandedItemIds={expandedItemIds}
129
+ defaultLeafIcon={defaultLeafIcon}
130
+ defaultNodeIcon={defaultNodeIcon}
131
+ handleDragStart={handleDragStart}
132
+ handleDrop={handleDrop}
133
+ draggedItem={draggedItem}
134
+ selectedClassName={selectedClassName}
135
+ {...props}
136
+ />
137
+ </div>
138
+ )
139
+ }
140
+ )
141
+ TreeView.displayName = 'TreeView'
142
+
143
+ type TreeItemProps = TreeProps & {
144
+ selectedItemId?: string
145
+ handleSelectChange: (item: TreeDataItem | undefined) => void
146
+ expandedItemIds: string[]
147
+ defaultNodeIcon?: TreeIcon
148
+ defaultLeafIcon?: TreeIcon
149
+ handleDragStart?: (item: TreeDataItem) => void
150
+ handleDrop?: (item: TreeDataItem) => void
151
+ draggedItem: TreeDataItem | null
152
+ selectedClassName?: string
153
+ }
154
+
155
+ const TreeItem = React.forwardRef<HTMLDivElement, TreeItemProps>(
156
+ (
157
+ {
158
+ className,
159
+ data,
160
+ selectedItemId,
161
+ handleSelectChange,
162
+ expandedItemIds,
163
+ defaultNodeIcon,
164
+ defaultLeafIcon,
165
+ handleDragStart,
166
+ handleDrop,
167
+ draggedItem,
168
+ selectedClassName,
169
+ ...props
170
+ },
171
+ ref
172
+ ) => {
173
+ if (!(data instanceof Array)) {
174
+ data = [data]
175
+ }
176
+ return (
177
+ <div ref={ref} role="tree" className={className} {...props}>
178
+ <ul>
179
+ {data.map((item) => (
180
+ <li key={item.id}>
181
+ {item.children ? (
182
+ <TreeNode
183
+ item={item}
184
+ selectedItemId={selectedItemId}
185
+ expandedItemIds={expandedItemIds}
186
+ handleSelectChange={handleSelectChange}
187
+ defaultNodeIcon={defaultNodeIcon}
188
+ defaultLeafIcon={defaultLeafIcon}
189
+ handleDragStart={handleDragStart}
190
+ handleDrop={handleDrop}
191
+ draggedItem={draggedItem}
192
+ selectedClassName={selectedClassName}
193
+ />
194
+ ) : (
195
+ <TreeLeaf
196
+ item={item}
197
+ selectedItemId={selectedItemId}
198
+ handleSelectChange={handleSelectChange}
199
+ defaultLeafIcon={defaultLeafIcon}
200
+ handleDragStart={handleDragStart}
201
+ handleDrop={handleDrop}
202
+ draggedItem={draggedItem}
203
+ selectedClassName={selectedClassName}
204
+ />
205
+ )}
206
+ </li>
207
+ ))}
208
+ </ul>
209
+ </div>
210
+ )
211
+ }
212
+ )
213
+ TreeItem.displayName = 'TreeItem'
214
+
215
+ const TreeNode = ({
216
+ item,
217
+ handleSelectChange,
218
+ expandedItemIds,
219
+ selectedItemId,
220
+ defaultNodeIcon,
221
+ defaultLeafIcon,
222
+ handleDragStart,
223
+ handleDrop,
224
+ draggedItem,
225
+ selectedClassName,
226
+ }: {
227
+ item: TreeDataItem
228
+ handleSelectChange: (item: TreeDataItem | undefined) => void
229
+ expandedItemIds: string[]
230
+ selectedItemId?: string
231
+ defaultNodeIcon?: TreeIcon
232
+ defaultLeafIcon?: TreeIcon
233
+ handleDragStart?: (item: TreeDataItem) => void
234
+ handleDrop?: (item: TreeDataItem) => void
235
+ draggedItem: TreeDataItem | null
236
+ selectedClassName?: string
237
+ }) => {
238
+ const [value, setValue] = React.useState<string[]>(
239
+ expandedItemIds.includes(item.id) ? [item.id] : []
240
+ )
241
+ const [isDragOver, setIsDragOver] = React.useState(false)
242
+
243
+ const onDragStart = (e: React.DragEvent) => {
244
+ if (!item.draggable) {
245
+ e.preventDefault()
246
+ return
247
+ }
248
+ e.dataTransfer.setData('text/plain', item.id)
249
+ handleDragStart?.(item)
250
+ }
251
+
252
+ const onDragOver = (e: React.DragEvent) => {
253
+ if (item.droppable !== false && draggedItem && draggedItem.id !== item.id) {
254
+ e.preventDefault()
255
+ setIsDragOver(true)
256
+ }
257
+ }
258
+
259
+ const onDragLeave = () => {
260
+ setIsDragOver(false)
261
+ }
262
+
263
+ const onDrop = (e: React.DragEvent) => {
264
+ e.preventDefault()
265
+ setIsDragOver(false)
266
+ handleDrop?.(item)
267
+ }
268
+
269
+ return (
270
+ <AccordionPrimitive.Root
271
+ multiple
272
+ value={value}
273
+ onValueChange={(s) => setValue(s as string[])}
274
+ >
275
+ <AccordionPrimitive.Item value={item.id}>
276
+ <TreeAccordionTrigger
277
+ className={cn(
278
+ treeVariants(),
279
+ selectedItemId === item.id && (selectedClassName || selectedTreeVariants()),
280
+ isDragOver && dragOverVariants()
281
+ )}
282
+ onClick={() => {
283
+ handleSelectChange(item)
284
+ item.onClick?.()
285
+ }}
286
+ draggable={!!item.draggable}
287
+ onDragStart={onDragStart}
288
+ onDragOver={onDragOver}
289
+ onDragLeave={onDragLeave}
290
+ onDrop={onDrop}
291
+ >
292
+ <TreeIconRenderer
293
+ item={item}
294
+ isSelected={selectedItemId === item.id}
295
+ isOpen={value.includes(item.id)}
296
+ default={defaultNodeIcon}
297
+ />
298
+ <span className="text-sm truncate">{item.name}</span>
299
+ <TreeActions isSelected={selectedItemId === item.id}>
300
+ {item.actions}
301
+ </TreeActions>
302
+ </TreeAccordionTrigger>
303
+ <TreeAccordionContent className="ml-5 border-l border-border">
304
+ <TreeItem
305
+ data={item.children ? item.children : item}
306
+ selectedItemId={selectedItemId}
307
+ handleSelectChange={handleSelectChange}
308
+ expandedItemIds={expandedItemIds}
309
+ defaultLeafIcon={defaultLeafIcon}
310
+ defaultNodeIcon={defaultNodeIcon}
311
+ handleDragStart={handleDragStart}
312
+ handleDrop={handleDrop}
313
+ draggedItem={draggedItem}
314
+ selectedClassName={selectedClassName}
315
+ />
316
+ </TreeAccordionContent>
317
+ </AccordionPrimitive.Item>
318
+ </AccordionPrimitive.Root>
319
+ )
320
+ }
321
+
322
+ const TreeLeaf = React.forwardRef<
323
+ HTMLDivElement,
324
+ React.HTMLAttributes<HTMLDivElement> & {
325
+ item: TreeDataItem
326
+ selectedItemId?: string
327
+ handleSelectChange: (item: TreeDataItem | undefined) => void
328
+ defaultLeafIcon?: TreeIcon
329
+ handleDragStart?: (item: TreeDataItem) => void
330
+ handleDrop?: (item: TreeDataItem) => void
331
+ draggedItem: TreeDataItem | null
332
+ selectedClassName?: string
333
+ }
334
+ >(
335
+ (
336
+ {
337
+ className,
338
+ item,
339
+ selectedItemId,
340
+ handleSelectChange,
341
+ defaultLeafIcon,
342
+ handleDragStart,
343
+ handleDrop,
344
+ draggedItem,
345
+ selectedClassName,
346
+ ...props
347
+ },
348
+ ref
349
+ ) => {
350
+ const [isDragOver, setIsDragOver] = React.useState(false)
351
+
352
+ const onDragStart = (e: React.DragEvent) => {
353
+ if (!item.draggable || item.disabled) {
354
+ e.preventDefault()
355
+ return
356
+ }
357
+ e.dataTransfer.setData('text/plain', item.id)
358
+ handleDragStart?.(item)
359
+ }
360
+
361
+ const onDragOver = (e: React.DragEvent) => {
362
+ if (item.droppable !== false && !item.disabled && draggedItem && draggedItem.id !== item.id) {
363
+ e.preventDefault()
364
+ setIsDragOver(true)
365
+ }
366
+ }
367
+
368
+ const onDragLeave = () => {
369
+ setIsDragOver(false)
370
+ }
371
+
372
+ const onDrop = (e: React.DragEvent) => {
373
+ if (item.disabled) return
374
+ e.preventDefault()
375
+ setIsDragOver(false)
376
+ handleDrop?.(item)
377
+ }
378
+
379
+ return (
380
+ <div
381
+ ref={ref}
382
+ className={cn(
383
+ 'flex text-left items-center py-2 cursor-pointer before:right-1',
384
+ treeVariants(),
385
+ className,
386
+ selectedItemId === item.id && (selectedClassName || selectedTreeVariants()),
387
+ isDragOver && dragOverVariants(),
388
+ item.disabled && 'opacity-50 cursor-not-allowed pointer-events-none'
389
+ )}
390
+ onClick={() => {
391
+ if (item.disabled) return
392
+ handleSelectChange(item)
393
+ item.onClick?.()
394
+ }}
395
+ draggable={!!item.draggable && !item.disabled}
396
+ onDragStart={onDragStart}
397
+ onDragOver={onDragOver}
398
+ onDragLeave={onDragLeave}
399
+ onDrop={onDrop}
400
+ {...props}
401
+ >
402
+ <TreeIconRenderer
403
+ item={item}
404
+ isSelected={selectedItemId === item.id}
405
+ default={defaultLeafIcon}
406
+ />
407
+ <span className="flex-grow text-sm truncate break-all whitespace-pre-wrap">{item.name}</span>
408
+ <TreeActions isSelected={selectedItemId === item.id && !item.disabled}>
409
+ {item.actions}
410
+ </TreeActions>
411
+ </div>
412
+ )
413
+ }
414
+ )
415
+ TreeLeaf.displayName = 'TreeLeaf'
416
+
417
+ const TreeAccordionTrigger = React.forwardRef<
418
+ HTMLElement,
419
+ AccordionPrimitive.Trigger.Props & React.HTMLAttributes<HTMLElement>
420
+ >(({ className, children, ...props }, ref) => (
421
+ <AccordionPrimitive.Header>
422
+ <AccordionPrimitive.Trigger
423
+ ref={ref}
424
+ className={cn(
425
+ 'flex flex-1 w-full items-center py-2 transition-all [&[data-panel-open]>svg:first-of-type]:rotate-90',
426
+ className
427
+ )}
428
+ {...props}
429
+ >
430
+ <ChevronRight className="h-4 w-4 shrink-0 transition-transform duration-200 text-accent-foreground/50 mr-1" />
431
+ {children}
432
+ </AccordionPrimitive.Trigger>
433
+ </AccordionPrimitive.Header>
434
+ ))
435
+ TreeAccordionTrigger.displayName = 'TreeAccordionTrigger'
436
+
437
+ const TreeAccordionContent = React.forwardRef<
438
+ HTMLDivElement,
439
+ AccordionPrimitive.Panel.Props
440
+ >(({ className, children, ...props }, ref) => (
441
+ <AccordionPrimitive.Panel
442
+ ref={ref}
443
+ className={cn(
444
+ 'overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up',
445
+ className
446
+ )}
447
+ {...props}
448
+ >
449
+ <div className="pb-1 pt-0"><span>{children}</span></div>
450
+ </AccordionPrimitive.Panel>
451
+ ))
452
+ TreeAccordionContent.displayName = 'TreeAccordionContent'
453
+
454
+ const TreeIconRenderer = ({
455
+ item,
456
+ isOpen,
457
+ isSelected,
458
+ default: defaultIcon
459
+ }: {
460
+ item: TreeDataItem
461
+ isOpen?: boolean
462
+ isSelected?: boolean
463
+ default?: TreeIcon
464
+ }) => {
465
+ let Icon = defaultIcon
466
+ if (isSelected && item.selectedIcon) {
467
+ Icon = item.selectedIcon
468
+ } else if (isOpen && item.openIcon) {
469
+ Icon = item.openIcon
470
+ } else if (item.icon) {
471
+ Icon = item.icon
472
+ }
473
+ return Icon ? (
474
+ <Icon className="h-4 w-4 shrink-0 mr-2" />
475
+ ) : (
476
+ <></>
477
+ )
478
+ }
479
+
480
+ const TreeActions = ({
481
+ children,
482
+ isSelected
483
+ }: {
484
+ children: React.ReactNode
485
+ isSelected: boolean
486
+ }) => {
487
+ return (
488
+ <div
489
+ className={cn(
490
+ isSelected ? 'block' : 'hidden',
491
+ 'absolute right-3 group-hover:block'
492
+ )}
493
+ >
494
+ {children}
495
+ </div>
496
+ )
497
+ }
498
+
499
+ export { TreeView, type TreeDataItem }
@@ -0,0 +1,33 @@
1
+ "use client";
2
+
3
+ import LogoBase from "./logo-base";
4
+
5
+ interface UnglowLoaderProps {
6
+ width?: number;
7
+ height?: number;
8
+ className?: string;
9
+ /** Custom color (CSS value like "hsl(var(--muted-foreground) / 0.2)") */
10
+ monoColor?: string;
11
+ strokeWidth?: number;
12
+ }
13
+
14
+ /**
15
+ * Static logo without animation or glow.
16
+ * Optionally pass monoColor for custom monochrome color.
17
+ */
18
+ const UnglowLoader = ({ width = 240, height = 240, className, monoColor, strokeWidth }: UnglowLoaderProps) => {
19
+ return (
20
+ <LogoBase
21
+ width={width}
22
+ height={height}
23
+ className={className}
24
+ strokeWidth={strokeWidth}
25
+ animated={false}
26
+ colored={monoColor ? false : true}
27
+ monoColor={monoColor}
28
+ withGlow={false}
29
+ />
30
+ );
31
+ };
32
+
33
+ export default UnglowLoader;