@gunjo/ui 0.0.1-alpha.0 → 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
@@ -1,57 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as AvatarPrimitive from "@radix-ui/react-avatar"
5
-
6
- import { cn } from "../../lib/utils"
7
- import type { AvatarVariantKey } from "./generated/variant-keys"
8
- import { avatarDefaultVariantKey } from "./generated/default-variant-keys"
9
-
10
- const avatarSlotClasses: Record<AvatarVariantKey, string> = {
11
- fallback: "flex h-full w-full items-center justify-center rounded-full bg-secondary text-sm font-medium text-muted-foreground",
12
- image: "aspect-square h-full w-full",
13
- }
14
-
15
- const Avatar = React.forwardRef<
16
- React.ElementRef<typeof AvatarPrimitive.Root>,
17
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
18
- >(({ className, ...props }, ref) => (
19
- <AvatarPrimitive.Root
20
- ref={ref}
21
- className={cn(
22
- "relative inline-flex h-10 w-10 shrink-0 items-center overflow-hidden rounded-full",
23
- className
24
- )}
25
- {...props}
26
- />
27
- ))
28
- Avatar.displayName = AvatarPrimitive.Root.displayName
29
-
30
- const AvatarImage = React.forwardRef<
31
- React.ElementRef<typeof AvatarPrimitive.Image>,
32
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
33
- >(({ className, ...props }, ref) => (
34
- <AvatarPrimitive.Image
35
- ref={ref}
36
- className={cn(avatarSlotClasses.image, className)}
37
- {...props}
38
- />
39
- ))
40
- AvatarImage.displayName = AvatarPrimitive.Image.displayName
41
-
42
- const AvatarFallback = React.forwardRef<
43
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
44
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
45
- >(({ className, ...props }, ref) => (
46
- <AvatarPrimitive.Fallback
47
- ref={ref}
48
- className={cn(
49
- avatarSlotClasses[avatarDefaultVariantKey],
50
- className
51
- )}
52
- {...props}
53
- />
54
- ))
55
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
56
-
57
- export { Avatar, AvatarImage, AvatarFallback }
@@ -1,28 +0,0 @@
1
- import * as React from "react"
2
- import { cn } from "../../lib/utils"
3
- import { ChevronDown } from "lucide-react"
4
-
5
- export interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> { }
6
-
7
- const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
8
- ({ className, children, ...props }, ref) => {
9
- return (
10
- <div className="relative">
11
- <select
12
- className={cn(
13
- "inline-flex h-10 w-[200px] appearance-none items-center justify-between rounded-lg border border-input bg-transparent px-3 py-2 text-sm font-normal text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground disabled:opacity-50",
14
- className
15
- )}
16
- ref={ref}
17
- {...props}
18
- >
19
- {children}
20
- </select>
21
- <ChevronDown className="pointer-events-none absolute right-3 top-3 h-4 w-4 text-muted-foreground" />
22
- </div>
23
- )
24
- }
25
- )
26
- Select.displayName = "Select"
27
-
28
- export { Select }
@@ -1,36 +0,0 @@
1
- /* eslint-disable */
2
- // Generated by `npm run design:sync:components`. Do not edit manually.
3
-
4
- import type { AlertVariantKey, AvatarVariantKey, BadgeVariantKey, ButtonVariantKey, CheckboxVariantKey, ImgVariantKey, InputVariantKey, RadioGroupVariantKey, SeparatorVariantKey, SpinnerVariantKey, SwitchVariantKey, TextareaVariantKey, ToggleGroupVariantKey, ToolPillVariantKey } from "./variant-keys";
5
-
6
- export const alertDefaultVariantKey: AlertVariantKey = "default";
7
- export const avatarDefaultVariantKey: AvatarVariantKey = "fallback";
8
- export const badgeDefaultVariantKey: BadgeVariantKey = "default";
9
- export const buttonDefaultVariantKey: ButtonVariantKey = "default";
10
- export const checkboxDefaultVariantKey: CheckboxVariantKey = "unchecked";
11
- export const imgDefaultVariantKey: ImgVariantKey = "loading";
12
- export const inputDefaultVariantKey: InputVariantKey = "default";
13
- export const radioGroupDefaultVariantKey: RadioGroupVariantKey = "unchecked";
14
- export const separatorDefaultVariantKey: SeparatorVariantKey = "horizontal";
15
- export const spinnerDefaultVariantKey: SpinnerVariantKey = "default";
16
- export const switchDefaultVariantKey: SwitchVariantKey = "unchecked";
17
- export const textareaDefaultVariantKey: TextareaVariantKey = "default";
18
- export const toggleGroupDefaultVariantKey: ToggleGroupVariantKey = "default";
19
- export const toolPillDefaultVariantKey: ToolPillVariantKey = "primary";
20
-
21
- export const atomDefaultVariantKeys = {
22
- alert: alertDefaultVariantKey,
23
- avatar: avatarDefaultVariantKey,
24
- badge: badgeDefaultVariantKey,
25
- button: buttonDefaultVariantKey,
26
- checkbox: checkboxDefaultVariantKey,
27
- img: imgDefaultVariantKey,
28
- input: inputDefaultVariantKey,
29
- radioGroup: radioGroupDefaultVariantKey,
30
- separator: separatorDefaultVariantKey,
31
- spinner: spinnerDefaultVariantKey,
32
- switch: switchDefaultVariantKey,
33
- textarea: textareaDefaultVariantKey,
34
- toggleGroup: toggleGroupDefaultVariantKey,
35
- toolPill: toolPillDefaultVariantKey,
36
- } as const;
@@ -1,140 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Send, Paperclip, Loader2, Square } from "lucide-react";
5
- import { Button } from "../atoms/Button";
6
- import { Textarea } from "../atoms/Textarea";
7
- import { cn } from "../../lib/utils";
8
- import { buttonDefaultVariantKey } from "../atoms/generated/default-variant-keys";
9
-
10
- export interface AIChatInputProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
11
- onSend: (message: string, files?: File[]) => void;
12
- onStop?: () => void;
13
- isProcessing?: boolean;
14
- placeholder?: string;
15
- enableAttachments?: boolean;
16
- }
17
-
18
- export function AIChatInput({
19
- onSend,
20
- onStop,
21
- isProcessing = false,
22
- placeholder = "メッセージを入力...",
23
- enableAttachments = true,
24
- className,
25
- disabled,
26
- ...props
27
- }: AIChatInputProps) {
28
- const [message, setMessage] = React.useState("");
29
- const textareaRef = React.useRef<HTMLTextAreaElement>(null);
30
- const fileInputRef = React.useRef<HTMLInputElement>(null);
31
-
32
- const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
33
- setMessage(e.target.value);
34
- adjustHeight();
35
- };
36
-
37
- const adjustHeight = () => {
38
- const textarea = textareaRef.current;
39
- if (textarea) {
40
- textarea.style.height = "auto";
41
- textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
42
- }
43
- };
44
-
45
- const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
46
- if (e.key === "Enter" && !e.shiftKey) {
47
- e.preventDefault();
48
- handleSend();
49
- }
50
- };
51
-
52
- const handleSend = () => {
53
- if (!message.trim() || isProcessing) return;
54
- onSend(message);
55
- setMessage("");
56
- if (textareaRef.current) {
57
- textareaRef.current.style.height = "auto";
58
- }
59
- };
60
-
61
- const handleUploadClick = () => {
62
- fileInputRef.current?.click();
63
- };
64
-
65
- const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
66
- if (e.target.files && e.target.files.length > 0) {
67
- // For now, we just pass the files to onSend alongside an empty message or handle it differently
68
- // In a real app, we might stage files. Here we'll just expose the capability.
69
- onSend(message, Array.from(e.target.files));
70
- setMessage(""); // Clear message if sent with file
71
-
72
- if (textareaRef.current) {
73
- textareaRef.current.value = ""; // Reset input
74
- textareaRef.current.style.height = "auto";
75
- }
76
- if (fileInputRef.current) {
77
- fileInputRef.current.value = ""; // Reset file input
78
- }
79
- }
80
- };
81
-
82
- return (
83
- <div className={cn("relative flex flex-col flex-row items-center items-end w-[640px] max-w-full gap-2 p-4 bg-background border border-t border-border", className)}>
84
- {enableAttachments && (
85
- <>
86
- <input
87
- type="file"
88
- multiple
89
- className="hidden"
90
- ref={fileInputRef}
91
- onChange={handleFileChange}
92
- />
93
- <Button
94
- variant="ghost"
95
- size="icon"
96
- className="flex-shrink-0 text-muted-foreground hover:text-foreground mb-0.5"
97
- onClick={handleUploadClick}
98
- disabled={disabled || isProcessing}
99
- >
100
- <Paperclip className="h-5 w-5" />
101
- </Button>
102
- </>
103
- )}
104
-
105
- <div className="flex-1 relative">
106
- <Textarea
107
- ref={textareaRef}
108
- value={message}
109
- onChange={handleInput}
110
- onKeyDown={handleKeyDown}
111
- placeholder={placeholder}
112
- disabled={disabled || isProcessing}
113
- className="min-h-[44px] max-h-[200px] py-3 pr-4 resize-none rounded-xl border-border focus:ring-ring bg-muted"
114
- rows={1}
115
- />
116
- </div>
117
-
118
- {isProcessing ? (
119
- <Button
120
- variant="destructive"
121
- size="icon"
122
- className="flex-shrink-0 rounded-xl mb-0.5"
123
- onClick={onStop}
124
- >
125
- <Square className="h-4 w-4 fill-current" />
126
- </Button>
127
- ) : (
128
- <Button
129
- variant={buttonDefaultVariantKey}
130
- size="icon"
131
- className="mb-0.5 flex-shrink-0 rounded-xl bg-primary text-primary-foreground hover:bg-primary/90"
132
- onClick={handleSend}
133
- disabled={!message.trim() || disabled}
134
- >
135
- <Send className="h-4 w-4" />
136
- </Button>
137
- )}
138
- </div>
139
- );
140
- }
@@ -1,109 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { User, Sparkles, Copy, ThumbsUp, ThumbsDown } from "lucide-react";
5
- import { Avatar, AvatarFallback, AvatarImage } from "../atoms/Avatar";
6
- import { Button } from "../atoms/Button";
7
- import { cn } from "../../lib/utils";
8
- import type { AiChatMessageVariantKey } from "./generated/variant-keys";
9
- import { aiChatMessageDefaultVariantKey } from "./generated/default-variant-keys";
10
-
11
- type AIChatMessageRole = AiChatMessageVariantKey | "system";
12
-
13
- export interface AIChatMessageProps {
14
- role: AIChatMessageRole;
15
- content: string;
16
- avatarSrc?: string;
17
- userName?: string;
18
- timestamp?: string;
19
- isTyping?: boolean;
20
- className?: string;
21
- }
22
-
23
- export function AIChatMessage({
24
- role,
25
- content,
26
- avatarSrc,
27
- userName = role === "user" ? "You" : "AI Assistant",
28
- timestamp,
29
- isTyping = false,
30
- className
31
- }: AIChatMessageProps) {
32
- if (role === "system") {
33
- return (
34
- <div className={cn("flex justify-center my-4", className)}>
35
- <span className="text-xs text-muted-foreground bg-muted px-3 py-1 rounded-full">
36
- {content}
37
- </span>
38
- </div>
39
- );
40
- }
41
-
42
- const messageRole: AiChatMessageVariantKey =
43
- role === "user" ? "user" : aiChatMessageDefaultVariantKey;
44
- const isUser = messageRole === "user";
45
-
46
- const rowDirectionClasses: Record<AiChatMessageVariantKey, string> = {
47
- assistant: "flex-row",
48
- user: "flex-row-reverse",
49
- };
50
-
51
- const bubbleClasses: Record<AiChatMessageVariantKey, string> = {
52
- assistant: "bg-background border border-border text-foreground rounded-tl-none",
53
- user: "bg-primary text-primary-foreground rounded-tr-none",
54
- };
55
-
56
- return (
57
- <div className={cn(
58
- "flex gap-4 p-4 w-[720px] max-w-full transition-colors hover:bg-muted/50 group",
59
- rowDirectionClasses[messageRole],
60
- className
61
- )}>
62
- {/* Avatar */}
63
- <div className="flex-shrink-0 mt-1">
64
- <Avatar className={cn("h-8 w-8", isUser ? "ring-2 ring-primary/20" : "bg-primary text-primary-foreground")}>
65
- {avatarSrc ? (
66
- <AvatarImage src={avatarSrc} alt={userName} />
67
- ) : (
68
- <AvatarFallback className={cn(isUser ? "bg-background text-muted-foreground" : "bg-transparent text-primary-foreground")}>
69
- {isUser ? <User className="h-4 w-4" /> : <Sparkles className="h-4 w-4" />}
70
- </AvatarFallback>
71
- )}
72
- </Avatar>
73
- </div>
74
-
75
- {/* Content Body */}
76
- <div className={cn("flex flex-col max-w-[80%]", isUser ? "items-end" : "items-start")}>
77
- <div className="flex items-center gap-2 mb-1">
78
- <span className="text-sm font-semibold text-foreground">{userName}</span>
79
- {timestamp && <span className="text-xs text-muted-foreground">{timestamp}</span>}
80
- </div>
81
-
82
- <div className={cn(
83
- "text-sm leading-relaxed rounded-2xl px-4 py-3 shadow-sm whitespace-pre-wrap",
84
- bubbleClasses[messageRole]
85
- )}>
86
- {content}
87
- {isTyping && (
88
- <span className="inline-block w-1.5 h-4 ml-1 align-middle bg-current animate-pulse" />
89
- )}
90
- </div>
91
-
92
- {/* Actions (Only for assistant messages usually, but logic allows both) */}
93
- {!isUser && !isTyping && (
94
- <div className="flex items-center gap-1 mt-2 opacity-0 group-hover:opacity-100 transition-opacity">
95
- <Button variant="ghost" size="icon" className="h-6 w-6 text-muted-foreground hover:text-foreground">
96
- <Copy className="h-3 w-3" />
97
- </Button>
98
- <Button variant="ghost" size="icon" className="h-6 w-6 text-muted-foreground hover:text-foreground">
99
- <ThumbsUp className="h-3 w-3" />
100
- </Button>
101
- <Button variant="ghost" size="icon" className="h-6 w-6 text-muted-foreground hover:text-foreground">
102
- <ThumbsDown className="h-3 w-3" />
103
- </Button>
104
- </div>
105
- )}
106
- </div>
107
- </div>
108
- );
109
- }
@@ -1,99 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as AccordionPrimitive from "@radix-ui/react-accordion"
5
- import { ChevronDown } from "lucide-react"
6
-
7
- import { cn } from "../../lib/utils"
8
- import type { AccordionVariantKey } from "./generated/variant-keys"
9
- import { accordionDefaultVariantKey } from "./generated/default-variant-keys"
10
-
11
- function buildVariantStateMap(
12
- defaultVariantKey: AccordionVariantKey,
13
- defaultStateClass: string,
14
- alternateStateClass: string
15
- ): Record<AccordionVariantKey, string> {
16
- return defaultVariantKey === "collapsed"
17
- ? { collapsed: defaultStateClass, expanded: alternateStateClass }
18
- : { collapsed: alternateStateClass, expanded: defaultStateClass }
19
- }
20
-
21
- const expandedAccordionVariantKey: AccordionVariantKey =
22
- accordionDefaultVariantKey === "collapsed" ? "expanded" : "collapsed"
23
-
24
- const triggerStateClasses = buildVariantStateMap(
25
- accordionDefaultVariantKey,
26
- "",
27
- "[&[data-state=open]>svg]:rotate-180"
28
- )
29
-
30
- const contentStateClasses = buildVariantStateMap(
31
- accordionDefaultVariantKey,
32
- "data-[state=closed]:animate-accordion-up",
33
- "data-[state=open]:animate-accordion-down"
34
- )
35
-
36
- const Accordion = React.forwardRef<
37
- React.ElementRef<typeof AccordionPrimitive.Root>,
38
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Root>
39
- >(({ className, ...props }, ref) => (
40
- <AccordionPrimitive.Root
41
- ref={ref}
42
- className={cn("flex flex-col w-[400px] border", className)}
43
- {...props}
44
- />
45
- ))
46
- Accordion.displayName = AccordionPrimitive.Root.displayName
47
-
48
- const AccordionItem = React.forwardRef<
49
- React.ElementRef<typeof AccordionPrimitive.Item>,
50
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
51
- >(({ className, ...props }, ref) => (
52
- <AccordionPrimitive.Item
53
- ref={ref}
54
- className={cn("border-b", className)}
55
- {...props}
56
- />
57
- ))
58
- AccordionItem.displayName = "AccordionItem"
59
-
60
- const AccordionTrigger = React.forwardRef<
61
- React.ElementRef<typeof AccordionPrimitive.Trigger>,
62
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
63
- >(({ className, children, ...props }, ref) => (
64
- <AccordionPrimitive.Header className="flex">
65
- <AccordionPrimitive.Trigger
66
- ref={ref}
67
- className={cn(
68
- "flex flex-1 items-center justify-between px-4 py-4 text-sm font-medium transition-all hover:underline",
69
- triggerStateClasses[expandedAccordionVariantKey],
70
- className
71
- )}
72
- {...props}
73
- >
74
- {children}
75
- <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
76
- </AccordionPrimitive.Trigger>
77
- </AccordionPrimitive.Header>
78
- ))
79
- AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
80
-
81
- const AccordionContent = React.forwardRef<
82
- React.ElementRef<typeof AccordionPrimitive.Content>,
83
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
84
- >(({ className, children, ...props }, ref) => (
85
- <AccordionPrimitive.Content
86
- ref={ref}
87
- className={cn(
88
- "overflow-hidden text-sm text-muted-foreground transition-all",
89
- contentStateClasses[accordionDefaultVariantKey],
90
- contentStateClasses[expandedAccordionVariantKey]
91
- )}
92
- {...props}
93
- >
94
- <div className={cn("px-4 pb-4 pt-0", className)}>{children}</div>
95
- </AccordionPrimitive.Content>
96
- ))
97
- AccordionContent.displayName = AccordionPrimitive.Content.displayName
98
-
99
- export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
@@ -1,60 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { DayPicker } from "react-day-picker"
5
-
6
- import { cn } from "../../lib/utils"
7
-
8
- export type CalendarProps = React.ComponentProps<typeof DayPicker>
9
-
10
- function Calendar({
11
- className,
12
- classNames,
13
- showOutsideDays = true,
14
- ...props
15
- }: CalendarProps) {
16
- return (
17
- <DayPicker
18
- showOutsideDays={showOutsideDays}
19
- className={cn("flex flex-col w-[320px] rounded-md rounded-lg border bg-card p-4", className)}
20
- classNames={{
21
- months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0 relative",
22
- month: "space-y-4",
23
- caption: "flex justify-center pt-1 relative items-center w-full",
24
- month_caption: "flex justify-center pt-1 relative items-center w-full",
25
- caption_label: "text-sm font-semibold",
26
- nav: "absolute left-0 top-0 right-0 flex items-center justify-between px-1 pointer-events-none",
27
- nav_button: cn(
28
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 text-foreground pointer-events-auto hover:bg-accent rounded-md flex items-center justify-center transition-colors"
29
- ),
30
- nav_button_previous: "absolute left-1 top-1",
31
- nav_button_next: "absolute right-1 top-1",
32
- table: "w-full border-collapse space-y-1",
33
- head_row: "",
34
- head_cell:
35
- "text-muted-foreground rounded-md w-9 font-normal text-xs",
36
- row: "w-full mt-2",
37
- cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
38
- day: "h-9 w-9 p-0 font-normal aria-selected:opacity-100",
39
- day_button: cn(
40
- "h-9 w-9 p-0 font-normal aria-selected:opacity-100 hover:bg-accent/50 rounded-md flex items-center justify-center transition-colors"
41
- ),
42
- day_range_end: "day-range-end",
43
- day_selected:
44
- "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
45
- day_today: "bg-accent text-accent-foreground",
46
- day_outside:
47
- "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
48
- day_disabled: "text-muted-foreground opacity-50",
49
- day_range_middle:
50
- "aria-selected:bg-accent aria-selected:text-accent-foreground",
51
- day_hidden: "invisible",
52
- ...classNames,
53
- }}
54
- {...props}
55
- />
56
- )
57
- }
58
- Calendar.displayName = "Calendar"
59
-
60
- export { Calendar }