@gunjo/ui 0.0.1-alpha.1 → 0.0.1-alpha.2

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 (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +90 -0
  3. package/README.md +52 -91
  4. package/package.json +47 -6
  5. package/src/components/display/Accordion.tsx +185 -0
  6. package/src/components/display/AccordionGroup.tsx +155 -0
  7. package/src/components/display/ActionDataTable.tsx +413 -0
  8. package/src/components/display/ActivityTimelineCard.tsx +483 -0
  9. package/src/components/display/AnalyticsCard.tsx +167 -0
  10. package/src/components/display/AssetCard.tsx +242 -0
  11. package/src/components/display/AssetGrid.tsx +164 -0
  12. package/src/components/display/Avatar.tsx +127 -0
  13. package/src/components/display/AvatarGroup.tsx +131 -0
  14. package/src/components/{atoms → display}/Badge.tsx +3 -3
  15. package/src/components/display/BarChart.tsx +247 -0
  16. package/src/components/{molecules → display}/Card.tsx +1 -1
  17. package/src/components/display/Carousel.tsx +593 -0
  18. package/src/components/display/ChartLegend.tsx +124 -0
  19. package/src/components/display/ChatMessage.tsx +382 -0
  20. package/src/components/display/ChoroplethMap.tsx +613 -0
  21. package/src/components/display/Code.tsx +42 -0
  22. package/src/components/display/CodeBlock.tsx +338 -0
  23. package/src/components/display/ColorSwatch.tsx +71 -0
  24. package/src/components/display/ConcentricProgressCard.tsx +545 -0
  25. package/src/components/display/DataTable.tsx +522 -0
  26. package/src/components/display/DistributionBar.tsx +102 -0
  27. package/src/components/display/DocNote.tsx +36 -0
  28. package/src/components/display/DonutChart.tsx +257 -0
  29. package/src/components/display/EmptyState.tsx +44 -0
  30. package/src/components/display/FileTree.tsx +180 -0
  31. package/src/components/display/GaugeChart.tsx +219 -0
  32. package/src/components/display/HeatmapChart.tsx +266 -0
  33. package/src/components/display/Icon.tsx +66 -0
  34. package/src/components/display/ImagePreview.tsx +140 -0
  35. package/src/components/{atoms → display}/Img.tsx +46 -12
  36. package/src/components/display/LabeledDonutCard.tsx +475 -0
  37. package/src/components/display/LineChart.tsx +464 -0
  38. package/src/components/{molecules → display}/List.tsx +20 -13
  39. package/src/components/display/MarkdownRenderer.tsx +157 -0
  40. package/src/components/display/MetadataList.tsx +81 -0
  41. package/src/components/display/MiniDistributionBarCard.tsx +314 -0
  42. package/src/components/display/PieChart.tsx +234 -0
  43. package/src/components/display/QuadrantMatrix.tsx +330 -0
  44. package/src/components/display/RadarChart.tsx +335 -0
  45. package/src/components/display/RadialBarChart.tsx +264 -0
  46. package/src/components/display/RetentionCohortCard.tsx +350 -0
  47. package/src/components/display/RibbonChart.tsx +618 -0
  48. package/src/components/display/SearchableAccordion.tsx +270 -0
  49. package/src/components/display/SegmentTimelineCard.tsx +452 -0
  50. package/src/components/display/SegmentedGaugeCard.tsx +607 -0
  51. package/src/components/display/Spacer.tsx +51 -0
  52. package/src/components/display/SparklineChart.tsx +394 -0
  53. package/src/components/display/StackedBarChart.tsx +393 -0
  54. package/src/components/display/Statistic.tsx +70 -0
  55. package/src/components/{molecules → display}/Table.tsx +22 -7
  56. package/src/components/display/Tag.tsx +80 -0
  57. package/src/components/display/TagEditor.tsx +141 -0
  58. package/src/components/display/Timeline.tsx +121 -0
  59. package/src/components/{atoms → display}/ToolPill.tsx +42 -18
  60. package/src/components/display/TreeView.tsx +226 -0
  61. package/src/components/display/chart-tooltip.tsx +423 -0
  62. package/src/components/display/chart-utils.ts +71 -0
  63. package/src/components/display/circular-chart-utils.ts +147 -0
  64. package/src/components/display/generated/default-variant-keys.ts +90 -0
  65. package/src/components/display/generated/variant-keys.ts +169 -0
  66. package/src/components/{atoms → feedback}/Alert.tsx +12 -5
  67. package/src/components/feedback/Banner.tsx +90 -0
  68. package/src/components/{molecules → feedback}/NotificationCenter.tsx +64 -31
  69. package/src/components/feedback/ProgressWidget.tsx +44 -0
  70. package/src/components/{atoms → feedback}/Spinner.tsx +2 -2
  71. package/src/components/{molecules → feedback}/StatusBar.tsx +4 -4
  72. package/src/components/feedback/StatusScreen.tsx +148 -0
  73. package/src/components/{molecules → feedback}/Stepper.tsx +10 -5
  74. package/src/components/feedback/Toast.tsx +108 -0
  75. package/src/components/feedback/ToastProvider.tsx +78 -0
  76. package/src/components/feedback/generated/default-variant-keys.ts +16 -0
  77. package/src/components/feedback/generated/variant-keys.ts +21 -0
  78. package/src/components/generated/component-manifest.ts +1568 -454
  79. package/src/components/generated/component-style-hints.ts +1958 -718
  80. package/src/components/{atoms → inputs}/ButtonVariants.ts +13 -3
  81. package/src/components/inputs/Calendar.tsx +212 -0
  82. package/src/components/inputs/ChatComposer.tsx +75 -0
  83. package/src/components/inputs/ChatInput.tsx +528 -0
  84. package/src/components/{atoms → inputs}/Checkbox.tsx +2 -2
  85. package/src/components/inputs/Combobox.tsx +175 -0
  86. package/src/components/inputs/CopyButton.tsx +187 -0
  87. package/src/components/inputs/DatePicker.tsx +519 -0
  88. package/src/components/inputs/DateRangePicker.tsx +878 -0
  89. package/src/components/inputs/EditableField.tsx +182 -0
  90. package/src/components/{organisms → inputs}/FileUploader.tsx +24 -9
  91. package/src/components/inputs/FilterButton.tsx +163 -0
  92. package/src/components/{molecules → inputs}/Form.tsx +20 -3
  93. package/src/components/{atoms → inputs}/Input.tsx +2 -0
  94. package/src/components/inputs/InputOTP.tsx +75 -0
  95. package/src/components/inputs/Mention.tsx +279 -0
  96. package/src/components/inputs/NumberInput.tsx +109 -0
  97. package/src/components/inputs/PasswordGroup.tsx +138 -0
  98. package/src/components/inputs/PasswordInput.tsx +74 -0
  99. package/src/components/inputs/PasswordRequirementList.tsx +96 -0
  100. package/src/components/inputs/PasswordStrengthMeter.tsx +93 -0
  101. package/src/components/inputs/PhoneInput.tsx +99 -0
  102. package/src/components/inputs/PostalCodeInput.tsx +98 -0
  103. package/src/components/inputs/RangeSlider.tsx +129 -0
  104. package/src/components/inputs/SearchInput.tsx +76 -0
  105. package/src/components/inputs/Select.tsx +39 -0
  106. package/src/components/{atoms → inputs}/Slider.tsx +18 -5
  107. package/src/components/{molecules → inputs}/SortButton.tsx +5 -2
  108. package/src/components/{atoms → inputs}/Switch.tsx +15 -4
  109. package/src/components/inputs/TagInput.tsx +114 -0
  110. package/src/components/{atoms → inputs}/Textarea.tsx +1 -0
  111. package/src/components/inputs/TimePicker.tsx +150 -0
  112. package/src/components/inputs/Toggle.tsx +48 -0
  113. package/src/components/{atoms → inputs}/ToggleGroup.tsx +2 -2
  114. package/src/components/inputs/TooltipButton.tsx +148 -0
  115. package/src/components/inputs/VoiceInputButton.tsx +317 -0
  116. package/src/components/inputs/calendar-holidays.ts +56 -0
  117. package/src/components/inputs/generated/default-variant-keys.ts +32 -0
  118. package/src/components/{atoms → inputs}/generated/variant-keys.ts +19 -27
  119. package/src/components/layout/AspectRatio.tsx +12 -0
  120. package/src/components/layout/AssetInspectorPanel.tsx +416 -0
  121. package/src/components/layout/Cluster.tsx +56 -0
  122. package/src/components/layout/CollapsiblePanelToggle.tsx +94 -0
  123. package/src/components/layout/Container.tsx +43 -0
  124. package/src/components/layout/DeviceFrame.tsx +227 -0
  125. package/src/components/layout/Grid.tsx +65 -0
  126. package/src/components/layout/HStack.tsx +73 -0
  127. package/src/components/{organisms → layout}/InspectorPanel.tsx +6 -5
  128. package/src/components/layout/MarqueeFrame.tsx +158 -0
  129. package/src/components/layout/Resizable.tsx +94 -0
  130. package/src/components/layout/ScrollArea.tsx +71 -0
  131. package/src/components/{organisms → layout}/SpatialCanvas.tsx +12 -7
  132. package/src/components/layout/VStack.tsx +69 -0
  133. package/src/components/layout/generated/default-variant-keys.ts +16 -0
  134. package/src/components/layout/generated/variant-keys.ts +21 -0
  135. package/src/components/{molecules → navigation}/Breadcrumb.tsx +5 -4
  136. package/src/components/navigation/Command.tsx +266 -0
  137. package/src/components/navigation/CommandPalette.tsx +83 -0
  138. package/src/components/navigation/DocumentPager.tsx +171 -0
  139. package/src/components/navigation/Footer.tsx +88 -0
  140. package/src/components/navigation/Header.tsx +80 -0
  141. package/src/components/{molecules → navigation}/Menubar.tsx +45 -12
  142. package/src/components/navigation/NavigationMenu.tsx +128 -0
  143. package/src/components/navigation/PageAside.tsx +84 -0
  144. package/src/components/{molecules → navigation}/Pagination.tsx +60 -7
  145. package/src/components/{organisms → navigation}/RightRail.tsx +1 -1
  146. package/src/components/navigation/Sidebar.tsx +223 -0
  147. package/src/components/navigation/SidebarItem.tsx +160 -0
  148. package/src/components/{molecules → navigation}/Tabs.tsx +2 -2
  149. package/src/components/navigation/TextLink.tsx +71 -0
  150. package/src/components/navigation/generated/default-variant-keys.ts +12 -0
  151. package/src/components/navigation/generated/variant-keys.ts +13 -0
  152. package/src/components/overlay/AIChatInput.tsx +5 -0
  153. package/src/components/overlay/AIChatMessage.tsx +6 -0
  154. package/src/components/overlay/AlertDialog.tsx +145 -0
  155. package/src/components/overlay/ChatPanel.tsx +180 -0
  156. package/src/components/{molecules → overlay}/ContextMenu.tsx +65 -29
  157. package/src/components/{molecules → overlay}/Dialog.tsx +21 -13
  158. package/src/components/overlay/Drawer.tsx +131 -0
  159. package/src/components/{molecules → overlay}/DropdownMenu.tsx +52 -17
  160. package/src/components/overlay/FloatingPanel.tsx +90 -0
  161. package/src/components/overlay/HoverCard.tsx +36 -0
  162. package/src/components/overlay/MediaLightbox.tsx +403 -0
  163. package/src/components/overlay/MediaPickerDialog.tsx +198 -0
  164. package/src/components/overlay/Modal.tsx +103 -0
  165. package/src/components/overlay/OnboardingFlow.tsx +172 -0
  166. package/src/components/overlay/Popover.tsx +36 -0
  167. package/src/components/overlay/ShareModal.tsx +324 -0
  168. package/src/components/{molecules → overlay}/Sheet.tsx +76 -19
  169. package/src/components/overlay/Tooltip.tsx +130 -0
  170. package/src/components/overlay/generated/default-variant-keys.ts +14 -0
  171. package/src/components/overlay/generated/variant-keys.ts +17 -0
  172. package/src/components/patterns/BlogTemplate.tsx +46 -0
  173. package/src/components/{templates → patterns}/DashboardTemplate.tsx +2 -2
  174. package/src/components/patterns/DocsTemplate.tsx +41 -0
  175. package/src/components/{templates → patterns}/MediaLibraryTemplate.tsx +1 -1
  176. package/src/components/patterns/OnboardingTemplate.tsx +32 -0
  177. package/src/components/patterns/PricingTemplate.tsx +106 -0
  178. package/src/globals.css +173 -22
  179. package/src/index.ts +177 -76
  180. package/tailwind-theme-extend.cjs +48 -3
  181. package/design/atoms-metadata.json +0 -82
  182. package/design/molecules-metadata.json +0 -130
  183. package/design/organisms-metadata.json +0 -38
  184. package/design/templates-metadata.json +0 -38
  185. package/src/components/atoms/Avatar.tsx +0 -57
  186. package/src/components/atoms/Select.tsx +0 -28
  187. package/src/components/atoms/generated/default-variant-keys.ts +0 -36
  188. package/src/components/molecules/AIChatInput.tsx +0 -140
  189. package/src/components/molecules/AIChatMessage.tsx +0 -109
  190. package/src/components/molecules/Accordion.tsx +0 -99
  191. package/src/components/molecules/Calendar.tsx +0 -60
  192. package/src/components/molecules/Carousel.tsx +0 -261
  193. package/src/components/molecules/Command.tsx +0 -152
  194. package/src/components/molecules/FilterButton.tsx +0 -133
  195. package/src/components/molecules/HoverCard.tsx +0 -29
  196. package/src/components/molecules/Modal.tsx +0 -66
  197. package/src/components/molecules/Popover.tsx +0 -31
  198. package/src/components/molecules/ProgressWidget.tsx +0 -40
  199. package/src/components/molecules/Resizable.tsx +0 -47
  200. package/src/components/molecules/ScrollArea.tsx +0 -48
  201. package/src/components/molecules/SidebarItem.tsx +0 -134
  202. package/src/components/molecules/Toast.tsx +0 -57
  203. package/src/components/molecules/Tooltip.tsx +0 -30
  204. package/src/components/molecules/generated/default-variant-keys.ts +0 -22
  205. package/src/components/molecules/generated/variant-keys.ts +0 -33
  206. package/src/components/organisms/CommandPalette.tsx +0 -58
  207. package/src/components/organisms/FloatingPanel.tsx +0 -46
  208. package/src/components/organisms/ShareModal.tsx +0 -182
  209. package/src/components/organisms/ToastProvider.tsx +0 -49
  210. /package/src/components/{atoms → display}/Kbd.tsx +0 -0
  211. /package/src/components/{atoms → display}/Separator.tsx +0 -0
  212. /package/src/components/{atoms → display}/Skeleton.tsx +0 -0
  213. /package/src/components/{atoms → feedback}/Progress.tsx +0 -0
  214. /package/src/components/{atoms → inputs}/Button.tsx +0 -0
  215. /package/src/components/{atoms → inputs}/Label.tsx +0 -0
  216. /package/src/components/{atoms → inputs}/RadioGroup.tsx +0 -0
  217. /package/src/components/{organisms → navigation}/AppRail.tsx +0 -0
  218. /package/src/components/{templates → patterns}/AuthTemplate.tsx +0 -0
  219. /package/src/components/{templates → patterns}/BannalyzeTemplate.tsx +0 -0
  220. /package/src/components/{templates → patterns}/ChatTemplate.tsx +0 -0
  221. /package/src/components/{templates → patterns}/EditorTemplate.tsx +0 -0
  222. /package/src/components/{templates → patterns}/KanbanTemplate.tsx +0 -0
  223. /package/src/components/{templates → patterns}/LandingTemplate.tsx +0 -0
  224. /package/src/components/{templates → patterns}/SettingsTemplate.tsx +0 -0
@@ -0,0 +1,71 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
5
+
6
+ import { cn } from "../../lib/utils"
7
+
8
+ export interface ScrollAreaProps
9
+ extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
10
+ viewportClassName?: string
11
+ scrollbarClassName?: string
12
+ thumbClassName?: string
13
+ scrollbarOrientation?: "vertical" | "horizontal" | "both"
14
+ }
15
+
16
+ const ScrollArea = React.forwardRef<
17
+ React.ElementRef<typeof ScrollAreaPrimitive.Root>,
18
+ ScrollAreaProps
19
+ >(({ className, viewportClassName, scrollbarClassName, thumbClassName, scrollbarOrientation = "vertical", children, ...props }, ref) => (
20
+ <ScrollAreaPrimitive.Root
21
+ ref={ref}
22
+ className={cn("relative overflow-hidden flex min-h-0 min-w-0 flex-col", className)}
23
+ {...props}
24
+ >
25
+ <ScrollAreaPrimitive.Viewport
26
+ className={cn(
27
+ "h-full w-full rounded-[inherit] [&>div]:!block [&>div]:!min-w-0 [&>div]:!w-full",
28
+ viewportClassName
29
+ )}
30
+ >
31
+ {children}
32
+ </ScrollAreaPrimitive.Viewport>
33
+ {(scrollbarOrientation === "vertical" || scrollbarOrientation === "both") && (
34
+ <ScrollBar className={scrollbarClassName} thumbClassName={thumbClassName} />
35
+ )}
36
+ {(scrollbarOrientation === "horizontal" || scrollbarOrientation === "both") && (
37
+ <ScrollBar orientation="horizontal" className={scrollbarClassName} thumbClassName={thumbClassName} />
38
+ )}
39
+ <ScrollAreaPrimitive.Corner />
40
+ </ScrollAreaPrimitive.Root>
41
+ ))
42
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
43
+
44
+ export interface ScrollBarProps
45
+ extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar> {
46
+ thumbClassName?: string
47
+ }
48
+
49
+ const ScrollBar = React.forwardRef<
50
+ React.ElementRef<typeof ScrollAreaPrimitive.Scrollbar>,
51
+ ScrollBarProps
52
+ >(({ className, thumbClassName, orientation = "vertical", ...props }, ref) => (
53
+ <ScrollAreaPrimitive.Scrollbar
54
+ ref={ref}
55
+ orientation={orientation}
56
+ className={cn(
57
+ "flex touch-none select-none transition-colors",
58
+ orientation === "vertical" &&
59
+ "h-full w-2.5 border-l border-l-transparent p-[1px]",
60
+ orientation === "horizontal" &&
61
+ "h-2.5 border-t border-t-transparent p-[1px]",
62
+ className
63
+ )}
64
+ {...props}
65
+ >
66
+ <ScrollAreaPrimitive.Thumb className={cn("relative flex-1 rounded-full bg-border", thumbClassName)} />
67
+ </ScrollAreaPrimitive.Scrollbar>
68
+ ))
69
+ ScrollBar.displayName = ScrollAreaPrimitive.Scrollbar.displayName
70
+
71
+ export { ScrollArea, ScrollBar }
@@ -1,27 +1,31 @@
1
1
  import React from 'react';
