@7onic-ui/react 0.3.9 → 0.3.11

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 (170) hide show
  1. package/README.md +2 -2
  2. package/dist/chart.mjs +3 -9
  3. package/dist/chart.mjs.map +1 -1
  4. package/dist/chunk-2WIIXHOV.mjs +148 -0
  5. package/dist/chunk-2WIIXHOV.mjs.map +1 -0
  6. package/dist/chunk-53MIUPSY.mjs +13 -0
  7. package/dist/chunk-53MIUPSY.mjs.map +1 -0
  8. package/dist/chunk-BN5BEA3V.mjs +195 -0
  9. package/dist/chunk-BN5BEA3V.mjs.map +1 -0
  10. package/dist/chunk-C5D3VRNJ.mjs +504 -0
  11. package/dist/chunk-C5D3VRNJ.mjs.map +1 -0
  12. package/dist/chunk-COW3B62M.mjs +214 -0
  13. package/dist/chunk-COW3B62M.mjs.map +1 -0
  14. package/dist/chunk-CTH6SN5Y.mjs +114 -0
  15. package/dist/chunk-CTH6SN5Y.mjs.map +1 -0
  16. package/dist/chunk-D3NTQNDW.mjs +440 -0
  17. package/dist/chunk-D3NTQNDW.mjs.map +1 -0
  18. package/dist/chunk-DDRYEJBJ.mjs +164 -0
  19. package/dist/chunk-DDRYEJBJ.mjs.map +1 -0
  20. package/dist/chunk-DJAEXCRU.mjs +190 -0
  21. package/dist/chunk-DJAEXCRU.mjs.map +1 -0
  22. package/dist/chunk-DYYQOHQR.mjs +214 -0
  23. package/dist/chunk-DYYQOHQR.mjs.map +1 -0
  24. package/dist/chunk-EG2GTK65.mjs +443 -0
  25. package/dist/chunk-EG2GTK65.mjs.map +1 -0
  26. package/dist/chunk-FHUAH6AJ.mjs +93 -0
  27. package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
  28. package/dist/chunk-GD4YE5AE.mjs +209 -0
  29. package/dist/chunk-GD4YE5AE.mjs.map +1 -0
  30. package/dist/chunk-HHX4GABH.mjs +129 -0
  31. package/dist/chunk-HHX4GABH.mjs.map +1 -0
  32. package/dist/chunk-HS2VRYSX.mjs +148 -0
  33. package/dist/chunk-HS2VRYSX.mjs.map +1 -0
  34. package/dist/chunk-IHHI3LIN.mjs +155 -0
  35. package/dist/chunk-IHHI3LIN.mjs.map +1 -0
  36. package/dist/chunk-IJ2FZ3L5.mjs +159 -0
  37. package/dist/chunk-IJ2FZ3L5.mjs.map +1 -0
  38. package/dist/chunk-IPCIC2BI.mjs +148 -0
  39. package/dist/chunk-IPCIC2BI.mjs.map +1 -0
  40. package/dist/chunk-JCJEVXER.mjs +170 -0
  41. package/dist/chunk-JCJEVXER.mjs.map +1 -0
  42. package/dist/chunk-KBPYAMGS.mjs +157 -0
  43. package/dist/chunk-KBPYAMGS.mjs.map +1 -0
  44. package/dist/chunk-L55ABE4H.mjs +283 -0
  45. package/dist/chunk-L55ABE4H.mjs.map +1 -0
  46. package/dist/chunk-LJJ6K4IU.mjs +318 -0
  47. package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
  48. package/dist/chunk-ND6TUVP2.mjs +148 -0
  49. package/dist/chunk-ND6TUVP2.mjs.map +1 -0
  50. package/dist/chunk-NWFMJWGX.mjs +165 -0
  51. package/dist/chunk-NWFMJWGX.mjs.map +1 -0
  52. package/dist/chunk-PTAPPOKU.mjs +117 -0
  53. package/dist/chunk-PTAPPOKU.mjs.map +1 -0
  54. package/dist/chunk-PVTBM7V7.mjs +316 -0
  55. package/dist/chunk-PVTBM7V7.mjs.map +1 -0
  56. package/dist/chunk-Q5WVLK2L.mjs +77 -0
  57. package/dist/chunk-Q5WVLK2L.mjs.map +1 -0
  58. package/dist/chunk-R7FJEO4K.mjs +252 -0
  59. package/dist/chunk-R7FJEO4K.mjs.map +1 -0
  60. package/dist/chunk-RKSB2N5L.mjs +206 -0
  61. package/dist/chunk-RKSB2N5L.mjs.map +1 -0
  62. package/dist/chunk-S4DGVKBK.mjs +151 -0
  63. package/dist/chunk-S4DGVKBK.mjs.map +1 -0
  64. package/dist/chunk-S4T4PU7F.mjs +114 -0
  65. package/dist/chunk-S4T4PU7F.mjs.map +1 -0
  66. package/dist/chunk-SDDAGZWA.mjs +224 -0
  67. package/dist/chunk-SDDAGZWA.mjs.map +1 -0
  68. package/dist/chunk-SZPZOGPC.mjs +394 -0
  69. package/dist/chunk-SZPZOGPC.mjs.map +1 -0
  70. package/dist/chunk-T5A4APEL.mjs +140 -0
  71. package/dist/chunk-T5A4APEL.mjs.map +1 -0
  72. package/dist/chunk-V5UFWYFI.mjs +255 -0
  73. package/dist/chunk-V5UFWYFI.mjs.map +1 -0
  74. package/dist/chunk-W6YNEU53.mjs +175 -0
  75. package/dist/chunk-W6YNEU53.mjs.map +1 -0
  76. package/dist/chunk-XK52LYR4.mjs +182 -0
  77. package/dist/chunk-XK52LYR4.mjs.map +1 -0
  78. package/dist/chunk-YIAH6KHV.mjs +164 -0
  79. package/dist/chunk-YIAH6KHV.mjs.map +1 -0
  80. package/dist/chunk-YZ7HHFKA.mjs +375 -0
  81. package/dist/chunk-YZ7HHFKA.mjs.map +1 -0
  82. package/dist/chunk-ZDRUTJ4T.mjs +119 -0
  83. package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
  84. package/dist/components/accordion.mjs +19 -0
  85. package/dist/components/accordion.mjs.map +1 -0
  86. package/dist/components/alert.mjs +15 -0
  87. package/dist/components/alert.mjs.map +1 -0
  88. package/dist/components/avatar.mjs +23 -0
  89. package/dist/components/avatar.mjs.map +1 -0
  90. package/dist/components/badge.mjs +11 -0
  91. package/dist/components/badge.mjs.map +1 -0
  92. package/dist/components/breadcrumb.mjs +23 -0
  93. package/dist/components/breadcrumb.mjs.map +1 -0
  94. package/dist/components/button-group.mjs +11 -0
  95. package/dist/components/button-group.mjs.map +1 -0
  96. package/dist/components/button.mjs +12 -0
  97. package/dist/components/button.mjs.map +1 -0
  98. package/dist/components/card.mjs +25 -0
  99. package/dist/components/card.mjs.map +1 -0
  100. package/dist/components/chat-input.mjs +15 -0
  101. package/dist/components/chat-input.mjs.map +1 -0
  102. package/dist/components/chat-message.mjs +17 -0
  103. package/dist/components/chat-message.mjs.map +1 -0
  104. package/dist/components/checkbox.mjs +12 -0
  105. package/dist/components/checkbox.mjs.map +1 -0
  106. package/dist/components/divider.mjs +11 -0
  107. package/dist/components/divider.mjs.map +1 -0
  108. package/dist/components/drawer.mjs +33 -0
  109. package/dist/components/drawer.mjs.map +1 -0
  110. package/dist/components/dropdown.mjs +35 -0
  111. package/dist/components/dropdown.mjs.map +1 -0
  112. package/dist/components/field.mjs +19 -0
  113. package/dist/components/field.mjs.map +1 -0
  114. package/dist/components/icon-button.mjs +12 -0
  115. package/dist/components/icon-button.mjs.map +1 -0
  116. package/dist/components/input.mjs +12 -0
  117. package/dist/components/input.mjs.map +1 -0
  118. package/dist/components/metric-card.mjs +23 -0
  119. package/dist/components/metric-card.mjs.map +1 -0
  120. package/dist/components/modal.mjs +57 -0
  121. package/dist/components/modal.mjs.map +1 -0
  122. package/dist/components/navigation-menu.mjs +27 -0
  123. package/dist/components/navigation-menu.mjs.map +1 -0
  124. package/dist/components/pagination.mjs +33 -0
  125. package/dist/components/pagination.mjs.map +1 -0
  126. package/dist/components/popover.mjs +23 -0
  127. package/dist/components/popover.mjs.map +1 -0
  128. package/dist/components/progress.mjs +11 -0
  129. package/dist/components/progress.mjs.map +1 -0
  130. package/dist/components/quick-reply.mjs +15 -0
  131. package/dist/components/quick-reply.mjs.map +1 -0
  132. package/dist/components/radio-group.mjs +16 -0
  133. package/dist/components/radio-group.mjs.map +1 -0
  134. package/dist/components/segmented.mjs +15 -0
  135. package/dist/components/segmented.mjs.map +1 -0
  136. package/dist/components/select.mjs +24 -0
  137. package/dist/components/select.mjs.map +1 -0
  138. package/dist/components/skeleton.mjs +11 -0
  139. package/dist/components/skeleton.mjs.map +1 -0
  140. package/dist/components/slider.mjs +12 -0
  141. package/dist/components/slider.mjs.map +1 -0
  142. package/dist/components/spinner.mjs +11 -0
  143. package/dist/components/spinner.mjs.map +1 -0
  144. package/dist/components/switch.mjs +12 -0
  145. package/dist/components/switch.mjs.map +1 -0
  146. package/dist/components/table.mjs +23 -0
  147. package/dist/components/table.mjs.map +1 -0
  148. package/dist/components/tabs.mjs +19 -0
  149. package/dist/components/tabs.mjs.map +1 -0
  150. package/dist/components/textarea.mjs +12 -0
  151. package/dist/components/textarea.mjs.map +1 -0
  152. package/dist/components/toast.mjs +13 -0
  153. package/dist/components/toast.mjs.map +1 -0
  154. package/dist/components/toggle-group.mjs +15 -0
  155. package/dist/components/toggle-group.mjs.map +1 -0
  156. package/dist/components/toggle.mjs +11 -0
  157. package/dist/components/toggle.mjs.map +1 -0
  158. package/dist/components/tooltip.mjs +21 -0
  159. package/dist/components/tooltip.mjs.map +1 -0
  160. package/dist/components/typing-indicator.mjs +11 -0
  161. package/dist/components/typing-indicator.mjs.map +1 -0
  162. package/dist/index.d.ts +11 -2
  163. package/dist/index.js +95 -21
  164. package/dist/index.js.map +1 -1
  165. package/dist/index.mjs +296 -7536
  166. package/dist/index.mjs.map +1 -1
  167. package/llms.txt +50 -32
  168. package/package.json +14 -14
  169. package/dist/chart.d.mts +0 -147
  170. package/dist/index.d.mts +0 -1535
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/accordion.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as AccordionPrimitive from '@radix-ui/react-accordion'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// Default chevron icon (built-in, no external dependency)\nconst DefaultChevronIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n aria-hidden=\"true\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n)\n\n// Context to pass style props from Accordion root to children\ntype AccordionStyleContextValue = {\n variant?: 'default' | 'bordered' | 'splitted'\n size?: 'sm' | 'default' | 'lg'\n iconPosition?: 'left' | 'right'\n}\nconst AccordionStyleContext = React.createContext<AccordionStyleContextValue>({})\nconst useAccordionStyleContext = () => React.useContext(AccordionStyleContext)\n\n// ─── Accordion (Root) ────────────────────────────────────────\n\nconst accordionVariants = cva('w-full', {\n variants: {\n variant: {\n default: 'divide-y divide-border',\n bordered: 'divide-y divide-border border border-border rounded-xl',\n splitted: 'flex flex-col gap-3',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nexport interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {\n type?: 'single' | 'multiple'\n variant?: 'default' | 'bordered' | 'splitted'\n size?: 'sm' | 'default' | 'lg'\n iconPosition?: 'left' | 'right'\n collapsible?: boolean\n defaultValue?: string | string[]\n value?: string | string[]\n onValueChange?: ((value: string) => void) | ((value: string[]) => void)\n disabled?: boolean\n}\n\nconst Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(\n ({ className, variant = 'default', size = 'default', iconPosition = 'right', type = 'single', collapsible = true, defaultValue, value, onValueChange, disabled, ...props }, ref) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Radix single/multiple union type conflict\n const restProps = props as any\n const sharedClassName = cn(accordionVariants({ variant }), className)\n\n const radixProps = type === 'multiple'\n ? {\n type: 'multiple' as const,\n defaultValue: defaultValue as string[] | undefined,\n value: value as string[] | undefined,\n onValueChange: onValueChange as ((value: string[]) => void) | undefined,\n disabled,\n }\n : {\n type: 'single' as const,\n collapsible,\n defaultValue: defaultValue as string | undefined,\n value: value as string | undefined,\n onValueChange: onValueChange as ((value: string) => void) | undefined,\n disabled,\n }\n\n return (\n <AccordionStyleContext.Provider value={{ variant, size, iconPosition }}>\n <AccordionPrimitive.Root\n ref={ref}\n className={sharedClassName}\n {...radixProps}\n {...restProps}\n />\n </AccordionStyleContext.Provider>\n )\n }\n)\nAccordion.displayName = 'Accordion'\n\n// ─── AccordionItem ───────────────────────────────────────────\n\nconst accordionItemVariants = cva('', {\n variants: {\n variant: {\n default: '',\n bordered: '',\n splitted: 'border border-border rounded-xl',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nexport interface AccordionItemProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>,\n Omit<VariantProps<typeof accordionItemVariants>, 'variant'> {}\n\nconst AccordionItem = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Item>,\n AccordionItemProps\n>(({ className, ...props }, ref) => {\n const { variant } = useAccordionStyleContext()\n return (\n <AccordionPrimitive.Item\n ref={ref}\n className={cn(accordionItemVariants({ variant }), className)}\n {...props}\n />\n )\n})\nAccordionItem.displayName = 'AccordionItem'\n\n// ─── AccordionTrigger ────────────────────────────────────────\n\nconst accordionTriggerVariants = cva(\n [\n 'flex flex-1 items-center gap-3 font-semibold text-foreground',\n 'transition-all duration-micro ease-out cursor-pointer',\n 'hover:bg-background-muted/50',\n 'focus-visible:focus-ring focus-visible:rounded-md',\n 'disabled:pointer-events-none disabled:text-text-subtle disabled:opacity-50',\n '[&[data-state=open]>svg.accordion-chevron]:rotate-180',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'py-3 px-4 text-sm', // 13px\n default: 'py-4 px-4 text-md', // 14px\n lg: 'py-5 px-6 text-base', // 16px\n },\n iconPosition: {\n left: 'flex-row',\n right: 'flex-row-reverse justify-between',\n },\n },\n defaultVariants: {\n size: 'default',\n iconPosition: 'right',\n },\n }\n)\n\n// Icon size per trigger size\nconst triggerIconSizeClasses = {\n sm: 'icon-xs', // 14px\n default: 'icon-sm', // 16px\n lg: 'icon-sm', // 16px\n} as const\n\nexport interface AccordionTriggerProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> {\n /** Custom indicator icon (replaces default chevron) */\n icon?: React.ReactNode\n}\n\nconst AccordionTrigger = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\n AccordionTriggerProps\n>(({ className, children, icon, ...props }, ref) => {\n const { size, iconPosition } = useAccordionStyleContext()\n const resolvedSize = size || 'default'\n\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cn(\n 'group',\n accordionTriggerVariants({ size: resolvedSize, iconPosition }),\n className\n )}\n {...props}\n >\n {icon || (\n <DefaultChevronIcon className={cn(\n 'accordion-chevron shrink-0 text-text-muted transition-transform duration-normal',\n triggerIconSizeClasses[resolvedSize]\n )} />\n )}\n <span className=\"text-left\">{children}</span>\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n )\n})\nAccordionTrigger.displayName = 'AccordionTrigger'\n\n// ─── AccordionContent ────────────────────────────────────────\n\nconst accordionContentSizeClasses = {\n sm: 'px-4 pb-3 text-sm',\n default: 'px-4 pb-4 text-md',\n lg: 'px-6 pb-5 text-base',\n} as const\n\nexport interface AccordionContentProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> {}\n\nconst AccordionContent = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Content>,\n AccordionContentProps\n>(({ className, children, ...props }, ref) => {\n const { size } = useAccordionStyleContext()\n const resolvedSize = size || 'default'\n\n return (\n <AccordionPrimitive.Content\n ref={ref}\n className=\"overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n {...props}\n >\n <div className={cn(\n 'text-text-muted',\n accordionContentSizeClasses[resolvedSize],\n className\n )}>\n {children}\n </div>\n </AccordionPrimitive.Content>\n )\n})\nAccordionContent.displayName = 'AccordionContent'\n\n// ─── Exports ─────────────────────────────────────────────────\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n accordionVariants,\n accordionTriggerVariants,\n}\n"],"mappings":";;;;;;AAEA,YAAY,WAAW;AACvB,YAAY,wBAAwB;AACpC,SAAS,WAA8B;AAIvC,IAAM,qBAAqB,CAAC,EAAE,UAAU,MACtC;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,MAAK;AAAA,IACL,SAAQ;AAAA,IACR,QAAO;AAAA,IACP,aAAa;AAAA,IACb,eAAY;AAAA;AAAA,EAEZ,oCAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,GAAE,kBAAiB;AACxE;AASF,IAAM,wBAA8B,oBAA0C,CAAC,CAAC;AAChF,IAAM,2BAA2B,MAAY,iBAAW,qBAAqB;AAI7E,IAAM,oBAAoB,IAAI,UAAU;AAAA,EACtC,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,EACX;AACF,CAAC;AAcD,IAAM,YAAkB;AAAA,EACtB,CAAC,EAAE,WAAW,UAAU,WAAW,OAAO,WAAW,eAAe,SAAS,OAAO,UAAU,cAAc,MAAM,cAAc,OAAO,eAAe,UAAU,GAAG,MAAM,GAAG,QAAQ;AAElL,UAAM,YAAY;AAClB,UAAM,kBAAkB,GAAG,kBAAkB,EAAE,QAAQ,CAAC,GAAG,SAAS;AAEpE,UAAM,aAAa,SAAS,aACxB;AAAA,MACE,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IACA;AAAA,MACE,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEJ,WACE,oCAAC,sBAAsB,UAAtB,EAA+B,OAAO,EAAE,SAAS,MAAM,aAAa,KACjE;AAAA,MAAoB;AAAA,MAAnB;AAAA,QACD;AAAA,QACA,WAAW;AAAA,QACV,GAAG;AAAA,QACH,GAAG;AAAA;AAAA,IACN,CACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;AAIxB,IAAM,wBAAwB,IAAI,IAAI;AAAA,EACpC,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,EACX;AACF,CAAC;AAMD,IAAM,gBAAsB,iBAG1B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAClC,QAAM,EAAE,QAAQ,IAAI,yBAAyB;AAC7C,SACE;AAAA,IAAoB;AAAA,IAAnB;AAAA,MACC;AAAA,MACA,WAAW,GAAG,sBAAsB,EAAE,QAAQ,CAAC,GAAG,SAAS;AAAA,MAC1D,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AACD,cAAc,cAAc;AAI5B,IAAM,2BAA2B;AAAA,EAC/B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,IAAI;AAAA;AAAA,MACN;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,cAAc;AAAA,IAChB;AAAA,EACF;AACF;AAGA,IAAM,yBAAyB;AAAA,EAC7B,IAAI;AAAA;AAAA,EACJ,SAAS;AAAA;AAAA,EACT,IAAI;AAAA;AACN;AAQA,IAAM,mBAAyB,iBAG7B,CAAC,EAAE,WAAW,UAAU,MAAM,GAAG,MAAM,GAAG,QAAQ;AAClD,QAAM,EAAE,MAAM,aAAa,IAAI,yBAAyB;AACxD,QAAM,eAAe,QAAQ;AAE7B,SACE,oCAAoB,2BAAnB,EAA0B,WAAU,UACnC;AAAA,IAAoB;AAAA,IAAnB;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,yBAAyB,EAAE,MAAM,cAAc,aAAa,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,IAEH,QACC,oCAAC,sBAAmB,WAAW;AAAA,MAC7B;AAAA,MACA,uBAAuB,YAAY;AAAA,IACrC,GAAG;AAAA,IAEL,oCAAC,UAAK,WAAU,eAAa,QAAS;AAAA,EACxC,CACF;AAEJ,CAAC;AACD,iBAAiB,cAAc;AAI/B,IAAM,8BAA8B;AAAA,EAClC,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AACN;AAKA,IAAM,mBAAyB,iBAG7B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,GAAG,QAAQ;AAC5C,QAAM,EAAE,KAAK,IAAI,yBAAyB;AAC1C,QAAM,eAAe,QAAQ;AAE7B,SACE;AAAA,IAAoB;AAAA,IAAnB;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACT,GAAG;AAAA;AAAA,IAEJ,oCAAC,SAAI,WAAW;AAAA,MACd;AAAA,MACA,4BAA4B,YAAY;AAAA,MACxC;AAAA,IACF,KACG,QACH;AAAA,EACF;AAEJ,CAAC;AACD,iBAAiB,cAAc;","names":[]}
@@ -0,0 +1,164 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/toggle.tsx
7
+ import * as React from "react";
8
+ import * as TogglePrimitive from "@radix-ui/react-toggle";
9
+ import { cva } from "class-variance-authority";
10
+ var toggleBaseStyles = "inline-flex items-center justify-center text-text-muted transition-all duration-micro focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-50";
11
+ var toggleVariants = cva(
12
+ toggleBaseStyles,
13
+ {
14
+ variants: {
15
+ variant: {
16
+ default: "bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground",
17
+ outline: "border border-border bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground",
18
+ ghost: "bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground",
19
+ "outline-ghost": "border border-border bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground data-[state=on]:border-border"
20
+ },
21
+ fontWeight: {
22
+ normal: "font-normal",
23
+ semibold: "font-semibold"
24
+ },
25
+ size: {
26
+ xs: "h-7 px-2.5 text-xs gap-1",
27
+ // 28px height, 10px paddingX, 12px font
28
+ sm: "h-8 px-3 text-sm gap-2",
29
+ // 32px height, 12px paddingX, 13px font
30
+ md: "h-9 px-3.5 text-md gap-2",
31
+ // 36px height, 14px paddingX, 14px font
32
+ default: "h-10 px-4 text-md gap-2",
33
+ // 40px height, 16px paddingX, 14px font
34
+ lg: "h-12 px-6 text-base gap-2"
35
+ // 48px height, 24px paddingX, 16px font
36
+ },
37
+ radius: {
38
+ none: "rounded-none",
39
+ // 0px - primitive.borderRadius.none
40
+ sm: "rounded-sm",
41
+ // 2px - primitive.borderRadius.sm
42
+ base: "rounded",
43
+ // 4px - primitive.borderRadius.base
44
+ default: "rounded-md",
45
+ // 6px - primitive.borderRadius.md
46
+ lg: "rounded-lg",
47
+ // 8px - primitive.borderRadius.lg
48
+ xl: "rounded-xl",
49
+ // 12px - primitive.borderRadius.xl
50
+ "2xl": "rounded-2xl",
51
+ // 16px - primitive.borderRadius.2xl
52
+ "3xl": "rounded-3xl",
53
+ // 24px - primitive.borderRadius.3xl
54
+ full: "rounded-full"
55
+ // 9999px - primitive.borderRadius.full
56
+ }
57
+ },
58
+ defaultVariants: {
59
+ variant: "default",
60
+ size: "default",
61
+ radius: "default",
62
+ // 6px - primitive.borderRadius.md (Figma button default)
63
+ fontWeight: "normal"
64
+ }
65
+ }
66
+ );
67
+ var iconOnlySizes = {
68
+ xs: "h-7 w-7",
69
+ // 28px × 28px - spacing.7
70
+ sm: "h-8 w-8",
71
+ // 32px × 32px - spacing.8
72
+ md: "h-9 w-9",
73
+ // 36px × 36px - spacing.9
74
+ default: "h-10 w-10",
75
+ // 40px × 40px - spacing.10
76
+ lg: "h-12 w-12"
77
+ // 48px × 48px - spacing.12
78
+ };
79
+ var radiusClasses = {
80
+ none: "rounded-none",
81
+ sm: "rounded-sm",
82
+ base: "rounded",
83
+ default: "rounded-md",
84
+ lg: "rounded-lg",
85
+ xl: "rounded-xl",
86
+ "2xl": "rounded-2xl",
87
+ "3xl": "rounded-3xl",
88
+ full: "rounded-full"
89
+ };
90
+ var variantClasses = {
91
+ default: "bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground",
92
+ outline: "border border-border bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground",
93
+ ghost: "bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground",
94
+ "outline-ghost": "border border-border bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground data-[state=on]:border-border"
95
+ };
96
+ var iconSizeClasses = {
97
+ xs: "[&>svg]:icon-xs",
98
+ // 14px
99
+ sm: "[&>svg]:icon-xs",
100
+ // 14px
101
+ md: "[&>svg]:icon-sm",
102
+ // 16px
103
+ default: "[&>svg]:icon-sm",
104
+ // 16px
105
+ lg: "[&>svg]:icon-sm"
106
+ // 16px
107
+ };
108
+ var Toggle = React.forwardRef(({ className, variant, size, radius, fontWeight, iconOnly, pressEffect, ...props }, ref) => {
109
+ const sizeKey = size || "default";
110
+ const radiusKey = radius || "default";
111
+ const variantKey = variant || "default";
112
+ const fontWeightClass = fontWeight === "normal" ? "font-normal" : fontWeight === "semibold" ? "font-semibold" : "font-normal";
113
+ if (iconOnly) {
114
+ const iconOnlyIconSize = {
115
+ xs: "[&>svg]:icon-xs",
116
+ // 14px
117
+ sm: "[&>svg]:icon-sm",
118
+ // 16px
119
+ md: "[&>svg]:icon-sm",
120
+ // 16px
121
+ default: "[&>svg]:icon-md",
122
+ // 20px
123
+ lg: "[&>svg]:icon-lg"
124
+ // 24px
125
+ }[sizeKey];
126
+ return /* @__PURE__ */ React.createElement(
127
+ TogglePrimitive.Root,
128
+ {
129
+ ref,
130
+ className: cn(
131
+ toggleBaseStyles,
132
+ pressEffect !== false && "active:scale-pressed",
133
+ fontWeightClass,
134
+ variantClasses[variantKey],
135
+ iconOnlySizes[sizeKey],
136
+ radiusClasses[radiusKey],
137
+ iconOnlyIconSize,
138
+ className
139
+ ),
140
+ ...props
141
+ }
142
+ );
143
+ }
144
+ return /* @__PURE__ */ React.createElement(
145
+ TogglePrimitive.Root,
146
+ {
147
+ ref,
148
+ className: cn(
149
+ toggleVariants({ variant, size, radius, fontWeight }),
150
+ pressEffect !== false && "active:scale-pressed",
151
+ iconSizeClasses[sizeKey],
152
+ className
153
+ ),
154
+ ...props
155
+ }
156
+ );
157
+ });
158
+ Toggle.displayName = TogglePrimitive.Root.displayName;
159
+
160
+ export {
161
+ toggleVariants,
162
+ Toggle
163
+ };
164
+ //# sourceMappingURL=chunk-YIAH6KHV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/toggle.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TogglePrimitive from '@radix-ui/react-toggle'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// Base styles without size (for iconOnly mode)\nconst toggleBaseStyles = 'inline-flex items-center justify-center text-text-muted transition-all duration-micro focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-50'\n\nconst toggleVariants = cva(\n toggleBaseStyles,\n {\n variants: {\n variant: {\n default: 'bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground',\n outline: 'border border-border bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground',\n ghost: 'bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground',\n 'outline-ghost': 'border border-border bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground data-[state=on]:border-border',\n },\n fontWeight: {\n normal: 'font-normal',\n semibold: 'font-semibold',\n },\n size: {\n xs: 'h-7 px-2.5 text-xs gap-1', // 28px height, 10px paddingX, 12px font\n sm: 'h-8 px-3 text-sm gap-2', // 32px height, 12px paddingX, 13px font\n md: 'h-9 px-3.5 text-md gap-2', // 36px height, 14px paddingX, 14px font\n default: 'h-10 px-4 text-md gap-2', // 40px height, 16px paddingX, 14px font\n lg: 'h-12 px-6 text-base gap-2', // 48px height, 24px paddingX, 16px font\n },\n radius: {\n none: 'rounded-none', // 0px - primitive.borderRadius.none\n sm: 'rounded-sm', // 2px - primitive.borderRadius.sm\n base: 'rounded', // 4px - primitive.borderRadius.base\n default: 'rounded-md', // 6px - primitive.borderRadius.md\n lg: 'rounded-lg', // 8px - primitive.borderRadius.lg\n xl: 'rounded-xl', // 12px - primitive.borderRadius.xl\n '2xl': 'rounded-2xl', // 16px - primitive.borderRadius.2xl\n '3xl': 'rounded-3xl', // 24px - primitive.borderRadius.3xl\n full: 'rounded-full', // 9999px - primitive.borderRadius.full\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default', // 6px - primitive.borderRadius.md (Figma button default)\n fontWeight: 'normal',\n },\n }\n)\n\n// iconOnly sizes - square like IconButton (same width and height, no padding)\nconst iconOnlySizes = {\n xs: 'h-7 w-7', // 28px × 28px - spacing.7\n sm: 'h-8 w-8', // 32px × 32px - spacing.8\n md: 'h-9 w-9', // 36px × 36px - spacing.9\n default: 'h-10 w-10', // 40px × 40px - spacing.10\n lg: 'h-12 w-12', // 48px × 48px - spacing.12\n}\n\n// Radius classes for iconOnly mode\nconst radiusClasses = {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n}\n\n// Variant classes for iconOnly mode\nconst variantClasses = {\n default: 'bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground',\n outline: 'border border-border bg-transparent hover:bg-background-muted hover:text-foreground data-[state=on]:bg-background-muted data-[state=on]:text-foreground',\n ghost: 'bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground',\n 'outline-ghost': 'border border-border bg-transparent hover:text-foreground data-[state=on]:bg-transparent data-[state=on]:text-foreground data-[state=on]:border-border',\n}\n\nexport interface ToggleProps\n extends React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root>,\n Omit<VariantProps<typeof toggleVariants>, 'fontWeight'> {\n iconOnly?: boolean\n fontWeight?: 'normal' | 'semibold'\n pressEffect?: boolean\n}\n\n// Icon size for text+icon mode (5-step scale)\n// xs~sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n xs: '[&>svg]:icon-xs', // 14px\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nconst Toggle = React.forwardRef<\n React.ElementRef<typeof TogglePrimitive.Root>,\n ToggleProps\n>(({ className, variant, size, radius, fontWeight, iconOnly, pressEffect, ...props }, ref) => {\n const sizeKey = size || 'default'\n const radiusKey = radius || 'default'\n const variantKey = variant || 'default'\n const fontWeightClass = fontWeight === 'normal' ? 'font-normal' : fontWeight === 'semibold' ? 'font-semibold' : 'font-normal'\n\n // When iconOnly, build classes manually without padding\n if (iconOnly) {\n // Icon only uses larger icon sizes (like IconButton, 5-step scale)\n // XS: 14px, SM~MD: 16px, Default: 20px, LG: 24px\n const iconOnlyIconSize = {\n xs: '[&>svg]:icon-xs', // 14px\n sm: '[&>svg]:icon-sm', // 16px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-md', // 20px\n lg: '[&>svg]:icon-lg', // 24px\n }[sizeKey]\n\n return (\n <TogglePrimitive.Root\n ref={ref}\n className={cn(\n toggleBaseStyles,\n pressEffect !== false && 'active:scale-pressed',\n fontWeightClass,\n variantClasses[variantKey],\n iconOnlySizes[sizeKey],\n radiusClasses[radiusKey],\n iconOnlyIconSize,\n className\n )}\n {...props}\n />\n )\n }\n\n // Normal mode with padding\n return (\n <TogglePrimitive.Root\n ref={ref}\n className={cn(\n toggleVariants({ variant, size, radius, fontWeight }),\n pressEffect !== false && 'active:scale-pressed',\n iconSizeClasses[sizeKey],\n className\n )}\n {...props}\n />\n )\n})\n\nToggle.displayName = TogglePrimitive.Root.displayName\n\nexport { Toggle, toggleVariants }\n"],"mappings":"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","names":[]}
@@ -0,0 +1,375 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/chat-input.tsx
7
+ import * as React from "react";
8
+ import { cva } from "class-variance-authority";
9
+ var fieldPaddingMap = {
10
+ sm: "pt-2.5 px-3 text-md",
11
+ default: "pt-3 px-4 text-md",
12
+ lg: "pt-4 px-5 text-base"
13
+ };
14
+ var submitWrapperMap = {
15
+ sm: "px-2.5 pb-2.5",
16
+ default: "px-3 pb-3",
17
+ lg: "px-4 pb-4"
18
+ };
19
+ var submitSizeMap = {
20
+ sm: "h-7 w-7",
21
+ default: "h-8 w-8",
22
+ lg: "h-9 w-9"
23
+ };
24
+ var submitRadiusMap = {
25
+ sm: "rounded-md",
26
+ md: "rounded-md",
27
+ lg: "rounded-md",
28
+ xl: "rounded-lg",
29
+ "2xl": "rounded-xl",
30
+ full: "rounded-full"
31
+ };
32
+ var buttonRadiusClassMap = {
33
+ sm: "rounded-sm",
34
+ md: "rounded-md",
35
+ lg: "rounded-lg",
36
+ xl: "rounded-xl",
37
+ "2xl": "rounded-2xl",
38
+ full: "rounded-full"
39
+ };
40
+ var submitIconSizeMap = {
41
+ sm: "icon-xs",
42
+ default: "icon-xs",
43
+ lg: "icon-sm"
44
+ };
45
+ var countStyleMap = {
46
+ sm: "text-xs",
47
+ default: "text-xs",
48
+ lg: "text-sm"
49
+ };
50
+ var lineHeightMap = {
51
+ sm: 20,
52
+ default: 22,
53
+ lg: 24
54
+ };
55
+ var inlineFieldPaddingMap = {
56
+ sm: "px-3 text-md",
57
+ default: "px-4 text-md",
58
+ lg: "px-5 text-base"
59
+ };
60
+ var submitWrapperInlineMap = {
61
+ sm: "px-2.5 py-2.5",
62
+ default: "px-3 py-3",
63
+ lg: "px-4 py-4"
64
+ };
65
+ var chatInputVariants = cva(
66
+ [
67
+ "flex flex-col w-full overflow-hidden cursor-text",
68
+ "transition-colors duration-micro"
69
+ ].join(" "),
70
+ {
71
+ variants: {
72
+ variant: {
73
+ outline: [
74
+ "border border-border bg-background",
75
+ "hover:border-border-strong",
76
+ "focus-within:border-border-strong focus-within:hover:border-border-strong"
77
+ ].join(" "),
78
+ filled: [
79
+ "border border-transparent bg-background-muted",
80
+ "focus-within:border-border"
81
+ ].join(" ")
82
+ },
83
+ radius: {
84
+ sm: "rounded-sm",
85
+ md: "rounded-md",
86
+ lg: "rounded-lg",
87
+ xl: "rounded-xl",
88
+ "2xl": "rounded-2xl",
89
+ full: "rounded-full"
90
+ }
91
+ },
92
+ defaultVariants: {
93
+ variant: "outline",
94
+ radius: "xl"
95
+ }
96
+ }
97
+ );
98
+ var ChatInputContext = React.createContext({
99
+ size: "default",
100
+ color: "default",
101
+ layout: "default",
102
+ radius: "xl",
103
+ disabled: false,
104
+ isEmpty: true,
105
+ charCount: 0,
106
+ showCount: false,
107
+ maxLength: void 0,
108
+ _setIsEmpty: () => {
109
+ },
110
+ _setCharCount: () => {
111
+ },
112
+ _setShowCount: () => {
113
+ },
114
+ _setMaxLength: () => {
115
+ },
116
+ _fieldRef: { current: null },
117
+ _handleSubmit: () => {
118
+ }
119
+ });
120
+ var ChatInput = React.forwardRef(
121
+ ({
122
+ className,
123
+ variant = "outline",
124
+ radius = "xl",
125
+ size = "default",
126
+ color = "default",
127
+ layout = "default",
128
+ disabled = false,
129
+ onSubmit,
130
+ children,
131
+ ...props
132
+ }, ref) => {
133
+ const [isEmpty, setIsEmpty] = React.useState(true);
134
+ const [charCount, setCharCount] = React.useState(0);
135
+ const [showCount, setShowCount] = React.useState(false);
136
+ const [maxLength, setMaxLength] = React.useState(void 0);
137
+ const fieldRef = React.useRef(null);
138
+ const handleSubmit = React.useCallback(() => {
139
+ const el = fieldRef.current;
140
+ if (!el || disabled) return;
141
+ const value = el.value.trim();
142
+ if (!value) return;
143
+ onSubmit?.(value);
144
+ el.value = "";
145
+ el.style.height = "auto";
146
+ setIsEmpty(true);
147
+ setCharCount(0);
148
+ }, [disabled, onSubmit]);
149
+ const contextValue = React.useMemo(
150
+ () => ({
151
+ size,
152
+ color,
153
+ layout,
154
+ radius,
155
+ disabled,
156
+ isEmpty,
157
+ charCount,
158
+ showCount,
159
+ maxLength,
160
+ _setIsEmpty: setIsEmpty,
161
+ _setCharCount: setCharCount,
162
+ _setShowCount: setShowCount,
163
+ _setMaxLength: setMaxLength,
164
+ _fieldRef: fieldRef,
165
+ _handleSubmit: handleSubmit
166
+ }),
167
+ [size, color, layout, radius, disabled, isEmpty, charCount, showCount, maxLength, handleSubmit]
168
+ );
169
+ const handleContainerClick = React.useCallback(
170
+ (e) => {
171
+ if (!disabled && !e.target.closest("button")) {
172
+ fieldRef.current?.focus();
173
+ }
174
+ },
175
+ [disabled]
176
+ );
177
+ return /* @__PURE__ */ React.createElement(ChatInputContext.Provider, { value: contextValue }, /* @__PURE__ */ React.createElement(
178
+ "div",
179
+ {
180
+ ref,
181
+ "data-disabled": disabled || void 0,
182
+ onClick: handleContainerClick,
183
+ className: cn(
184
+ chatInputVariants({ variant, radius }),
185
+ layout === "inline" && "flex-row",
186
+ disabled && "opacity-50 pointer-events-none",
187
+ className
188
+ ),
189
+ ...props
190
+ },
191
+ children
192
+ ));
193
+ }
194
+ );
195
+ ChatInput.displayName = "ChatInput";
196
+ function assignRef(ref, value) {
197
+ if (typeof ref === "function") ref(value);
198
+ else if (ref) ref.current = value;
199
+ }
200
+ var ChatInputField = React.forwardRef(
201
+ ({
202
+ className,
203
+ maxRows = 8,
204
+ showCount = false,
205
+ maxLength,
206
+ placeholder,
207
+ onChange,
208
+ onKeyDown,
209
+ disabled,
210
+ ...props
211
+ }, forwardedRef) => {
212
+ const ctx = React.useContext(ChatInputContext);
213
+ const internalRef = React.useRef(null);
214
+ const isDisabled = disabled ?? ctx.disabled;
215
+ React.useEffect(() => {
216
+ ctx._setShowCount(showCount);
217
+ ctx._setMaxLength(maxLength);
218
+ }, [showCount, maxLength]);
219
+ const setRef = React.useCallback(
220
+ (el) => {
221
+ internalRef.current = el;
222
+ assignRef(ctx._fieldRef, el);
223
+ assignRef(forwardedRef, el);
224
+ },
225
+ // eslint-disable-next-line react-hooks/exhaustive-deps
226
+ [forwardedRef]
227
+ );
228
+ const autoResize = React.useCallback(() => {
229
+ const el = internalRef.current;
230
+ if (!el) return;
231
+ el.style.height = "auto";
232
+ const maxHeight = maxRows * lineHeightMap[ctx.size];
233
+ const newHeight = Math.min(el.scrollHeight, maxHeight);
234
+ el.style.height = `${newHeight}px`;
235
+ el.style.overflowY = el.scrollHeight > maxHeight ? "auto" : "hidden";
236
+ }, [ctx.size, maxRows]);
237
+ const handleChange = React.useCallback(
238
+ (e) => {
239
+ const val = e.target.value;
240
+ ctx._setIsEmpty(val.trim() === "");
241
+ ctx._setCharCount(val.length);
242
+ autoResize();
243
+ onChange?.(e);
244
+ },
245
+ [ctx, autoResize, onChange]
246
+ );
247
+ const handleKeyDown = React.useCallback(
248
+ (e) => {
249
+ if (e.key === "Enter" && !e.shiftKey) {
250
+ e.preventDefault();
251
+ ctx._handleSubmit();
252
+ }
253
+ onKeyDown?.(e);
254
+ },
255
+ [ctx, onKeyDown]
256
+ );
257
+ return /* @__PURE__ */ React.createElement("div", { className: cn("flex-1 min-w-0", ctx.layout === "inline" && "flex items-center self-stretch") }, /* @__PURE__ */ React.createElement(
258
+ "textarea",
259
+ {
260
+ ref: setRef,
261
+ rows: 1,
262
+ placeholder,
263
+ maxLength,
264
+ disabled: isDisabled,
265
+ className: cn(
266
+ "w-full bg-transparent text-foreground placeholder:text-foreground/30",
267
+ "resize-none outline-none focus:outline-none",
268
+ "disabled:cursor-not-allowed",
269
+ "overflow-hidden",
270
+ ctx.layout === "inline" ? inlineFieldPaddingMap[ctx.size] : fieldPaddingMap[ctx.size],
271
+ className
272
+ ),
273
+ onChange: handleChange,
274
+ onKeyDown: handleKeyDown,
275
+ ...props
276
+ }
277
+ ));
278
+ }
279
+ );
280
+ ChatInputField.displayName = "ChatInputField";
281
+ var ChatInputSubmit = React.forwardRef(
282
+ ({
283
+ className,
284
+ loading = false,
285
+ onStop,
286
+ children,
287
+ disabled,
288
+ onClick,
289
+ buttonRadius,
290
+ ...props
291
+ }, ref) => {
292
+ const ctx = React.useContext(ChatInputContext);
293
+ const isDisabled = (disabled ?? ctx.disabled) || !loading && ctx.isEmpty;
294
+ const handleClick = React.useCallback(
295
+ (e) => {
296
+ if (loading) {
297
+ onStop?.();
298
+ } else if (!isDisabled) {
299
+ ctx._handleSubmit();
300
+ }
301
+ onClick?.(e);
302
+ },
303
+ [ctx, isDisabled, loading, onStop, onClick]
304
+ );
305
+ return /* @__PURE__ */ React.createElement("div", { className: cn("flex items-center justify-end gap-2 shrink-0 cursor-default", ctx.layout === "inline" ? submitWrapperInlineMap[ctx.size] : submitWrapperMap[ctx.size]) }, ctx.showCount && ctx.maxLength != null && /* @__PURE__ */ React.createElement("span", { className: cn("text-text-subtle select-none", countStyleMap[ctx.size]) }, ctx.charCount, " / ", ctx.maxLength), /* @__PURE__ */ React.createElement(
306
+ "button",
307
+ {
308
+ ref,
309
+ type: "button",
310
+ disabled: isDisabled && !loading,
311
+ "aria-label": loading ? "Stop generating" : "Send message",
312
+ className: cn(
313
+ "inline-flex items-center justify-center shrink-0",
314
+ buttonRadius ? buttonRadiusClassMap[buttonRadius] : submitRadiusMap[ctx.radius],
315
+ "transition-all duration-fast",
316
+ "focus-visible:outline-none focus-visible:focus-ring",
317
+ submitSizeMap[ctx.size],
318
+ // Loading state — enabled, pulsing
319
+ loading && ctx.color === "default" && "bg-foreground text-background animate-pulse cursor-pointer",
320
+ loading && ctx.color === "primary" && "bg-primary text-primary-foreground animate-pulse cursor-pointer",
321
+ // Enabled state
322
+ !loading && !isDisabled && ctx.color === "default" && [
323
+ "bg-foreground text-background",
324
+ "hover:bg-foreground/90 active:bg-foreground/80 active:scale-pressed cursor-pointer"
325
+ ],
326
+ !loading && !isDisabled && ctx.color === "primary" && [
327
+ "bg-primary text-primary-foreground",
328
+ "hover:bg-primary-hover active:scale-pressed cursor-pointer"
329
+ ],
330
+ // Disabled state
331
+ !loading && isDisabled && "bg-background-muted text-text-subtle pointer-events-none",
332
+ className
333
+ ),
334
+ onClick: handleClick,
335
+ ...props
336
+ },
337
+ /* @__PURE__ */ React.createElement(
338
+ "span",
339
+ {
340
+ "aria-hidden": "true",
341
+ className: cn("flex items-center justify-center", submitIconSizeMap[ctx.size])
342
+ },
343
+ children ?? (loading ? /* @__PURE__ */ React.createElement(StopIcon, null) : /* @__PURE__ */ React.createElement(SendIcon, null))
344
+ )
345
+ ));
346
+ }
347
+ );
348
+ ChatInputSubmit.displayName = "ChatInputSubmit";
349
+ function SendIcon() {
350
+ return /* @__PURE__ */ React.createElement(
351
+ "svg",
352
+ {
353
+ viewBox: "0 0 24 24",
354
+ fill: "none",
355
+ stroke: "currentColor",
356
+ strokeWidth: 2.5,
357
+ strokeLinecap: "round",
358
+ strokeLinejoin: "round",
359
+ className: "w-full h-full"
360
+ },
361
+ /* @__PURE__ */ React.createElement("path", { d: "M22 2 11 13" }),
362
+ /* @__PURE__ */ React.createElement("path", { d: "M22 2 15 22 11 13 2 9l20-7Z" })
363
+ );
364
+ }
365
+ function StopIcon() {
366
+ return /* @__PURE__ */ React.createElement("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: "w-full h-full" }, /* @__PURE__ */ React.createElement("rect", { x: "5", y: "5", width: "14", height: "14", rx: "2" }));
367
+ }
368
+
369
+ export {
370
+ chatInputVariants,
371
+ ChatInput,
372
+ ChatInputField,
373
+ ChatInputSubmit
374
+ };
375
+ //# sourceMappingURL=chunk-YZ7HHFKA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/chat-input.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ============================================================================\n// Size maps\n// ============================================================================\n\n/** Textarea padding per size */\nconst fieldPaddingMap = {\n sm: 'pt-2.5 px-3 text-md',\n default: 'pt-3 px-4 text-md',\n lg: 'pt-4 px-5 text-base',\n} as const\n\n/** Submit row padding per size */\nconst submitWrapperMap = {\n sm: 'px-2.5 pb-2.5',\n default: 'px-3 pb-3',\n lg: 'px-4 pb-4',\n} as const\n\n/** Submit button dimensions per size */\nconst submitSizeMap = {\n sm: 'h-7 w-7',\n default: 'h-8 w-8',\n lg: 'h-9 w-9',\n} as const\n\n/** Submit button radius — auto-calculated from container radius (min rounded-md) */\nconst submitRadiusMap = {\n sm: 'rounded-md',\n md: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n full: 'rounded-full',\n} as const\n\n/** Submit button radius — direct class map for explicit buttonRadius prop */\nconst buttonRadiusClassMap: Record<ChatInputRadius, string> = {\n sm: 'rounded-sm',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n full: 'rounded-full',\n}\n\n/** Submit icon size class per size */\nconst submitIconSizeMap = {\n sm: 'icon-xs',\n default: 'icon-xs',\n lg: 'icon-sm',\n} as const\n\n/** Character count text size per size */\nconst countStyleMap = {\n sm: 'text-xs',\n default: 'text-xs',\n lg: 'text-sm',\n} as const\n\n/** Approximate line-height (px) per size for auto-resize */\nconst lineHeightMap = {\n sm: 20,\n default: 22,\n lg: 24,\n} as const\n\n/** Field padding in inline layout — horizontal only (vertical centering via flex) */\nconst inlineFieldPaddingMap = {\n sm: 'px-3 text-md',\n default: 'px-4 text-md',\n lg: 'px-5 text-base',\n} as const\n\n/** Submit wrapper padding in inline layout — symmetric vertical */\nconst submitWrapperInlineMap = {\n sm: 'px-2.5 py-2.5',\n default: 'px-3 py-3',\n lg: 'px-4 py-4',\n} as const\n\n// ============================================================================\n// CVA — root container variants\n// ============================================================================\n\nconst chatInputVariants = cva(\n [\n 'flex flex-col w-full overflow-hidden cursor-text',\n 'transition-colors duration-micro',\n ].join(' '),\n {\n variants: {\n variant: {\n outline: [\n 'border border-border bg-background',\n 'hover:border-border-strong',\n 'focus-within:border-border-strong focus-within:hover:border-border-strong',\n ].join(' '),\n filled: [\n 'border border-transparent bg-background-muted',\n 'focus-within:border-border',\n ].join(' '),\n },\n radius: {\n sm: 'rounded-sm',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n full: 'rounded-full',\n },\n },\n defaultVariants: {\n variant: 'outline',\n radius: 'xl',\n },\n }\n)\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type ChatInputSize = 'sm' | 'default' | 'lg'\nexport type ChatInputVariant = 'outline' | 'filled'\nexport type ChatInputRadius = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\nexport type ChatInputColor = 'default' | 'primary'\nexport type ChatInputLayout = 'default' | 'inline'\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface ChatInputContextValue {\n size: ChatInputSize\n color: ChatInputColor\n layout: ChatInputLayout\n radius: ChatInputRadius\n disabled: boolean\n isEmpty: boolean\n charCount: number\n showCount: boolean\n maxLength: number | undefined\n _setIsEmpty: React.Dispatch<React.SetStateAction<boolean>>\n _setCharCount: React.Dispatch<React.SetStateAction<number>>\n _setShowCount: React.Dispatch<React.SetStateAction<boolean>>\n _setMaxLength: React.Dispatch<React.SetStateAction<number | undefined>>\n _fieldRef: React.MutableRefObject<HTMLTextAreaElement | null>\n _handleSubmit: () => void\n}\n\nconst ChatInputContext = React.createContext<ChatInputContextValue>({\n size: 'default',\n color: 'default',\n layout: 'default',\n radius: 'xl',\n disabled: false,\n isEmpty: true,\n charCount: 0,\n showCount: false,\n maxLength: undefined,\n _setIsEmpty: () => {},\n _setCharCount: () => {},\n _setShowCount: () => {},\n _setMaxLength: () => {},\n _fieldRef: { current: null },\n _handleSubmit: () => {},\n})\n\n// ============================================================================\n// Props interfaces\n// ============================================================================\n\nexport interface ChatInputRootProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSubmit'>,\n VariantProps<typeof chatInputVariants> {\n /** Visual style of the container */\n variant?: ChatInputVariant\n /** Corner radius */\n radius?: ChatInputRadius\n /** Size scale */\n size?: ChatInputSize\n /** Submit button color — default (dark) or primary (brand) */\n color?: ChatInputColor\n /** Layout direction — default (stacked) or inline (field + button side by side) */\n layout?: ChatInputLayout\n /** Disable all interaction */\n disabled?: boolean\n /** Called when the user submits (Enter key or Submit button) — receives current field value */\n onSubmit?: (value: string) => void\n}\n\nexport interface ChatInputFieldProps\n extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'children'> {\n /** Maximum visible rows before the field scrolls */\n maxRows?: number\n /** Show character counter — requires maxLength to be set */\n showCount?: boolean\n}\n\nexport interface ChatInputSubmitProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Show loading/stop state — keeps button enabled so user can stop generation */\n loading?: boolean\n /** Called when clicked during loading state (e.g., stop generation) */\n onStop?: () => void\n /** Override the auto-calculated button radius */\n buttonRadius?: ChatInputRadius\n}\n\n// ============================================================================\n// ChatInput — Root container\n// ============================================================================\n\nconst ChatInput = React.forwardRef<HTMLDivElement, ChatInputRootProps>(\n (\n {\n className,\n variant = 'outline',\n radius = 'xl',\n size = 'default',\n color = 'default',\n layout = 'default',\n disabled = false,\n onSubmit,\n children,\n ...props\n },\n ref\n ) => {\n const [isEmpty, setIsEmpty] = React.useState(true)\n const [charCount, setCharCount] = React.useState(0)\n const [showCount, setShowCount] = React.useState(false)\n const [maxLength, setMaxLength] = React.useState<number | undefined>(undefined)\n const fieldRef = React.useRef<HTMLTextAreaElement | null>(null)\n\n const handleSubmit = React.useCallback(() => {\n const el = fieldRef.current\n if (!el || disabled) return\n const value = el.value.trim()\n if (!value) return\n onSubmit?.(value)\n // Auto-clear in uncontrolled mode\n // Controlled-mode users should clear value inside their onSubmit callback\n el.value = ''\n el.style.height = 'auto'\n setIsEmpty(true)\n setCharCount(0)\n }, [disabled, onSubmit])\n\n const contextValue = React.useMemo<ChatInputContextValue>(\n () => ({\n size,\n color,\n layout,\n radius,\n disabled,\n isEmpty,\n charCount,\n showCount,\n maxLength,\n _setIsEmpty: setIsEmpty,\n _setCharCount: setCharCount,\n _setShowCount: setShowCount,\n _setMaxLength: setMaxLength,\n _fieldRef: fieldRef,\n _handleSubmit: handleSubmit,\n }),\n [size, color, layout, radius, disabled, isEmpty, charCount, showCount, maxLength, handleSubmit]\n )\n\n const handleContainerClick = React.useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n // Focus the textarea when clicking anywhere in the container (not on a button)\n if (!disabled && !(e.target as HTMLElement).closest('button')) {\n fieldRef.current?.focus()\n }\n },\n [disabled]\n )\n\n return (\n <ChatInputContext.Provider value={contextValue}>\n <div\n ref={ref}\n data-disabled={disabled || undefined}\n onClick={handleContainerClick}\n className={cn(\n chatInputVariants({ variant, radius }),\n layout === 'inline' && 'flex-row',\n disabled && 'opacity-50 pointer-events-none',\n className\n )}\n {...props}\n >\n {children}\n </div>\n </ChatInputContext.Provider>\n )\n }\n)\nChatInput.displayName = 'ChatInput'\n\n// Writes a node into a callback or object ref. Kept outside the component: React\n// Compiler rules flag assigning `.current` on refs that come from props or context.\nfunction assignRef<T>(ref: React.Ref<T> | undefined, value: T | null) {\n if (typeof ref === 'function') ref(value)\n else if (ref) (ref as React.MutableRefObject<T | null>).current = value\n}\n\n// ============================================================================\n// ChatInputField — Auto-resizing textarea\n// ============================================================================\n\nconst ChatInputField = React.forwardRef<HTMLTextAreaElement, ChatInputFieldProps>(\n (\n {\n className,\n maxRows = 8,\n showCount = false,\n maxLength,\n placeholder,\n onChange,\n onKeyDown,\n disabled,\n ...props\n },\n forwardedRef\n ) => {\n const ctx = React.useContext(ChatInputContext)\n const internalRef = React.useRef<HTMLTextAreaElement | null>(null)\n const isDisabled = disabled ?? ctx.disabled\n\n // Sync showCount + maxLength into root context on mount/update\n React.useEffect(() => {\n ctx._setShowCount(showCount)\n ctx._setMaxLength(maxLength)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [showCount, maxLength])\n\n // Merge forwarded ref + internal ref + context field ref\n const setRef = React.useCallback(\n (el: HTMLTextAreaElement | null) => {\n internalRef.current = el\n assignRef(ctx._fieldRef, el)\n assignRef(forwardedRef, el)\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [forwardedRef]\n )\n\n // Adjust textarea height to content, bounded by maxRows\n const autoResize = React.useCallback(() => {\n const el = internalRef.current\n if (!el) return\n el.style.height = 'auto'\n const maxHeight = maxRows * lineHeightMap[ctx.size]\n const newHeight = Math.min(el.scrollHeight, maxHeight)\n el.style.height = `${newHeight}px`\n el.style.overflowY = el.scrollHeight > maxHeight ? 'auto' : 'hidden'\n }, [ctx.size, maxRows])\n\n const handleChange = React.useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const val = e.target.value\n ctx._setIsEmpty(val.trim() === '')\n ctx._setCharCount(val.length)\n autoResize()\n onChange?.(e)\n },\n [ctx, autoResize, onChange]\n )\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n // Enter = submit | Shift+Enter = new line\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n ctx._handleSubmit()\n }\n onKeyDown?.(e)\n },\n [ctx, onKeyDown]\n )\n\n return (\n <div className={cn('flex-1 min-w-0', ctx.layout === 'inline' && 'flex items-center self-stretch')}>\n <textarea\n ref={setRef}\n rows={1}\n placeholder={placeholder}\n maxLength={maxLength}\n disabled={isDisabled}\n className={cn(\n 'w-full bg-transparent text-foreground placeholder:text-foreground/30',\n 'resize-none outline-none focus:outline-none',\n 'disabled:cursor-not-allowed',\n 'overflow-hidden',\n ctx.layout === 'inline' ? inlineFieldPaddingMap[ctx.size] : fieldPaddingMap[ctx.size],\n className\n )}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n />\n </div>\n )\n }\n)\nChatInputField.displayName = 'ChatInputField'\n\n// ============================================================================\n// ChatInputSubmit — Send / stop button\n// ============================================================================\n\nconst ChatInputSubmit = React.forwardRef<HTMLButtonElement, ChatInputSubmitProps>(\n (\n {\n className,\n loading = false,\n onStop,\n children,\n disabled,\n onClick,\n buttonRadius,\n ...props\n },\n ref\n ) => {\n const ctx = React.useContext(ChatInputContext)\n\n // Disabled: context disabled | user prop | empty field (only when not loading)\n const isDisabled = (disabled ?? ctx.disabled) || (!loading && ctx.isEmpty)\n\n const handleClick = React.useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (loading) {\n onStop?.()\n } else if (!isDisabled) {\n ctx._handleSubmit()\n }\n onClick?.(e)\n },\n [ctx, isDisabled, loading, onStop, onClick]\n )\n\n return (\n <div className={cn('flex items-center justify-end gap-2 shrink-0 cursor-default', ctx.layout === 'inline' ? submitWrapperInlineMap[ctx.size] : submitWrapperMap[ctx.size])}>\n {ctx.showCount && ctx.maxLength != null && (\n <span className={cn('text-text-subtle select-none', countStyleMap[ctx.size])}>\n {ctx.charCount} / {ctx.maxLength}\n </span>\n )}\n <button\n ref={ref}\n type=\"button\"\n disabled={isDisabled && !loading}\n aria-label={loading ? 'Stop generating' : 'Send message'}\n className={cn(\n 'inline-flex items-center justify-center shrink-0',\n buttonRadius ? buttonRadiusClassMap[buttonRadius] : submitRadiusMap[ctx.radius],\n 'transition-all duration-fast',\n 'focus-visible:outline-none focus-visible:focus-ring',\n submitSizeMap[ctx.size],\n // Loading state — enabled, pulsing\n loading && ctx.color === 'default' && 'bg-foreground text-background animate-pulse cursor-pointer',\n loading && ctx.color === 'primary' && 'bg-primary text-primary-foreground animate-pulse cursor-pointer',\n // Enabled state\n !loading && !isDisabled && ctx.color === 'default' && [\n 'bg-foreground text-background',\n 'hover:bg-foreground/90 active:bg-foreground/80 active:scale-pressed cursor-pointer',\n ],\n !loading && !isDisabled && ctx.color === 'primary' && [\n 'bg-primary text-primary-foreground',\n 'hover:bg-primary-hover active:scale-pressed cursor-pointer',\n ],\n // Disabled state\n !loading && isDisabled && 'bg-background-muted text-text-subtle pointer-events-none',\n className\n )}\n onClick={handleClick}\n {...props}\n >\n <span\n aria-hidden=\"true\"\n className={cn('flex items-center justify-center', submitIconSizeMap[ctx.size])}\n >\n {children ?? (loading ? <StopIcon /> : <SendIcon />)}\n </span>\n </button>\n </div>\n )\n }\n)\nChatInputSubmit.displayName = 'ChatInputSubmit'\n\n// ============================================================================\n// Built-in SVG icons — no external icon dependency\n// ============================================================================\n\nfunction SendIcon() {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"w-full h-full\"\n >\n <path d=\"M22 2 11 13\" />\n <path d=\"M22 2 15 22 11 13 2 9l20-7Z\" />\n </svg>\n )\n}\n\nfunction StopIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" className=\"w-full h-full\">\n <rect x=\"5\" y=\"5\" width=\"14\" height=\"14\" rx=\"2\" />\n </svg>\n )\n}\n\nexport {\n ChatInput,\n ChatInputField,\n ChatInputSubmit,\n chatInputVariants,\n}\n"],"mappings":"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","names":[]}