2
2
  import { cn } from '../../lib/utils';
3
3
 
4
- interface SpatialCanvasProps {
4
+ interface SpatialCanvasProps extends React.HTMLAttributes<HTMLDivElement> {
5
5
  children: React.ReactNode;
6
- className?: string;
7
6
  gridSize?: number;
8
7
  }
9
8
 
10
- export const SpatialCanvas: React.FC<SpatialCanvasProps> = ({
9
+ export const SpatialCanvas = React.forwardRef<HTMLDivElement, SpatialCanvasProps>(({
11
10
  children,
12
11
  className,
13
- gridSize = 20
14
- }) => {
12
+ gridSize = 20,
13
+ style,
14
+ ...props
15
+ }, ref) => {
15
16
  return (
16
17
  <div
18
+ ref={ref}
17
19
  className={cn(
18
- "relative flex flex-col w-[640px] h-[360px] w-full h-full overflow-hidden bg-muted/50 select-none",
20
+ "relative flex h-full min-h-0 w-full min-w-0 select-none flex-col overflow-hidden bg-muted/50",
19
21
  className
20
22
  )}
21
23
  style={{
24
+ ...style,
22
25
  backgroundImage: `radial-gradient(circle, hsl(var(--foreground) / 0.08) 1px, transparent 1px)`,
23
26
  backgroundSize: `${gridSize}px ${gridSize}px`
24
27
  }}
28
+ {...props}
25
29
  >
26
30
  <div className="absolute inset-0 pointer-events-none dark:opacity-20 opacity-5"
27
31
  style={{
@@ -33,4 +37,5 @@ export const SpatialCanvas: React.FC<SpatialCanvasProps> = ({
33
37
  {children}
34
38
  </div>
35
39
  );
36
- };
40
+ });
41
+ SpatialCanvas.displayName = 'SpatialCanvas';
@@ -0,0 +1,69 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../../lib/utils"
4
+
5
+ const GAP_MAP = {
6
+ 0: "gap-0",
7
+ 1: "gap-1",
8
+ 2: "gap-2",
9
+ 3: "gap-3",
10
+ 4: "gap-4",
11
+ 5: "gap-5",
12
+ 6: "gap-6",
13
+ 8: "gap-8",
14
+ 10: "gap-10",
15
+ 12: "gap-12",
16
+ } as const
17
+
18
+ const ALIGN_MAP = {
19
+ start: "items-start",
20
+ center: "items-center",
21
+ end: "items-end",
22
+ stretch: "items-stretch",
23
+ } as const
24
+
25
+ const JUSTIFY_MAP = {
26
+ start: "justify-start",
27
+ center: "justify-center",
28
+ end: "justify-end",
29
+ between: "justify-between",
30
+ around: "justify-around",
31
+ evenly: "justify-evenly",
32
+ } as const
33
+
34
+ export interface VStackProps extends React.HTMLAttributes<HTMLDivElement> {
35
+ gap?: keyof typeof GAP_MAP
36
+ align?: keyof typeof ALIGN_MAP
37
+ justify?: keyof typeof JUSTIFY_MAP
38
+ inline?: boolean
39
+ }
40
+
41
+ const VStack = React.forwardRef<HTMLDivElement, VStackProps>(
42
+ (
43
+ {
44
+ className,
45
+ gap = 2,
46
+ align = "stretch",
47
+ justify = "start",
48
+ inline = false,
49
+ ...props
50
+ },
51
+ ref
52
+ ) => (
53
+ <div
54
+ ref={ref}
55
+ className={cn(
56
+ inline ? "inline-flex" : "flex",
57
+ "flex-col",
58
+ GAP_MAP[gap],
59
+ ALIGN_MAP[align],
60
+ JUSTIFY_MAP[justify],
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ )
66
+ )
67
+ VStack.displayName = "VStack"
68
+
69
+ export { VStack }
@@ -0,0 +1,16 @@
1
+ /* eslint-disable */
2
+ // Generated by `npm run design:sync:components`. Do not edit manually.
3
+
4
+ import type { AssetInspectorPanelVariantKey, CollapsiblePanelToggleVariantKey, DeviceFrameVariantKey, MarqueeFrameVariantKey } from "./variant-keys";
5
+
6
+ export const assetInspectorPanelDefaultVariantKey: AssetInspectorPanelVariantKey = "default";
7
+ export const collapsiblePanelToggleDefaultVariantKey: CollapsiblePanelToggleVariantKey = "left";
8
+ export const deviceFrameDefaultVariantKey: DeviceFrameVariantKey = "default";
9
+ export const marqueeFrameDefaultVariantKey: MarqueeFrameVariantKey = "default";
10
+
11
+ export const layoutDefaultVariantKeys = {
12
+ assetInspectorPanel: assetInspectorPanelDefaultVariantKey,
13
+ collapsiblePanelToggle: collapsiblePanelToggleDefaultVariantKey,
14
+ deviceFrame: deviceFrameDefaultVariantKey,
15
+ marqueeFrame: marqueeFrameDefaultVariantKey,
16
+ } as const;
@@ -0,0 +1,21 @@
1
+ /* eslint-disable */
2
+ // Generated by `npm run design:sync:components`. Do not edit manually.
3
+
4
+ export const assetInspectorPanelVariantKeys = ["compact", "default"] as const;
5
+ export type AssetInspectorPanelVariantKey = (typeof assetInspectorPanelVariantKeys)[number];
6
+
7
+ export const collapsiblePanelToggleVariantKeys = ["bottom", "left", "right", "top"] as const;
8
+ export type CollapsiblePanelToggleVariantKey = (typeof collapsiblePanelToggleVariantKeys)[number];
9
+
10
+ export const deviceFrameVariantKeys = ["default", "windows11"] as const;
11
+ export type DeviceFrameVariantKey = (typeof deviceFrameVariantKeys)[number];
12
+
13
+ export const marqueeFrameVariantKeys = ["default", "desktop", "mobile", "tablet"] as const;
14
+ export type MarqueeFrameVariantKey = (typeof marqueeFrameVariantKeys)[number];
15
+
16
+ export const layoutVariantKeys = {
17
+ assetInspectorPanel: assetInspectorPanelVariantKeys,
18
+ collapsiblePanelToggle: collapsiblePanelToggleVariantKeys,
19
+ deviceFrame: deviceFrameVariantKeys,
20
+ marqueeFrame: marqueeFrameVariantKeys,
21
+ } as const;
@@ -1,6 +1,6 @@
1
1
  import * as React from "react"
2
2
  import { Slot } from "@radix-ui/react-slot"
3
- import { ChevronRight, MoreHorizontal } from "lucide-react"
3
+ import { IconChevronRight as ChevronRight, IconDots as MoreHorizontal } from "@tabler/icons-react";
4
4
 
5
5
  import { cn } from "../../lib/utils"
6
6
 
@@ -90,8 +90,9 @@ BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
90
90
 
91
91
  const BreadcrumbEllipsis = ({
92
92
  className,
93
+ label = "More",
93
94
  ...props
94
- }: React.ComponentProps<"span">) => (
95
+ }: React.ComponentProps<"span"> & { label?: string }) => (
95
96
  <span
96
97
  role="presentation"
97
98
  aria-hidden="true"
@@ -99,10 +100,10 @@ const BreadcrumbEllipsis = ({
99
100
  {...props}
100
101
  >
101
102
  <MoreHorizontal className="h-4 w-4" />
102
- <span className="sr-only">More</span>
103
+ <span className="sr-only">{label}</span>
103
104
  </span>
104
105
  )
105
- BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
106
+ BreadcrumbEllipsis.displayName = "BreadcrumbEllipsis"
106
107
 
107
108
  export {
108
109
  Breadcrumb,
@@ -0,0 +1,266 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Command as CommandPrimitive } from "cmdk"
5
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
6
+ import { IconSearch as Search, IconX as X } from "@tabler/icons-react";
7
+
8
+ import { cn } from "../../lib/utils"
9
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../overlay/Tooltip"
10
+
11
+ const Command = React.forwardRef<
12
+ React.ElementRef<typeof CommandPrimitive>,
13
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
14
+ >(({ className, ...props }, ref) => (
15
+ <CommandPrimitive
16
+ ref={ref}
17
+ className={cn(
18
+ "flex h-full w-[320px] w-full flex-col overflow-hidden rounded-md border bg-popover text-popover-foreground",
19
+ className
20
+ )}
21
+ {...props}
22
+ />
23
+ ))
24
+ Command.displayName = CommandPrimitive.displayName
25
+
26
+ type CommandDialogProps = React.ComponentProps<typeof CommandPrimitive.Dialog> & {
27
+ dialogTitle?: React.ReactNode
28
+ portalContainer?: HTMLElement | null
29
+ }
30
+
31
+ const CommandDialog = ({
32
+ children,
33
+ dialogTitle = "Command Menu",
34
+ portalContainer,
35
+ container,
36
+ className,
37
+ overlayClassName,
38
+ contentClassName,
39
+ ...props
40
+ }: CommandDialogProps) => {
41
+ const resolvedContainer = portalContainer ?? container
42
+
43
+ return (
44
+ <CommandPrimitive.Dialog
45
+ {...props}
46
+ container={resolvedContainer ?? undefined}
47
+ overlayClassName={cn(
48
+ "fixed inset-0 z-50 bg-overlay/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
49
+ resolvedContainer && "absolute",
50
+ overlayClassName
51
+ )}
52
+ contentClassName={cn(
53
+ "fixed left-1/2 top-[10%] z-50 w-[calc(100%-2rem)] max-w-[640px] -translate-x-1/2 overflow-hidden rounded-lg bg-popover text-left text-popover-foreground shadow-lg 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",
54
+ resolvedContainer && "absolute",
55
+ contentClassName
56
+ )}
57
+ className={cn("flex h-full w-full flex-col overflow-hidden rounded-lg border bg-popover text-left text-popover-foreground", className)}
58
+ >
59
+ <DialogPrimitive.Title className="sr-only">{dialogTitle}</DialogPrimitive.Title>
60
+ {children}
61
+ </CommandPrimitive.Dialog>
62
+ )
63
+ }
64
+
65
+ type CommandInputProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> & {
66
+ clearable?: boolean
67
+ clearLabel?: string
68
+ }
69
+
70
+ function setNativeInputValue(input: HTMLInputElement, value: string) {
71
+ const valueSetter = Object.getOwnPropertyDescriptor(
72
+ window.HTMLInputElement.prototype,
73
+ "value"
74
+ )?.set
75
+ valueSetter?.call(input, value)
76
+ input.dispatchEvent(new Event("input", { bubbles: true }))
77
+ }
78
+
79
+ const CommandInput = React.forwardRef<
80
+ React.ElementRef<typeof CommandPrimitive.Input>,
81
+ CommandInputProps
82
+ >(({ className, clearable = false, clearLabel = "Clear search", onInput, onValueChange, disabled, ...props }, ref) => {
83
+ const inputRef = React.useRef<HTMLInputElement | null>(null)
84
+ const [hasValue, setHasValue] = React.useState(Boolean(props.value ?? props.defaultValue))
85
+
86
+ const setRefs = React.useCallback(
87
+ (node: HTMLInputElement | null) => {
88
+ inputRef.current = node
89
+ if (typeof ref === "function") {
90
+ ref(node)
91
+ } else if (ref) {
92
+ ref.current = node
93
+ }
94
+ },
95
+ [ref]
96
+ )
97
+
98
+ const handleClear = React.useCallback(() => {
99
+ const input = inputRef.current
100
+ if (!input) return
101
+ onValueChange?.("")
102
+ setNativeInputValue(input, "")
103
+ setHasValue(false)
104
+ input.focus()
105
+ }, [onValueChange])
106
+
107
+ React.useEffect(() => {
108
+ setHasValue(Boolean(props.value ?? inputRef.current?.value ?? props.defaultValue))
109
+ }, [props.defaultValue, props.value])
110
+
111
+ return (
112
+ <div className="relative flex items-center border-b px-3 py-2" cmdk-input-wrapper="">
113
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
114
+ <CommandPrimitive.Input
115
+ ref={setRefs}
116
+ disabled={disabled}
117
+ className={cn(
118
+ "flex h-10 w-full rounded-md bg-transparent text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
119
+ clearable && "pr-8",
120
+ className
121
+ )}
122
+ onInput={(event) => {
123
+ setHasValue(Boolean(event.currentTarget.value))
124
+ onInput?.(event)
125
+ }}
126
+ onValueChange={onValueChange}
127
+ {...props}
128
+ />
129
+ {clearable && hasValue && !disabled ? (
130
+ <Tooltip>
131
+ <TooltipTrigger asChild>
132
+ <button
133
+ type="button"
134
+ className="absolute right-3 top-1/2 flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
135
+ aria-label={clearLabel}
136
+ onMouseDown={(event) => event.preventDefault()}
137
+ onClick={handleClear}
138
+ >
139
+ <X className="h-3.5 w-3.5" />
140
+ </button>
141
+ </TooltipTrigger>
142
+ <TooltipContent>{clearLabel}</TooltipContent>
143
+ </Tooltip>
144
+ ) : null}
145
+ </div>
146
+ )
147
+ })
148
+ CommandInput.displayName = CommandPrimitive.Input.displayName
149
+
150
+ const CommandList = React.forwardRef<
151
+ React.ElementRef<typeof CommandPrimitive.List>,
152
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
153
+ >(({ className, ...props }, ref) => (
154
+ <CommandPrimitive.List
155
+ ref={ref}
156
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
157
+ {...props}
158
+ />
159
+ ))
160
+ CommandList.displayName = CommandPrimitive.List.displayName
161
+
162
+ const CommandEmpty = React.forwardRef<
163
+ React.ElementRef<typeof CommandPrimitive.Empty>,
164
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
165
+ >((props, ref) => (
166
+ <CommandPrimitive.Empty
167
+ ref={ref}
168
+ className="py-6 text-center text-sm"
169
+ {...props}
170
+ />
171
+ ))
172
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName
173
+
174
+ const CommandGroup = React.forwardRef<
175
+ React.ElementRef<typeof CommandPrimitive.Group>,
176
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
177
+ >(({ className, ...props }, ref) => (
178
+ <CommandPrimitive.Group
179
+ ref={ref}
180
+ className={cn(
181
+ "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-semibold [&_[cmdk-group-heading]]:text-muted-foreground",
182
+ className
183
+ )}
184
+ {...props}
185
+ />
186
+ ))
187
+ CommandGroup.displayName = CommandPrimitive.Group.displayName
188
+
189
+ const CommandSeparator = React.forwardRef<
190
+ React.ElementRef<typeof CommandPrimitive.Separator>,
191
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
192
+ >(({ className, ...props }, ref) => (
193
+ <CommandPrimitive.Separator
194
+ ref={ref}
195
+ className={cn("-mx-1 h-px bg-border", className)}
196
+ {...props}
197
+ />
198
+ ))
199
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
200
+
201
+ type CommandItemProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item> & {
202
+ disabledReason?: React.ReactNode
203
+ disabledReasonLabel?: string
204
+ }
205
+
206
+ const CommandItem = React.forwardRef<
207
+ React.ElementRef<typeof CommandPrimitive.Item>,
208
+ CommandItemProps
209
+ >(({ className, disabledReason, disabledReasonLabel, disabled, ...props }, ref) => {
210
+ const item = (
211
+ <CommandPrimitive.Item
212
+ ref={ref}
213
+ disabled={disabled}
214
+ className={cn(
215
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
216
+ className
217
+ )}
218
+ {...props}
219
+ />
220
+ )
221
+
222
+ if (!disabled || !disabledReason) return item
223
+
224
+ const label =
225
+ disabledReasonLabel ?? (typeof disabledReason === "string" ? disabledReason : "Disabled item reason")
226
+
227
+ return (
228
+ <Tooltip>
229
+ <TooltipTrigger asChild>
230
+ <span className="block rounded-sm" tabIndex={0} aria-label={label}>
231
+ {item}
232
+ </span>
233
+ </TooltipTrigger>
234
+ <TooltipContent>{disabledReason}</TooltipContent>
235
+ </Tooltip>
236
+ )
237
+ })
238
+ CommandItem.displayName = CommandPrimitive.Item.displayName
239
+
240
+ const CommandShortcut = ({
241
+ className,
242
+ ...props
243
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
244
+ return (
245
+ <span
246
+ className={cn(
247
+ "ml-auto text-xs tracking-widest text-muted-foreground",
248
+ className
249
+ )}
250
+ {...props}
251
+ />
252
+ )
253
+ }
254
+ CommandShortcut.displayName = "CommandShortcut"
255
+
256
+ export {
257
+ Command,
258
+ CommandDialog,
259
+ CommandInput,
260
+ CommandList,
261
+ CommandEmpty,
262
+ CommandGroup,
263
+ CommandItem,
264
+ CommandShortcut,
265
+ CommandSeparator,
266
+ }
@@ -0,0 +1,83 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import {
5
+ CommandDialog,
6
+ CommandEmpty,
7
+ CommandGroup,
8
+ CommandInput,
9
+ CommandItem,
10
+ CommandList,
11
+ CommandSeparator,
12
+ CommandShortcut,
13
+ } from "./Command"
14
+ import { cn } from "../../lib/utils"
15
+
16
+ export interface CommandPaletteAction {
17
+ id: string
18
+ label: string
19
+ icon?: React.ReactNode
20
+ shortcut?: string
21
+ action: () => void
22
+ }
23
+
24
+ export interface CommandPaletteGroup {
25
+ heading: string
26
+ items: CommandPaletteAction[]
27
+ }
28
+
29
+ export interface CommandPaletteProps extends Omit<React.ComponentPropsWithoutRef<typeof CommandDialog>, "children"> {
30
+ groups: CommandPaletteGroup[]
31
+ placeholder?: string
32
+ emptyMessage?: React.ReactNode
33
+ dialogTitle?: React.ReactNode
34
+ clearLabel?: string
35
+ }
36
+
37
+ export function CommandPalette({
38
+ groups,
39
+ placeholder = "Type a command or search...",
40
+ emptyMessage = "No results found.",
41
+ dialogTitle = "Command Menu",
42
+ clearLabel = "Clear search",
43
+ className,
44
+ contentClassName,
45
+ ...props
46
+ }: CommandPaletteProps) {
47
+ return (
48
+ <CommandDialog
49
+ dialogTitle={dialogTitle}
50
+ className={cn("flex-col w-[480px] w-full max-h-[min(32rem,calc(100%-2rem))] rounded-lg border", className)}
51
+ contentClassName={cn("max-w-[640px]", contentClassName)}
52
+ {...props}
53
+ >
54
+ <CommandInput placeholder={placeholder} clearable clearLabel={clearLabel} autoFocus />
55
+ <CommandList>
56
+ <CommandEmpty>{emptyMessage}</CommandEmpty>
57
+ {groups.map((group, groupIndex) => (
58
+ <React.Fragment key={group.heading}>
59
+ <CommandGroup heading={group.heading}>
60
+ {group.items.map((item) => (
61
+ <CommandItem
62
+ key={item.id}
63
+ value={item.id}
64
+ keywords={[item.label, item.shortcut].filter(Boolean) as string[]}
65
+ onSelect={item.action}
66
+ >
67
+ {item.icon ? (
68
+ <span className="mr-2 flex h-4 w-4 shrink-0 items-center justify-center [&>svg]:h-4 [&>svg]:w-4">
69
+ {item.icon}
70
+ </span>
71
+ ) : null}
72
+ <span className="min-w-0 flex-1 truncate">{item.label}</span>
73
+ {item.shortcut ? <CommandShortcut>{item.shortcut}</CommandShortcut> : null}
74
+ </CommandItem>
75
+ ))}
76
+ </CommandGroup>
77
+ {groupIndex < groups.length - 1 ? <CommandSeparator /> : null}
78
+ </React.Fragment>
79
+ ))}
80
+ </CommandList>
81
+ </CommandDialog>
82
+ )
83
+ }