@intlayer/design-system 8.11.3 → 8.12.0-canary.0

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 (259) hide show
  1. package/dist/esm/api/hooks/project.mjs +110 -1
  2. package/dist/esm/api/hooks/project.mjs.map +1 -1
  3. package/dist/esm/api/index.mjs +2 -2
  4. package/dist/esm/api/useAuth/useOAuth2.mjs +1 -1
  5. package/dist/esm/api/useIntlayerAPI.mjs +1 -1
  6. package/dist/esm/components/Accordion/Accordion.mjs.map +1 -1
  7. package/dist/esm/components/Badge/index.mjs +18 -55
  8. package/dist/esm/components/Badge/index.mjs.map +1 -1
  9. package/dist/esm/components/Breadcrumb/index.mjs +12 -12
  10. package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
  11. package/dist/esm/components/Browser/Browser.mjs +1 -1
  12. package/dist/esm/components/Browser/Browser.mjs.map +1 -1
  13. package/dist/esm/components/Button/Button.mjs +60 -117
  14. package/dist/esm/components/Button/Button.mjs.map +1 -1
  15. package/dist/esm/components/Button/index.mjs +2 -2
  16. package/dist/esm/components/Carousel/index.mjs +3 -3
  17. package/dist/esm/components/Carousel/index.mjs.map +1 -1
  18. package/dist/esm/components/Container/index.mjs +1 -71
  19. package/dist/esm/components/Container/index.mjs.map +1 -1
  20. package/dist/esm/components/ContentEditor/ContentEditor.mjs +0 -1
  21. package/dist/esm/components/ContentEditor/ContentEditor.mjs.map +1 -1
  22. package/dist/esm/components/ContentEditor/ContentEditorInput.mjs +2 -2
  23. package/dist/esm/components/ContentEditor/ContentEditorInput.mjs.map +1 -1
  24. package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +2 -2
  25. package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs.map +1 -1
  26. package/dist/esm/components/ContentEditor/index.mjs +1 -1
  27. package/dist/esm/components/CopyButton/index.mjs +4 -4
  28. package/dist/esm/components/CopyButton/index.mjs.map +1 -1
  29. package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +6 -7
  30. package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs.map +1 -1
  31. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +0 -1
  32. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs.map +1 -1
  33. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +3 -4
  34. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs.map +1 -1
  35. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +3 -3
  36. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs.map +1 -1
  37. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +3 -3
  38. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs.map +1 -1
  39. package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +2 -3
  40. package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs.map +1 -1
  41. package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +2 -3
  42. package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs.map +1 -1
  43. package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.mjs +1 -1
  44. package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.mjs.map +1 -1
  45. package/dist/esm/components/DropDown/index.mjs +3 -23
  46. package/dist/esm/components/DropDown/index.mjs.map +1 -1
  47. package/dist/esm/components/EditableField/EditableFieldLayout.mjs +1 -1
  48. package/dist/esm/components/EditableField/EditableFieldLayout.mjs.map +1 -1
  49. package/dist/esm/components/EditableField/EditableFieldTextArea.mjs +1 -1
  50. package/dist/esm/components/IDE/CopyCode.mjs +0 -1
  51. package/dist/esm/components/IDE/CopyCode.mjs.map +1 -1
  52. package/dist/esm/components/Input/Checkbox.mjs +2 -22
  53. package/dist/esm/components/Input/Checkbox.mjs.map +1 -1
  54. package/dist/esm/components/Input/Input.mjs +1 -11
  55. package/dist/esm/components/Input/Input.mjs.map +1 -1
  56. package/dist/esm/components/Input/Radio.mjs +82 -0
  57. package/dist/esm/components/Input/Radio.mjs.map +1 -0
  58. package/dist/esm/components/Input/index.mjs +4 -3
  59. package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs +1 -52
  60. package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs.map +1 -1
  61. package/dist/esm/components/KeyboardShortcut/index.mjs +2 -2
  62. package/dist/esm/components/Link/Link.mjs +33 -85
  63. package/dist/esm/components/Link/Link.mjs.map +1 -1
  64. package/dist/esm/components/Link/index.mjs +2 -2
  65. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +2 -2
  66. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs.map +1 -1
  67. package/dist/esm/components/LocaleSwitcherDropDown/LocaleSwitcher.mjs +1 -1
  68. package/dist/esm/components/LocaleSwitcherDropDown/LocaleSwitcher.mjs.map +1 -1
  69. package/dist/esm/components/MarkDownRender/MarkDownIframe.mjs +3 -3
  70. package/dist/esm/components/MarkDownRender/MarkDownIframe.mjs.map +1 -1
  71. package/dist/esm/components/Modal/Modal.mjs +3 -14
  72. package/dist/esm/components/Modal/Modal.mjs.map +1 -1
  73. package/dist/esm/components/Modal/index.mjs +2 -2
  74. package/dist/esm/components/Navbar/DesktopNavbar.mjs +1 -1
  75. package/dist/esm/components/Navbar/DesktopNavbar.mjs.map +1 -1
  76. package/dist/esm/components/Pagination/Pagination.mjs +2 -14
  77. package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
  78. package/dist/esm/components/Pagination/index.mjs +2 -2
  79. package/dist/esm/components/Pattern/DotPattern.mjs +1 -1
  80. package/dist/esm/components/Pattern/DotPattern.mjs.map +1 -1
  81. package/dist/esm/components/Popover/dynamic.mjs +4 -4
  82. package/dist/esm/components/Popover/dynamic.mjs.map +1 -1
  83. package/dist/esm/components/Popover/index.mjs +2 -2
  84. package/dist/esm/components/Popover/static.mjs +6 -28
  85. package/dist/esm/components/Popover/static.mjs.map +1 -1
  86. package/dist/esm/components/RightDrawer/RightDrawer.mjs +1 -1
  87. package/dist/esm/components/RightDrawer/RightDrawer.mjs.map +1 -1
  88. package/dist/esm/components/Select/Multiselect.mjs +4 -4
  89. package/dist/esm/components/Select/Multiselect.mjs.map +1 -1
  90. package/dist/esm/components/Select/Select.mjs +3 -15
  91. package/dist/esm/components/Select/Select.mjs.map +1 -1
  92. package/dist/esm/components/Select/index.mjs +2 -2
  93. package/dist/esm/components/Steps/index.mjs +37 -27
  94. package/dist/esm/components/Steps/index.mjs.map +1 -1
  95. package/dist/esm/components/Steps/steps.content.mjs +55 -0
  96. package/dist/esm/components/Steps/steps.content.mjs.map +1 -0
  97. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +19 -35
  98. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs.map +1 -1
  99. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +20 -20
  100. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs.map +1 -1
  101. package/dist/esm/components/SwitchSelector/index.mjs +2 -2
  102. package/dist/esm/components/Tab/Tab.mjs +2 -2
  103. package/dist/esm/components/Tab/Tab.mjs.map +1 -1
  104. package/dist/esm/components/TabSelector/TabSelector.mjs +1 -11
  105. package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
  106. package/dist/esm/components/TabSelector/index.mjs +2 -2
  107. package/dist/esm/components/Table/ExpandButton.mjs +0 -1
  108. package/dist/esm/components/Table/ExpandButton.mjs.map +1 -1
  109. package/dist/esm/components/Table/SmartTable.mjs +1 -1
  110. package/dist/esm/components/Table/SmartTable.mjs.map +1 -1
  111. package/dist/esm/components/Tag/index.mjs +51 -205
  112. package/dist/esm/components/Tag/index.mjs.map +1 -1
  113. package/dist/esm/components/TechLogo/TechLogo.mjs +36 -37
  114. package/dist/esm/components/TechLogo/TechLogo.mjs.map +1 -1
  115. package/dist/esm/components/TechLogo/index.mjs +1 -2
  116. package/dist/esm/components/TechLogo/types.mjs +0 -44
  117. package/dist/esm/components/TextArea/AutoSizeTextArea.mjs +1 -1
  118. package/dist/esm/components/TextArea/AutoSizeTextArea.mjs.map +1 -1
  119. package/dist/esm/components/TextArea/ContentEditableTextArea.mjs.map +1 -1
  120. package/dist/esm/components/TextArea/TextArea.mjs +2 -2
  121. package/dist/esm/components/TextArea/TextArea.mjs.map +1 -1
  122. package/dist/esm/components/TextArea/index.mjs +2 -2
  123. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs +1 -2
  124. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs.map +1 -1
  125. package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs +0 -1
  126. package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs.map +1 -1
  127. package/dist/esm/components/ThemeSwitcherDropDown/index.mjs +1 -2
  128. package/dist/esm/components/ThemeSwitcherDropDown/types.mjs +0 -11
  129. package/dist/esm/components/index.mjs +24 -23
  130. package/dist/types/api/hooks/project.d.ts +8 -1
  131. package/dist/types/api/hooks/project.d.ts.map +1 -1
  132. package/dist/types/api/index.d.ts +2 -2
  133. package/dist/types/api/useIntlayerAPI.d.ts +10 -3
  134. package/dist/types/api/useIntlayerAPI.d.ts.map +1 -1
  135. package/dist/types/components/Accordion/Accordion.d.ts.map +1 -1
  136. package/dist/types/components/Badge/index.d.ts +6 -25
  137. package/dist/types/components/Badge/index.d.ts.map +1 -1
  138. package/dist/types/components/Breadcrumb/index.d.ts +1 -1
  139. package/dist/types/components/Browser/Browser.d.ts +1 -1
  140. package/dist/types/components/Browser/Browser.d.ts.map +1 -1
  141. package/dist/types/components/Button/Button.d.ts +9 -45
  142. package/dist/types/components/Button/Button.d.ts.map +1 -1
  143. package/dist/types/components/Carousel/index.d.ts.map +1 -1
  144. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +2 -2
  145. package/dist/types/components/Command/index.d.ts +3 -3
  146. package/dist/types/components/Command/index.d.ts.map +1 -1
  147. package/dist/types/components/Container/index.d.ts +11 -60
  148. package/dist/types/components/Container/index.d.ts.map +1 -1
  149. package/dist/types/components/ContentEditor/ContentEditor.d.ts.map +1 -1
  150. package/dist/types/components/CopyButton/index.d.ts +3 -3
  151. package/dist/types/components/CopyButton/index.d.ts.map +1 -1
  152. package/dist/types/components/DictionaryFieldEditor/ContentEditorView/SafeHtmlRenderer.d.ts +1 -1
  153. package/dist/types/components/DictionaryFieldEditor/ContentEditorView/SafeHtmlRenderer.d.ts.map +1 -1
  154. package/dist/types/components/DictionaryFieldEditor/ContentEditorView/TextEditor.d.ts.map +1 -1
  155. package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.d.ts.map +1 -1
  156. package/dist/types/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.d.ts.map +1 -1
  157. package/dist/types/components/DictionaryFieldEditor/SaveForm/SaveForm.d.ts.map +1 -1
  158. package/dist/types/components/DictionaryFieldEditor/StructureView/StructureView.d.ts.map +1 -1
  159. package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.d.ts.map +1 -1
  160. package/dist/types/components/DropDown/index.d.ts +4 -14
  161. package/dist/types/components/DropDown/index.d.ts.map +1 -1
  162. package/dist/types/components/Form/FormBase.d.ts +1 -1
  163. package/dist/types/components/Form/FormBase.d.ts.map +1 -1
  164. package/dist/types/components/Form/FormField.d.ts +1 -1
  165. package/dist/types/components/Form/FormField.d.ts.map +1 -1
  166. package/dist/types/components/Form/elements/EditableFieldInputElement.d.ts +1 -1
  167. package/dist/types/components/Form/elements/EditableFieldInputElement.d.ts.map +1 -1
  168. package/dist/types/components/Form/elements/EditableFieldTextAreaElement.d.ts +1 -1
  169. package/dist/types/components/Form/elements/EditableFieldTextAreaElement.d.ts.map +1 -1
  170. package/dist/types/components/Form/elements/FormElement.d.ts +1 -1
  171. package/dist/types/components/Form/elements/FormElement.d.ts.map +1 -1
  172. package/dist/types/components/Form/elements/MultiselectElement.d.ts +1 -1
  173. package/dist/types/components/Form/elements/MultiselectElement.d.ts.map +1 -1
  174. package/dist/types/components/Form/elements/OTPElement.d.ts +1 -1
  175. package/dist/types/components/Form/elements/OTPElement.d.ts.map +1 -1
  176. package/dist/types/components/Form/elements/SelectElement.d.ts +1 -1
  177. package/dist/types/components/Form/elements/SelectElement.d.ts.map +1 -1
  178. package/dist/types/components/Form/elements/SwitchSelectorElement.d.ts +1 -1
  179. package/dist/types/components/Form/elements/SwitchSelectorElement.d.ts.map +1 -1
  180. package/dist/types/components/IDE/CodeBlockHighlight.d.ts +1 -1
  181. package/dist/types/components/IDE/CodeBlockHighlight.d.ts.map +1 -1
  182. package/dist/types/components/Input/Checkbox.d.ts +4 -20
  183. package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
  184. package/dist/types/components/Input/Input.d.ts +3 -9
  185. package/dist/types/components/Input/Input.d.ts.map +1 -1
  186. package/dist/types/components/Input/OTPInput.d.ts +1 -1
  187. package/dist/types/components/Input/OTPInput.d.ts.map +1 -1
  188. package/dist/types/components/Input/Radio.d.ts +25 -0
  189. package/dist/types/components/Input/Radio.d.ts.map +1 -0
  190. package/dist/types/components/Input/SearchInput.d.ts +1 -1
  191. package/dist/types/components/Input/SearchInput.d.ts.map +1 -1
  192. package/dist/types/components/Input/index.d.ts +2 -1
  193. package/dist/types/components/KeyboardShortcut/KeyboardShortcut.d.ts +1 -47
  194. package/dist/types/components/KeyboardShortcut/KeyboardShortcut.d.ts.map +1 -1
  195. package/dist/types/components/Link/Link.d.ts +8 -47
  196. package/dist/types/components/Link/Link.d.ts.map +1 -1
  197. package/dist/types/components/Loader/spinner.d.ts +1 -1
  198. package/dist/types/components/Loader/spinner.d.ts.map +1 -1
  199. package/dist/types/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.d.ts.map +1 -1
  200. package/dist/types/components/MarkDownRender/MarkDownRender.d.ts +44 -44
  201. package/dist/types/components/MarkDownRender/MarkDownRender.d.ts.map +1 -1
  202. package/dist/types/components/MaxWidthSmoother/index.d.ts +1 -1
  203. package/dist/types/components/MaxWidthSmoother/index.d.ts.map +1 -1
  204. package/dist/types/components/Modal/Modal.d.ts +2 -8
  205. package/dist/types/components/Modal/Modal.d.ts.map +1 -1
  206. package/dist/types/components/Navbar/Burger.d.ts +1 -1
  207. package/dist/types/components/Navbar/Burger.d.ts.map +1 -1
  208. package/dist/types/components/Navbar/DesktopNavbar.d.ts +1 -1
  209. package/dist/types/components/Navbar/DesktopNavbar.d.ts.map +1 -1
  210. package/dist/types/components/Navbar/MobileNavbar.d.ts +1 -1
  211. package/dist/types/components/Navbar/MobileNavbar.d.ts.map +1 -1
  212. package/dist/types/components/Navbar/index.d.ts +1 -1
  213. package/dist/types/components/Navbar/index.d.ts.map +1 -1
  214. package/dist/types/components/Pagination/Pagination.d.ts +2 -10
  215. package/dist/types/components/Pagination/Pagination.d.ts.map +1 -1
  216. package/dist/types/components/Popover/dynamic.d.ts.map +1 -1
  217. package/dist/types/components/Popover/static.d.ts +5 -17
  218. package/dist/types/components/Popover/static.d.ts.map +1 -1
  219. package/dist/types/components/Select/Multiselect.d.ts +3 -3
  220. package/dist/types/components/Select/Select.d.ts +3 -8
  221. package/dist/types/components/Select/Select.d.ts.map +1 -1
  222. package/dist/types/components/SocialNetworks/index.d.ts +1 -1
  223. package/dist/types/components/Steps/index.d.ts +4 -4
  224. package/dist/types/components/Steps/index.d.ts.map +1 -1
  225. package/dist/types/components/Steps/steps.content.d.ts +52 -0
  226. package/dist/types/components/Steps/steps.content.d.ts.map +1 -0
  227. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts +4 -16
  228. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts.map +1 -1
  229. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts +2 -2
  230. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts.map +1 -1
  231. package/dist/types/components/Tab/Tab.d.ts +2 -2
  232. package/dist/types/components/Tab/Tab.d.ts.map +1 -1
  233. package/dist/types/components/TabSelector/TabSelector.d.ts +2 -10
  234. package/dist/types/components/TabSelector/TabSelector.d.ts.map +1 -1
  235. package/dist/types/components/Table/TableElements.d.ts +4 -4
  236. package/dist/types/components/Table/TableElements.d.ts.map +1 -1
  237. package/dist/types/components/Tag/index.d.ts +44 -83
  238. package/dist/types/components/Tag/index.d.ts.map +1 -1
  239. package/dist/types/components/TechLogo/TechLogo.d.ts.map +1 -1
  240. package/dist/types/components/TechLogo/index.d.ts +1 -1
  241. package/dist/types/components/TechLogo/logos/Lit.d.ts +1 -1
  242. package/dist/types/components/TechLogo/logos/Lit.d.ts.map +1 -1
  243. package/dist/types/components/TechLogo/logos/Vanilla.d.ts +1 -1
  244. package/dist/types/components/TechLogo/logos/Vanilla.d.ts.map +1 -1
  245. package/dist/types/components/TechLogo/types.d.ts +1 -38
  246. package/dist/types/components/TechLogo/types.d.ts.map +1 -1
  247. package/dist/types/components/TextArea/AutoSizeTextArea.d.ts +1 -1
  248. package/dist/types/components/TextArea/ContentEditableTextArea.d.ts +3 -3
  249. package/dist/types/components/TextArea/TextArea.d.ts +6 -6
  250. package/dist/types/components/TextArea/TextArea.d.ts.map +1 -1
  251. package/dist/types/components/ThemeSwitcherDropDown/types.d.ts +1 -5
  252. package/dist/types/components/ThemeSwitcherDropDown/types.d.ts.map +1 -1
  253. package/dist/types/components/Toaster/Toast.d.ts +1 -1
  254. package/dist/types/components/Toaster/Toaster.d.ts +1 -1
  255. package/dist/types/components/Toaster/Toaster.d.ts.map +1 -1
  256. package/dist/types/components/index.d.ts +5 -2
  257. package/package.json +23 -24
  258. package/dist/esm/components/TechLogo/types.mjs.map +0 -1
  259. package/dist/esm/components/ThemeSwitcherDropDown/types.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TechLogo.mjs","names":[],"sources":["../../../../src/components/TechLogo/TechLogo.tsx"],"sourcesContent":["import { type FC, type JSX, lazy, Suspense, type SVGProps } from 'react';\nimport { cn } from '../../utils/cn';\nimport { TechLogoName } from './types';\n\nexport type TechLogoProps = SVGProps<SVGSVGElement> & {\n name: TechLogoName;\n};\n\n/**\n * This ensures React.lazy always receives a valid component.\n */\nconst dynamicLogo = (importFn: () => Promise<any>, exportName: string) =>\n lazy(async () => {\n const module = await importFn();\n const asset = module[exportName];\n\n return { default: asset };\n });\n\nconst logoRecord: Record<TechLogoName, ReturnType<typeof dynamicLogo>> = {\n [TechLogoName.Adonis]: dynamicLogo(\n () => import('./logos/Adonis'),\n 'AdonisLogo'\n ),\n [TechLogoName.Angular]: dynamicLogo(\n () => import('./logos/Angular'),\n 'AngularLogo'\n ),\n [TechLogoName.Astro]: dynamicLogo(() => import('./logos/Astro'), 'AstroLogo'),\n [TechLogoName.Express]: dynamicLogo(\n () => import('./logos/Express'),\n 'ExpressLogo'\n ),\n [TechLogoName.Fastify]: dynamicLogo(\n () => import('./logos/Fastify'),\n 'FastifyLogo'\n ),\n [TechLogoName.Hono]: dynamicLogo(() => import('./logos/Hono'), 'HonoLogo'),\n [TechLogoName.Lynx]: dynamicLogo(() => import('./logos/Lynx'), 'LynxLogo'),\n [TechLogoName.NestJS]: dynamicLogo(\n () => import('./logos/NestJS'),\n 'NestJSLogo'\n ),\n [TechLogoName.Nextjs]: dynamicLogo(\n () => import('./logos/Nextjs'),\n 'NextJSLogo'\n ),\n [TechLogoName.Node]: dynamicLogo(() => import('./logos/Node'), 'NodejsLogo'),\n [TechLogoName.Nuxt]: dynamicLogo(() => import('./logos/Nuxt'), 'NuxtLogo'),\n [TechLogoName.Preact]: dynamicLogo(\n () => import('./logos/Preact'),\n 'PreactLogo'\n ),\n [TechLogoName.React]: dynamicLogo(\n () => import('./logos/Reactjs'),\n 'ReactLogo'\n ),\n [TechLogoName.Solid]: dynamicLogo(() => import('./logos/Solid'), 'SolidLogo'),\n [TechLogoName.Svelte]: dynamicLogo(\n () => import('./logos/Svelte'),\n 'SvelteLogo'\n ),\n [TechLogoName.Tanstack]: dynamicLogo(\n () => import('./logos/Tanstack'),\n 'TanstackLogo'\n ),\n [TechLogoName.Vite]: dynamicLogo(() => import('./logos/Vitejs'), 'ViteLogo'),\n [TechLogoName.Vue]: dynamicLogo(() => import('./logos/Vuejs'), 'VuejsLogo'),\n [TechLogoName.Lit]: dynamicLogo(() => import('./logos/Lit'), 'LitLogo'),\n [TechLogoName.Vanilla]: dynamicLogo(\n () => import('./logos/Vanilla'),\n 'JavaScriptLogo'\n ),\n [TechLogoName.Anthropic]: dynamicLogo(\n () => import('./logos/Anthropic'),\n 'AnthropicLogo'\n ),\n [TechLogoName.Claude]: dynamicLogo(\n () => import('./logos/Claude'),\n 'ClaudeLogo'\n ),\n [TechLogoName.ChatGPT]: dynamicLogo(\n () => import('./logos/ChatGPT'),\n 'ChatGPTLogo'\n ),\n [TechLogoName.DeepSeek]: dynamicLogo(\n () => import('./logos/DeepSeek'),\n 'DeepSeekLogo'\n ),\n [TechLogoName.Gemini]: dynamicLogo(\n () => import('./logos/Gemini'),\n 'GeminiLogo'\n ),\n [TechLogoName.GoogleAI]: dynamicLogo(\n () => import('./logos/GoogleAI'),\n 'GoogleAILogo'\n ),\n [TechLogoName.Grok]: dynamicLogo(() => import('./logos/Grok'), 'GrokLogo'),\n [TechLogoName.Mistral]: dynamicLogo(\n () => import('./logos/Mistral'),\n 'MistralLogo'\n ),\n [TechLogoName.Ollama]: dynamicLogo(\n () => import('./logos/Ollama'),\n 'OllamaLogo'\n ),\n [TechLogoName.OpenAI]: dynamicLogo(\n () => import('./logos/OpenAI'),\n 'OpenAILogo'\n ),\n [TechLogoName.Perplexity]: dynamicLogo(\n () => import('./logos/Perplexity'),\n 'PerplexityLogo'\n ),\n [TechLogoName.GitHub]: dynamicLogo(\n () => import('./logos/GitHub'),\n 'GitHubLogo'\n ),\n [TechLogoName.GitLab]: dynamicLogo(\n () => import('./logos/GitLab'),\n 'GitLabLogo'\n ),\n [TechLogoName.Bitbucket]: dynamicLogo(\n () => import('./logos/Bitbucket'),\n 'BitbucketLogo'\n ),\n [TechLogoName.Google]: dynamicLogo(\n () => import('./logos/Google'),\n 'GoogleLogo'\n ),\n [TechLogoName.LinkedIn]: dynamicLogo(\n () => import('./logos/LinkedIn'),\n 'LinkedInLogo'\n ),\n};\n\nexport const TechLogo: FC<TechLogoProps> = ({\n name,\n ...props\n}): JSX.Element => {\n const LazyLogo = logoRecord[name];\n\n if (!LazyLogo) {\n return <></>;\n }\n\n return (\n <Suspense\n fallback={\n <div className={cn('animate-pulse bg-neutral-200', props.className)} />\n }\n >\n <LazyLogo {...(props as any)} />\n </Suspense>\n );\n};\n"],"mappings":";;;;;;;;;AAWA,MAAM,eAAe,UAA8B,eACjD,KAAK,YAAY;CAIf,OAAO,EAAE,UAFK,MADO,SAAS,GACT,YAEG;AAC1B,CAAC;AAEH,MAAM,aAAmE;aAChD,kBACf,OAAO,uBACb,YACF;cACwB,kBAChB,OAAO,wBACb,aACF;YACsB,kBAAkB,OAAO,sBAAkB,WAAW;cACpD,kBAChB,OAAO,wBACb,aACF;cACwB,kBAChB,OAAO,wBACb,aACF;WACqB,kBAAkB,OAAO,qBAAiB,UAAU;WACpD,kBAAkB,OAAO,qBAAiB,UAAU;aAClD,kBACf,OAAO,uBACb,YACF;aACuB,kBACf,OAAO,uBACb,YACF;WACqB,kBAAkB,OAAO,qBAAiB,YAAY;WACtD,kBAAkB,OAAO,qBAAiB,UAAU;aAClD,kBACf,OAAO,uBACb,YACF;YACsB,kBACd,OAAO,wBACb,WACF;YACsB,kBAAkB,OAAO,sBAAkB,WAAW;aACrD,kBACf,OAAO,uBACb,YACF;eACyB,kBACjB,OAAO,yBACb,cACF;WACqB,kBAAkB,OAAO,uBAAmB,UAAU;UACvD,kBAAkB,OAAO,sBAAkB,WAAW;UACtD,kBAAkB,OAAO,oBAAgB,SAAS;cAC9C,kBAChB,OAAO,wBACb,gBACF;gBAC0B,kBAClB,OAAO,0BACb,eACF;aACuB,kBACf,OAAO,uBACb,YACF;cACwB,kBAChB,OAAO,wBACb,aACF;eACyB,kBACjB,OAAO,yBACb,cACF;aACuB,kBACf,OAAO,uBACb,YACF;eACyB,kBACjB,OAAO,yBACb,cACF;WACqB,kBAAkB,OAAO,qBAAiB,UAAU;cACjD,kBAChB,OAAO,wBACb,aACF;aACuB,kBACf,OAAO,uBACb,YACF;aACuB,kBACf,OAAO,uBACb,YACF;iBAC2B,kBACnB,OAAO,2BACb,gBACF;aACuB,kBACf,OAAO,uBACb,YACF;aACuB,kBACf,OAAO,uBACb,YACF;gBAC0B,kBAClB,OAAO,0BACb,eACF;aACuB,kBACf,OAAO,uBACb,YACF;eACyB,kBACjB,OAAO,yBACb,cACF;AACF;AAEA,MAAa,YAA+B,EAC1C,MACA,GAAG,YACc;CACjB,MAAM,WAAW,WAAW;CAE5B,IAAI,CAAC,UACH,OAAO,iCAAI;CAGb,OACE,oBAAC,UAAD;EACE,UACE,oBAAC,OAAD,EAAK,WAAW,GAAG,gCAAgC,MAAM,SAAS,EAAI;YAGxE,oBAAC,UAAD,EAAU,GAAK,MAAgB;CACvB;AAEd"}
1
+ {"version":3,"file":"TechLogo.mjs","names":[],"sources":["../../../../src/components/TechLogo/TechLogo.tsx"],"sourcesContent":["import { type FC, type JSX, lazy, Suspense, type SVGProps } from 'react';\nimport { cn } from '../../utils/cn';\nimport type { TechLogoName } from './types';\n\nexport type TechLogoProps = SVGProps<SVGSVGElement> & {\n name: TechLogoName;\n};\n\n/**\n * This ensures React.lazy always receives a valid component.\n */\nconst dynamicLogo = (importFn: () => Promise<any>, exportName: string) =>\n lazy(async () => {\n const module = await importFn();\n const asset = module[exportName];\n\n return { default: asset };\n });\n\nconst logoRecord: Record<TechLogoName, ReturnType<typeof dynamicLogo>> = {\n adonis: dynamicLogo(() => import('./logos/Adonis'), 'AdonisLogo'),\n angular: dynamicLogo(() => import('./logos/Angular'), 'AngularLogo'),\n astro: dynamicLogo(() => import('./logos/Astro'), 'AstroLogo'),\n express: dynamicLogo(() => import('./logos/Express'), 'ExpressLogo'),\n fastify: dynamicLogo(() => import('./logos/Fastify'), 'FastifyLogo'),\n hono: dynamicLogo(() => import('./logos/Hono'), 'HonoLogo'),\n lynx: dynamicLogo(() => import('./logos/Lynx'), 'LynxLogo'),\n nestjs: dynamicLogo(() => import('./logos/NestJS'), 'NestJSLogo'),\n nextjs: dynamicLogo(() => import('./logos/Nextjs'), 'NextJSLogo'),\n node: dynamicLogo(() => import('./logos/Node'), 'NodejsLogo'),\n nuxt: dynamicLogo(() => import('./logos/Nuxt'), 'NuxtLogo'),\n preact: dynamicLogo(() => import('./logos/Preact'), 'PreactLogo'),\n react: dynamicLogo(() => import('./logos/Reactjs'), 'ReactLogo'),\n solid: dynamicLogo(() => import('./logos/Solid'), 'SolidLogo'),\n svelte: dynamicLogo(() => import('./logos/Svelte'), 'SvelteLogo'),\n tanstack: dynamicLogo(() => import('./logos/Tanstack'), 'TanstackLogo'),\n vite: dynamicLogo(() => import('./logos/Vitejs'), 'ViteLogo'),\n vue: dynamicLogo(() => import('./logos/Vuejs'), 'VuejsLogo'),\n lit: dynamicLogo(() => import('./logos/Lit'), 'LitLogo'),\n vanilla: dynamicLogo(() => import('./logos/Vanilla'), 'JavaScriptLogo'),\n anthropic: dynamicLogo(() => import('./logos/Anthropic'), 'AnthropicLogo'),\n claude: dynamicLogo(() => import('./logos/Claude'), 'ClaudeLogo'),\n chatgpt: dynamicLogo(() => import('./logos/ChatGPT'), 'ChatGPTLogo'),\n deepseek: dynamicLogo(() => import('./logos/DeepSeek'), 'DeepSeekLogo'),\n gemini: dynamicLogo(() => import('./logos/Gemini'), 'GeminiLogo'),\n googleai: dynamicLogo(() => import('./logos/GoogleAI'), 'GoogleAILogo'),\n grok: dynamicLogo(() => import('./logos/Grok'), 'GrokLogo'),\n mistral: dynamicLogo(() => import('./logos/Mistral'), 'MistralLogo'),\n ollama: dynamicLogo(() => import('./logos/Ollama'), 'OllamaLogo'),\n openai: dynamicLogo(() => import('./logos/OpenAI'), 'OpenAILogo'),\n perplexity: dynamicLogo(() => import('./logos/Perplexity'), 'PerplexityLogo'),\n github: dynamicLogo(() => import('./logos/GitHub'), 'GitHubLogo'),\n gitlab: dynamicLogo(() => import('./logos/GitLab'), 'GitLabLogo'),\n bitbucket: dynamicLogo(() => import('./logos/Bitbucket'), 'BitbucketLogo'),\n google: dynamicLogo(() => import('./logos/Google'), 'GoogleLogo'),\n linkedin: dynamicLogo(() => import('./logos/LinkedIn'), 'LinkedInLogo'),\n};\n\nexport const TechLogo: FC<TechLogoProps> = ({\n name,\n ...props\n}): JSX.Element => {\n const LazyLogo = logoRecord[name as TechLogoName];\n\n if (!LazyLogo) {\n return <></>;\n }\n\n return (\n <Suspense\n fallback={\n <div className={cn('animate-pulse bg-neutral-200', props.className)} />\n }\n >\n <LazyLogo {...(props as any)} />\n </Suspense>\n );\n};\n"],"mappings":";;;;;;;;AAWA,MAAM,eAAe,UAA8B,eACjD,KAAK,YAAY;CAIf,OAAO,EAAE,UAFK,MADO,SAAS,GACT,YAEG;AAC1B,CAAC;AAEH,MAAM,aAAmE;CACvE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,OAAO,kBAAkB,OAAO,sBAAkB,WAAW;CAC7D,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,MAAM,kBAAkB,OAAO,qBAAiB,YAAY;CAC5D,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,OAAO,kBAAkB,OAAO,wBAAoB,WAAW;CAC/D,OAAO,kBAAkB,OAAO,sBAAkB,WAAW;CAC7D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,MAAM,kBAAkB,OAAO,uBAAmB,UAAU;CAC5D,KAAK,kBAAkB,OAAO,sBAAkB,WAAW;CAC3D,KAAK,kBAAkB,OAAO,oBAAgB,SAAS;CACvD,SAAS,kBAAkB,OAAO,wBAAoB,gBAAgB;CACtE,WAAW,kBAAkB,OAAO,0BAAsB,eAAe;CACzE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,YAAY,kBAAkB,OAAO,2BAAuB,gBAAgB;CAC5E,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,WAAW,kBAAkB,OAAO,0BAAsB,eAAe;CACzE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;AACxE;AAEA,MAAa,YAA+B,EAC1C,MACA,GAAG,YACc;CACjB,MAAM,WAAW,WAAW;CAE5B,IAAI,CAAC,UACH,OAAO,iCAAI;CAGb,OACE,oBAAC,UAAD;EACE,UACE,oBAAC,OAAD,EAAK,WAAW,GAAG,gCAAgC,MAAM,SAAS,EAAI;YAGxE,oBAAC,UAAD,EAAU,GAAK,MAAgB;CACvB;AAEd"}
@@ -1,5 +1,4 @@
1
- import { TechLogoName } from "./types.mjs";
2
1
  import { TechLogo } from "./TechLogo.mjs";
3
2
  import { techLogos_exports } from "./techLogos.mjs";
4
3
 
5
- export { TechLogo, TechLogoName, techLogos_exports as TechLogos };
4
+ export { TechLogo, techLogos_exports as TechLogos };
@@ -1,44 +0,0 @@
1
- //#region src/components/TechLogo/types.ts
2
- let TechLogoName = /* @__PURE__ */ function(TechLogoName) {
3
- TechLogoName["Adonis"] = "adonis";
4
- TechLogoName["Angular"] = "angular";
5
- TechLogoName["Astro"] = "astro";
6
- TechLogoName["Express"] = "express";
7
- TechLogoName["Fastify"] = "fastify";
8
- TechLogoName["Hono"] = "hono";
9
- TechLogoName["Lynx"] = "lynx";
10
- TechLogoName["NestJS"] = "nestjs";
11
- TechLogoName["Nextjs"] = "nextjs";
12
- TechLogoName["Node"] = "node";
13
- TechLogoName["Nuxt"] = "nuxt";
14
- TechLogoName["Preact"] = "preact";
15
- TechLogoName["React"] = "react";
16
- TechLogoName["Solid"] = "solid";
17
- TechLogoName["Svelte"] = "svelte";
18
- TechLogoName["Tanstack"] = "tanstack";
19
- TechLogoName["Vite"] = "vite";
20
- TechLogoName["Vue"] = "vue";
21
- TechLogoName["Lit"] = "lit";
22
- TechLogoName["Vanilla"] = "vanilla";
23
- TechLogoName["Anthropic"] = "anthropic";
24
- TechLogoName["Claude"] = "claude";
25
- TechLogoName["ChatGPT"] = "chatgpt";
26
- TechLogoName["DeepSeek"] = "deepseek";
27
- TechLogoName["Gemini"] = "gemini";
28
- TechLogoName["GoogleAI"] = "googleai";
29
- TechLogoName["Grok"] = "grok";
30
- TechLogoName["Mistral"] = "mistral";
31
- TechLogoName["Ollama"] = "ollama";
32
- TechLogoName["OpenAI"] = "openai";
33
- TechLogoName["Perplexity"] = "perplexity";
34
- TechLogoName["GitHub"] = "github";
35
- TechLogoName["GitLab"] = "gitlab";
36
- TechLogoName["Bitbucket"] = "bitbucket";
37
- TechLogoName["Google"] = "google";
38
- TechLogoName["LinkedIn"] = "linkedin";
39
- return TechLogoName;
40
- }({});
41
-
42
- //#endregion
43
- export { TechLogoName };
44
- //# sourceMappingURL=types.mjs.map
@@ -62,7 +62,7 @@ const LINE_PADDING = 12;
62
62
  * placeholder="Write your notes here..."
63
63
  * autoSize={true}
64
64
  * maxRows={20}
65
- * variant={InputVariant.DEFAULT}
65
+ * variant="default"
66
66
  * />
67
67
  * ```
68
68
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AutoSizeTextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/AutoSizeTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport {\n type ChangeEventHandler,\n type FC,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n} from 'react';\nimport { TextArea, type TextAreaProps } from './TextArea';\n\n/**\n * Props for the AutoSizedTextArea component.\n *\n * Extends TextAreaProps with auto-sizing functionality and row limitations.\n *\n * @example\n * ```tsx\n * // Auto-sizing textarea that grows with content\n * <AutoSizedTextArea\n * placeholder=\"Start typing and watch it grow...\"\n * autoSize={true}\n * maxRows={10}\n * />\n *\n * // Limited height with scroll when exceeded\n * <AutoSizedTextArea\n * value={longText}\n * onChange={handleChange}\n * autoSize={true}\n * maxRows={5}\n * className=\"max-h-[120px]\"\n * />\n *\n * // Disable auto-sizing for fixed height\n * <AutoSizedTextArea\n * autoSize={false}\n * rows={3}\n * placeholder=\"Fixed height textarea\"\n * />\n * ```\n */\nexport type AutoSizedTextAreaProps = TextAreaProps & {\n /** Whether to automatically adjust height based on content */\n autoSize?: boolean;\n /** Maximum number of rows before scrolling is enabled */\n maxRows?: number;\n};\n\nconst LINE_HEIGHT = 24; // px\nconst LINE_PADDING = 12; // px\n\n/**\n * AutoSizedTextArea Component\n *\n * An enhanced textarea that automatically adjusts its height based on content,\n * providing a smooth user experience for variable-length text input.\n *\n * ## Features\n * - **Auto-Sizing**: Dynamically grows and shrinks based on content\n * - **Row Limits**: Configurable maximum rows before scrolling\n * - **Smooth Transitions**: Seamless height adjustments as user types\n * - **Scroll Management**: Automatic overflow handling when max height reached\n * - **Performance Optimized**: Efficient height calculations and updates\n *\n * ## Technical Details\n * - Line height: 24px with 12px padding\n * - Height calculation: `scrollHeight` vs `maxRows * lineHeight + padding`\n * - Resize: Disabled when auto-sizing is active for smooth experience\n * - Ref forwarding: Supports imperative access to textarea element\n *\n * ## Use Cases\n * - Chat message composition with dynamic sizing\n * - Comment forms that expand with content\n * - Note-taking interfaces with variable length\n * - Social media post creation\n * - Code snippet input with growth limits\n *\n * @example\n * ```tsx\n * // Chat-style auto-expanding textarea\n * const [message, setMessage] = useState('');\n *\n * <AutoSizedTextArea\n * value={message}\n * onChange={(e) => setMessage(e.target.value)}\n * placeholder=\"Type your message...\"\n * autoSize={true}\n * maxRows={8}\n * className=\"min-h-[40px]\"\n * onKeyDown={(e) => {\n * if (e.key === 'Enter' && !e.shiftKey) {\n * e.preventDefault();\n * sendMessage(message);\n * setMessage('');\n * }\n * }}\n * />\n *\n * // Note-taking with generous height limits\n * <AutoSizedTextArea\n * defaultValue={note.content}\n * onChange={handleNoteChange}\n * placeholder=\"Write your notes here...\"\n * autoSize={true}\n * maxRows={20}\n * variant={InputVariant.DEFAULT}\n * />\n * ```\n */\nexport const AutoSizedTextArea: FC<AutoSizedTextAreaProps> = ({\n className,\n autoSize = true,\n onChange,\n maxRows = 999,\n ref,\n ...props\n}) => {\n const textAreaRef = useRef<HTMLTextAreaElement | null>(null);\n\n useImperativeHandle(ref, () => textAreaRef.current!);\n\n const adjustHeight = () => {\n const textAreaEl = textAreaRef.current;\n\n if (!textAreaEl || !autoSize) return;\n\n const textAreaStyle = textAreaEl.style;\n\n // Reset height to get accurate scrollHeight\n textAreaStyle.height = 'auto';\n const scrollHeight = textAreaEl.scrollHeight;\n const maxHeight = LINE_HEIGHT * maxRows + LINE_PADDING;\n const minHeight = LINE_HEIGHT + LINE_PADDING;\n\n // Set the new height\n textAreaStyle.height = `${Math.max(Math.min(scrollHeight, maxHeight), minHeight)}px`;\n };\n\n useLayoutEffect(() => {\n adjustHeight();\n }, [props.value, props.defaultValue, adjustHeight]);\n\n const handleChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {\n onChange?.(e);\n adjustHeight();\n };\n\n const setRef = (el: HTMLTextAreaElement | null) => {\n textAreaRef.current = el;\n if (el) {\n adjustHeight();\n }\n };\n\n return (\n <TextArea\n ref={setRef}\n onChange={handleChange}\n className={cn('overflow-y-auto', autoSize && 'resize-none', className)}\n {...props}\n />\n );\n};\n"],"mappings":";;;;;;;;AAkDA,MAAM,cAAc;AACpB,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DrB,MAAa,qBAAiD,EAC5D,WACA,WAAW,MACX,UACA,UAAU,KACV,KACA,GAAG,YACC;CACJ,MAAM,cAAc,OAAmC,IAAI;CAE3D,oBAAoB,WAAW,YAAY,OAAQ;CAEnD,MAAM,qBAAqB;EACzB,MAAM,aAAa,YAAY;EAE/B,IAAI,CAAC,cAAc,CAAC,UAAU;EAE9B,MAAM,gBAAgB,WAAW;EAGjC,cAAc,SAAS;EACvB,MAAM,eAAe,WAAW;EAChC,MAAM,YAAY,cAAc,UAAU;EAI1C,cAAc,SAAS,GAAG,KAAK,IAAI,KAAK,IAAI,cAAc,SAAS,GAAG,EAAS,EAAE;CACnF;CAEA,sBAAsB;EACpB,aAAa;CACf,GAAG;EAAC,MAAM;EAAO,MAAM;EAAc;CAAY,CAAC;CAElD,MAAM,gBAAyD,MAAM;EACnE,WAAW,CAAC;EACZ,aAAa;CACf;CAEA,MAAM,UAAU,OAAmC;EACjD,YAAY,UAAU;EACtB,IAAI,IACF,aAAa;CAEjB;CAEA,OACE,oBAAC,UAAD;EACE,KAAK;EACL,UAAU;EACV,WAAW,GAAG,mBAAmB,YAAY,eAAe,SAAS;EACrE,GAAI;CACL;AAEL"}
1
+ {"version":3,"file":"AutoSizeTextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/AutoSizeTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport {\n type ChangeEventHandler,\n type FC,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n} from 'react';\nimport { TextArea, type TextAreaProps } from './TextArea';\n\n/**\n * Props for the AutoSizedTextArea component.\n *\n * Extends TextAreaProps with auto-sizing functionality and row limitations.\n *\n * @example\n * ```tsx\n * // Auto-sizing textarea that grows with content\n * <AutoSizedTextArea\n * placeholder=\"Start typing and watch it grow...\"\n * autoSize={true}\n * maxRows={10}\n * />\n *\n * // Limited height with scroll when exceeded\n * <AutoSizedTextArea\n * value={longText}\n * onChange={handleChange}\n * autoSize={true}\n * maxRows={5}\n * className=\"max-h-[120px]\"\n * />\n *\n * // Disable auto-sizing for fixed height\n * <AutoSizedTextArea\n * autoSize={false}\n * rows={3}\n * placeholder=\"Fixed height textarea\"\n * />\n * ```\n */\nexport type AutoSizedTextAreaProps = TextAreaProps & {\n /** Whether to automatically adjust height based on content */\n autoSize?: boolean;\n /** Maximum number of rows before scrolling is enabled */\n maxRows?: number;\n};\n\nconst LINE_HEIGHT = 24; // px\nconst LINE_PADDING = 12; // px\n\n/**\n * AutoSizedTextArea Component\n *\n * An enhanced textarea that automatically adjusts its height based on content,\n * providing a smooth user experience for variable-length text input.\n *\n * ## Features\n * - **Auto-Sizing**: Dynamically grows and shrinks based on content\n * - **Row Limits**: Configurable maximum rows before scrolling\n * - **Smooth Transitions**: Seamless height adjustments as user types\n * - **Scroll Management**: Automatic overflow handling when max height reached\n * - **Performance Optimized**: Efficient height calculations and updates\n *\n * ## Technical Details\n * - Line height: 24px with 12px padding\n * - Height calculation: `scrollHeight` vs `maxRows * lineHeight + padding`\n * - Resize: Disabled when auto-sizing is active for smooth experience\n * - Ref forwarding: Supports imperative access to textarea element\n *\n * ## Use Cases\n * - Chat message composition with dynamic sizing\n * - Comment forms that expand with content\n * - Note-taking interfaces with variable length\n * - Social media post creation\n * - Code snippet input with growth limits\n *\n * @example\n * ```tsx\n * // Chat-style auto-expanding textarea\n * const [message, setMessage] = useState('');\n *\n * <AutoSizedTextArea\n * value={message}\n * onChange={(e) => setMessage(e.target.value)}\n * placeholder=\"Type your message...\"\n * autoSize={true}\n * maxRows={8}\n * className=\"min-h-[40px]\"\n * onKeyDown={(e) => {\n * if (e.key === 'Enter' && !e.shiftKey) {\n * e.preventDefault();\n * sendMessage(message);\n * setMessage('');\n * }\n * }}\n * />\n *\n * // Note-taking with generous height limits\n * <AutoSizedTextArea\n * defaultValue={note.content}\n * onChange={handleNoteChange}\n * placeholder=\"Write your notes here...\"\n * autoSize={true}\n * maxRows={20}\n * variant=\"default\"\n * />\n * ```\n */\nexport const AutoSizedTextArea: FC<AutoSizedTextAreaProps> = ({\n className,\n autoSize = true,\n onChange,\n maxRows = 999,\n ref,\n ...props\n}) => {\n const textAreaRef = useRef<HTMLTextAreaElement | null>(null);\n\n useImperativeHandle(ref, () => textAreaRef.current!);\n\n const adjustHeight = () => {\n const textAreaEl = textAreaRef.current;\n\n if (!textAreaEl || !autoSize) return;\n\n const textAreaStyle = textAreaEl.style;\n\n // Reset height to get accurate scrollHeight\n textAreaStyle.height = 'auto';\n const scrollHeight = textAreaEl.scrollHeight;\n const maxHeight = LINE_HEIGHT * maxRows + LINE_PADDING;\n const minHeight = LINE_HEIGHT + LINE_PADDING;\n\n // Set the new height\n textAreaStyle.height = `${Math.max(Math.min(scrollHeight, maxHeight), minHeight)}px`;\n };\n\n useLayoutEffect(() => {\n adjustHeight();\n }, [props.value, props.defaultValue, adjustHeight]);\n\n const handleChange: ChangeEventHandler<HTMLTextAreaElement> = (e) => {\n onChange?.(e);\n adjustHeight();\n };\n\n const setRef = (el: HTMLTextAreaElement | null) => {\n textAreaRef.current = el;\n if (el) {\n adjustHeight();\n }\n };\n\n return (\n <TextArea\n ref={setRef}\n onChange={handleChange}\n className={cn('overflow-y-auto', autoSize && 'resize-none', className)}\n {...props}\n />\n );\n};\n"],"mappings":";;;;;;;;AAkDA,MAAM,cAAc;AACpB,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DrB,MAAa,qBAAiD,EAC5D,WACA,WAAW,MACX,UACA,UAAU,KACV,KACA,GAAG,YACC;CACJ,MAAM,cAAc,OAAmC,IAAI;CAE3D,oBAAoB,WAAW,YAAY,OAAQ;CAEnD,MAAM,qBAAqB;EACzB,MAAM,aAAa,YAAY;EAE/B,IAAI,CAAC,cAAc,CAAC,UAAU;EAE9B,MAAM,gBAAgB,WAAW;EAGjC,cAAc,SAAS;EACvB,MAAM,eAAe,WAAW;EAChC,MAAM,YAAY,cAAc,UAAU;EAI1C,cAAc,SAAS,GAAG,KAAK,IAAI,KAAK,IAAI,cAAc,SAAS,GAAG,EAAS,EAAE;CACnF;CAEA,sBAAsB;EACpB,aAAa;CACf,GAAG;EAAC,MAAM;EAAO,MAAM;EAAc;CAAY,CAAC;CAElD,MAAM,gBAAyD,MAAM;EACnE,WAAW,CAAC;EACZ,aAAa;CACf;CAEA,MAAM,UAAU,OAAmC;EACjD,YAAY,UAAU;EACtB,IAAI,IACF,aAAa;CAEjB;CAEA,OACE,oBAAC,UAAD;EACE,KAAK;EACL,UAAU;EACV,WAAW,GAAG,mBAAmB,YAAY,eAAe,SAAS;EACrE,GAAI;CACL;AAEL"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContentEditableTextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/ContentEditableTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport type { VariantProps } from 'class-variance-authority';\nimport {\n type ClipboardEvent,\n type DragEvent,\n type FC,\n type HTMLAttributes,\n type InputEvent,\n type KeyboardEvent,\n type MutableRefObject,\n type Ref,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { type InputVariant, inputVariants } from '../Input';\n\ntype CaretPosition = {\n line: number;\n offset: number;\n};\n\ntype UseContentEditableOptions = {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n};\n\nconst ZERO_WIDTH_SPACE = '\\u200B';\n\nconst getTextFromContainer = (container: HTMLDivElement): string => {\n const lineEls = container.querySelectorAll('[data-line]');\n if (lineEls.length === 0) {\n return (container.textContent ?? '').split(ZERO_WIDTH_SPACE).join('');\n }\n\n return Array.from(lineEls)\n .map((el) => {\n const editable = el.querySelector('[data-editable]');\n const raw = editable?.textContent ?? el.textContent ?? '';\n return raw === ZERO_WIDTH_SPACE\n ? ''\n : raw.split(ZERO_WIDTH_SPACE).join('');\n })\n .join('\\n');\n};\n\nconst splitLines = (text: string): string[] => {\n const lines = text.split('\\n');\n return lines.length === 0 ? [''] : lines;\n};\n\n// Cached Intl.Segmenter for grapheme-aware deletion (emoji, CJK, etc.)\n// Intl.Segmenter is ES2022+ but we feature-detect at runtime.\ntype GraphemeSegmenter = {\n segment: (input: string) => Iterable<{ segment: string }>;\n};\n\nconst createGraphemeSegmenter = (): GraphemeSegmenter | null => {\n if (typeof Intl === 'undefined' || !('Segmenter' in Intl)) return null;\n const SegmenterCtor = (\n Intl as unknown as Record<\n string,\n new (\n ...args: unknown[]\n ) => GraphemeSegmenter\n >\n ).Segmenter;\n return new SegmenterCtor(undefined, { granularity: 'grapheme' });\n};\n\nconst graphemeSegmenter = createGraphemeSegmenter();\n\n/**\n * Find the previous grapheme cluster boundary for safe deletion.\n * Falls back to code-point-aware deletion if Intl.Segmenter is unavailable.\n */\nconst prevGraphemeBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(0, offset))];\n const last = segments[segments.length - 1];\n return last ? offset - last.segment.length : offset - 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset - 1);\n if (code >= 0xdc00 && code <= 0xdfff && offset >= 2) {\n return offset - 2;\n }\n return offset - 1;\n};\n\n/**\n * Find the next grapheme cluster boundary for safe forward deletion.\n */\nconst nextGraphemeBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(offset))];\n const first = segments[0];\n return first ? offset + first.segment.length : offset + 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset);\n if (code >= 0xd800 && code <= 0xdbff && offset + 1 < text.length) {\n return offset + 2;\n }\n return offset + 1;\n};\n\n/**\n * Find the previous word boundary for Option+Backspace.\n */\nconst prevWordBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n let i = offset - 1;\n // Skip whitespace\n while (i > 0 && /\\s/.test(text[i - 1])) i--;\n // Skip word characters\n while (i > 0 && /\\S/.test(text[i - 1])) i--;\n return i;\n};\n\n/**\n * Find the next word boundary for Option+Delete.\n */\nconst nextWordBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n let i = offset;\n // Skip word characters\n while (i < text.length && /\\S/.test(text[i])) i++;\n // Skip whitespace\n while (i < text.length && /\\s/.test(text[i])) i++;\n return i;\n};\n\n/**\n * Find the start of the current line (for Cmd+Backspace).\n */\nconst lineStart = (text: string, offset: number): number => {\n const before = text.slice(0, offset);\n const lastNewline = before.lastIndexOf('\\n');\n return lastNewline + 1;\n};\n\n/**\n * Find the end of the current line (for Cmd+Delete).\n */\nconst lineEnd = (text: string, offset: number): number => {\n const nextNewline = text.indexOf('\\n', offset);\n return nextNewline === -1 ? text.length : nextNewline;\n};\n\nexport const useContentEditable = ({\n value,\n defaultValue,\n onChange,\n disabled = false,\n}: UseContentEditableOptions) => {\n const initialValue = value ?? defaultValue ?? '';\n const [lines, setLines] = useState<string[]>(() => splitLines(initialValue));\n const containerRef = useRef<HTMLDivElement | null>(null);\n const pendingCaretRef = useRef<CaretPosition | null>(null);\n const isControlled = value !== undefined;\n\n // Keep a ref to the latest lines to avoid stale closures in rapid typing\n const linesRef = useRef(lines);\n linesRef.current = lines;\n\n useEffect(() => {\n if (isControlled && value !== undefined) {\n setLines(splitLines(value));\n }\n }, [value, isControlled]);\n\n const getText = () => linesRef.current.join('\\n');\n\n const getCaretPosition = (): CaretPosition | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(range.startContainer)) {\n return { line: i, offset: range.startOffset };\n }\n }\n return null;\n };\n\n const getSelectionOffsets = (): {\n start: number;\n end: number;\n hasSelection: boolean;\n } | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const currentLines = linesRef.current;\n\n const findOffset = (node: Node, nodeOffset: number): number => {\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(node)) {\n let flat = 0;\n for (let j = 0; j < i; j++) {\n flat += currentLines[j].length + 1;\n }\n return flat + Math.min(nodeOffset, currentLines[i]?.length ?? 0);\n }\n }\n // Selection is on the root container (e.g. select-all)\n if (node === containerRef.current) {\n if (nodeOffset === 0) return 0;\n return currentLines.join('\\n').length;\n }\n return 0;\n };\n\n const start = findOffset(range.startContainer, range.startOffset);\n const end = findOffset(range.endContainer, range.endOffset);\n\n return {\n start: Math.min(start, end),\n end: Math.max(start, end),\n hasSelection: !range.collapsed,\n };\n };\n\n const setCaretPosition = (pos: CaretPosition) => {\n if (!containerRef.current) return;\n\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const lineEl = lineEls[pos.line];\n if (!lineEl) return;\n\n const editable = lineEl.querySelector('[data-editable]');\n const node =\n editable?.firstChild ?? editable ?? lineEl.firstChild ?? lineEl;\n\n const sel = window.getSelection();\n if (!sel) return;\n\n const range = document.createRange();\n const maxOff = Math.min(pos.offset, node.textContent?.length ?? 0);\n\n try {\n range.setStart(node, maxOff);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n } catch {\n range.selectNodeContents(node);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n };\n\n useLayoutEffect(() => {\n if (pendingCaretRef.current && containerRef.current) {\n setCaretPosition(pendingCaretRef.current);\n pendingCaretRef.current = null;\n }\n });\n\n const flatOffsetFromCaret = (pos: CaretPosition): number => {\n const currentLines = linesRef.current;\n let offset = 0;\n for (let i = 0; i < pos.line; i++) {\n offset += currentLines[i].length + 1;\n }\n return offset + pos.offset;\n };\n\n const caretFromFlatOffset = (\n flat: number,\n targetLines: string[]\n ): CaretPosition => {\n let rem = flat;\n for (let i = 0; i < targetLines.length; i++) {\n if (rem <= targetLines[i].length) {\n return { line: i, offset: rem };\n }\n rem -= targetLines[i].length + 1;\n }\n return {\n line: targetLines.length - 1,\n offset: targetLines[targetLines.length - 1]?.length ?? 0,\n };\n };\n\n const getCursorOffset = (): number => {\n const pos = getCaretPosition();\n if (!pos) return 0;\n return flatOffsetFromCaret(pos);\n };\n\n /**\n * Applies a text mutation: computes new lines, sets pending caret, updates state.\n */\n const applyTextChange = (newText: string, caretOffset: number) => {\n const newLines = splitLines(newText);\n pendingCaretRef.current = caretFromFlatOffset(caretOffset, newLines);\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleInput = () => {\n if (pendingCaretRef.current !== null) return;\n if (disabled || !containerRef.current) return;\n\n const caretPos = getCaretPosition();\n const newText = getTextFromContainer(containerRef.current);\n const newLines = splitLines(newText);\n\n pendingCaretRef.current = caretPos;\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n // Don't intercept during IME composition (CJK input)\n if (e.nativeEvent.isComposing) return;\n\n // Block undo/redo - browser would mutate DOM out of sync with React\n if ((e.metaKey || e.ctrlKey) && e.key === 'z') {\n e.preventDefault();\n return;\n }\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (e.key === 'Enter') {\n e.preventDefault();\n const newText =\n currentText.slice(0, selInfo.start) +\n '\\n' +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + 1);\n return;\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start === 0) return;\n\n let deleteFrom: number;\n if (e.metaKey) {\n // Cmd+Backspace: delete to start of line\n deleteFrom = lineStart(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Backspace: delete previous word\n deleteFrom = prevWordBoundary(currentText, selInfo.start);\n } else {\n // Regular backspace: delete one grapheme\n deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n }\n return;\n }\n\n if (e.key === 'Delete') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start >= currentText.length) return;\n\n let deleteTo: number;\n if (e.metaKey) {\n // Cmd+Delete: delete to end of line\n deleteTo = lineEnd(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Delete: delete next word\n deleteTo = nextWordBoundary(currentText, selInfo.start);\n } else {\n // Regular delete: delete one grapheme\n deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n };\n\n const handleCut = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo?.hasSelection) return;\n\n const currentText = linesRef.current.join('\\n');\n const selectedText = currentText.slice(selInfo.start, selInfo.end);\n\n // Write selected text to clipboard\n e.clipboardData.setData('text/plain', selectedText);\n\n // Delete the selected text\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const pastedText = e.clipboardData.getData('text/plain');\n if (!pastedText) return;\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const newText =\n currentText.slice(0, selInfo.start) +\n pastedText +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + pastedText.length);\n };\n\n const handleBeforeInput = (e: InputEvent<HTMLDivElement>) => {\n if (disabled) return;\n\n const inputEvent = e.nativeEvent as InputEvent;\n\n // Don't intercept during IME composition (CJK input)\n if (inputEvent.isComposing) return;\n\n const inputType = inputEvent.inputType;\n\n // Skip types handled by handleKeyDown (when keydown fires)\n if (inputType === 'insertParagraph' || inputType === 'insertLineBreak') {\n return;\n }\n\n // Handle deletions as fallback for mobile keyboards that don't fire keydown\n if (\n inputType === 'deleteContentBackward' ||\n inputType === 'deleteContentForward'\n ) {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else if (inputType === 'deleteContentBackward') {\n if (selInfo.start === 0) return;\n const deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n } else {\n if (selInfo.start >= currentText.length) return;\n const deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n\n // Handle spell-check replacements\n if (inputType === 'insertReplacementText') {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const replacement =\n inputEvent.data ?? inputEvent.dataTransfer?.getData('text/plain') ?? '';\n const newText =\n currentText.slice(0, selInfo.start) +\n replacement +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + replacement.length);\n return;\n }\n\n if (inputType === 'insertText' && inputEvent.data) {\n e.preventDefault();\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const inserted = inputEvent.data;\n const newText =\n currentText.slice(0, selInfo.start) +\n inserted +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + inserted.length);\n }\n };\n\n const handleDrop = (e: DragEvent<HTMLDivElement>) => {\n // Block drag-and-drop to prevent uncontrolled DOM mutations\n e.preventDefault();\n };\n\n const handleDragOver = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n };\n\n return {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCaretPosition,\n setCaretPosition,\n getCursorOffset,\n caretFromFlatOffset,\n };\n};\n\ntype LineProps = {\n index: number;\n text: string;\n isLast: boolean;\n ghostText?: string;\n};\n\nconst Line: FC<LineProps> = ({ index, text, isLast, ghostText }) => (\n <span data-line={index} className=\"block min-h-[1.5rem]\">\n <span data-editable>{text || '\\u200B'}</span>\n {ghostText && (\n <span\n data-ghost\n className=\"pointer-events-none select-none text-neutral\"\n aria-hidden=\"true\"\n >\n {ghostText}\n </span>\n )}\n {!isLast && <br />}\n </span>\n);\n\nexport type ContentEditableTextAreaHandle = {\n getContainer: () => HTMLDivElement | null;\n getText: () => string;\n focus: () => void;\n getCursorOffset: () => number;\n setCursorAtOffset: (offset: number) => void;\n};\n\nexport type ContentEditableTextAreaProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue'\n> & {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n minRows?: number;\n maxRows?: number;\n autoSize?: boolean;\n validationStyleEnabled?: boolean;\n variant?: InputVariant | `${InputVariant}`;\n ghostText?: string;\n ghostLine?: number;\n ghostOffset?: number;\n ref?: Ref<ContentEditableTextAreaHandle>;\n dir?: 'ltr' | 'rtl' | 'auto';\n} & Omit<\n VariantProps<typeof inputVariants>,\n 'validationStyleEnabled' | 'variant'\n >;\n\nconst LINE_HEIGHT = 24;\nconst LINE_PADDING = 12;\n\nexport const ContentEditableTextArea: FC<ContentEditableTextAreaProps> = ({\n value,\n defaultValue,\n onChange,\n placeholder,\n disabled = false,\n minRows = 1,\n maxRows = 999,\n autoSize = true,\n validationStyleEnabled = false,\n variant,\n ghostText,\n ghostLine,\n ghostOffset,\n onClick,\n className,\n dir = 'auto',\n ref,\n ...rest\n}) => {\n const {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCursorOffset,\n setCaretPosition,\n caretFromFlatOffset,\n } = useContentEditable({ value, defaultValue, onChange, disabled });\n\n const elRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = (el: HTMLDivElement | null) => {\n elRef.current = el;\n (containerRef as MutableRefObject<HTMLDivElement | null>).current = el;\n };\n\n useImperativeHandle(ref, () => ({\n getContainer: () => elRef.current,\n getText,\n focus: () => elRef.current?.focus(),\n getCursorOffset,\n setCursorAtOffset: (offset: number) => {\n setCaretPosition(caretFromFlatOffset(offset, lines));\n },\n }));\n\n useLayoutEffect(() => {\n if (!autoSize || !elRef.current) return;\n\n const el = elRef.current;\n const max = LINE_HEIGHT * maxRows + LINE_PADDING;\n const min = LINE_HEIGHT * minRows + LINE_PADDING;\n\n el.style.height = 'auto';\n const sh = el.scrollHeight;\n el.style.height = `${Math.max(Math.min(sh, max), min)}px`;\n el.style.overflowY = sh > max ? 'auto' : 'hidden';\n }, [lines, autoSize, maxRows, minRows]);\n\n const isEmpty = lines.length === 1 && lines[0] === '';\n const hasGhost =\n ghostText && ghostLine !== undefined && ghostOffset !== undefined;\n\n return (\n <div className=\"relative w-full\">\n {isEmpty && placeholder && (\n <div\n className=\"pointer-events-none absolute inset-0 select-none px-2 py-3 text-base text-neutral-400 leading-[1.5rem] md:py-2 md:text-sm\"\n aria-hidden=\"true\"\n >\n {placeholder}\n </div>\n )}\n\n <div\n {...rest}\n ref={setRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-placeholder={placeholder}\n aria-disabled={disabled}\n aria-autocomplete={hasGhost ? 'inline' : undefined}\n tabIndex={disabled ? -1 : 0}\n contentEditable={!disabled}\n suppressContentEditableWarning\n dir={dir}\n onInput={handleInput}\n onBeforeInput={handleBeforeInput}\n onKeyDown={handleKeyDown}\n onCut={handleCut}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onClick={onClick}\n className={cn(\n 'resize-none whitespace-pre-wrap break-words outline-none',\n inputVariants({\n variant,\n validationStyleEnabled: validationStyleEnabled\n ? 'enabled'\n : 'disabled',\n }),\n autoSize && 'overflow-y-auto',\n className\n )}\n >\n {lines.map((text, i) => (\n <Line\n key={i}\n index={i}\n text={text}\n isLast={i === lines.length - 1}\n ghostText={hasGhost && ghostLine === i ? ghostText : undefined}\n />\n ))}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;AAiCA,MAAM,mBAAmB;AAEzB,MAAM,wBAAwB,cAAsC;CAClE,MAAM,UAAU,UAAU,iBAAiB,aAAa;CACxD,IAAI,QAAQ,WAAW,GACrB,QAAQ,UAAU,eAAe,IAAI,MAAM,gBAAgB,EAAE,KAAK,EAAE;CAGtE,OAAO,MAAM,KAAK,OAAO,EACtB,KAAK,OAAO;EAEX,MAAM,MADW,GAAG,cAAc,iBACf,GAAG,eAAe,GAAG,eAAe;EACvD,OAAO,QAAQ,mBACX,KACA,IAAI,MAAM,gBAAgB,EAAE,KAAK,EAAE;CACzC,CAAC,EACA,KAAK,IAAI;AACd;AAEA,MAAM,cAAc,SAA2B;CAC7C,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,OAAO,MAAM,WAAW,IAAI,CAAC,EAAE,IAAI;AACrC;AAQA,MAAM,gCAA0D;CAC9D,IAAI,OAAO,SAAS,eAAe,EAAE,eAAe,OAAO,OAAO;CAClE,MAAM,gBACJ,KAMA;CACF,OAAO,IAAI,cAAc,QAAW,EAAE,aAAa,WAAW,CAAC;AACjE;AAEA,MAAM,oBAAoB,wBAAwB;;;;;AAMlD,MAAM,wBAAwB,MAAc,WAA2B;CACrE,IAAI,UAAU,GAAG,OAAO;CAExB,IAAI,mBAAmB;EACrB,MAAM,WAAW,CAAC,GAAG,kBAAkB,QAAQ,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC;EACrE,MAAM,OAAO,SAAS,SAAS,SAAS;EACxC,OAAO,OAAO,SAAS,KAAK,QAAQ,SAAS,SAAS;CACxD;CAGA,MAAM,OAAO,KAAK,WAAW,SAAS,CAAC;CACvC,IAAI,QAAQ,SAAU,QAAQ,SAAU,UAAU,GAChD,OAAO,SAAS;CAElB,OAAO,SAAS;AAClB;;;;AAKA,MAAM,wBAAwB,MAAc,WAA2B;CACrE,IAAI,UAAU,KAAK,QAAQ,OAAO,KAAK;CAEvC,IAAI,mBAAmB;EAErB,MAAM,QAAQ,CADI,GAAG,kBAAkB,QAAQ,KAAK,MAAM,MAAM,CAAC,CAC5C,EAAE;EACvB,OAAO,QAAQ,SAAS,MAAM,QAAQ,SAAS,SAAS;CAC1D;CAGA,MAAM,OAAO,KAAK,WAAW,MAAM;CACnC,IAAI,QAAQ,SAAU,QAAQ,SAAU,SAAS,IAAI,KAAK,QACxD,OAAO,SAAS;CAElB,OAAO,SAAS;AAClB;;;;AAKA,MAAM,oBAAoB,MAAc,WAA2B;CACjE,IAAI,UAAU,GAAG,OAAO;CACxB,IAAI,IAAI,SAAS;CAEjB,OAAO,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,GAAG;CAExC,OAAO,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,GAAG;CACxC,OAAO;AACT;;;;AAKA,MAAM,oBAAoB,MAAc,WAA2B;CACjE,IAAI,UAAU,KAAK,QAAQ,OAAO,KAAK;CACvC,IAAI,IAAI;CAER,OAAO,IAAI,KAAK,UAAU,KAAK,KAAK,KAAK,EAAE,GAAG;CAE9C,OAAO,IAAI,KAAK,UAAU,KAAK,KAAK,KAAK,EAAE,GAAG;CAC9C,OAAO;AACT;;;;AAKA,MAAM,aAAa,MAAc,WAA2B;CAG1D,OAFe,KAAK,MAAM,GAAG,MACJ,EAAE,YAAY,IACtB,IAAI;AACvB;;;;AAKA,MAAM,WAAW,MAAc,WAA2B;CACxD,MAAM,cAAc,KAAK,QAAQ,MAAM,MAAM;CAC7C,OAAO,gBAAgB,KAAK,KAAK,SAAS;AAC5C;AAEA,MAAa,sBAAsB,EACjC,OACA,cACA,UACA,WAAW,YACoB;CAC/B,MAAM,eAAe,SAAS,gBAAgB;CAC9C,MAAM,CAAC,OAAO,YAAY,eAAyB,WAAW,YAAY,CAAC;CAC3E,MAAM,eAAe,OAA8B,IAAI;CACvD,MAAM,kBAAkB,OAA6B,IAAI;CACzD,MAAM,eAAe,UAAU;CAG/B,MAAM,WAAW,OAAO,KAAK;CAC7B,SAAS,UAAU;CAEnB,gBAAgB;EACd,IAAI,gBAAgB,UAAU,QAC5B,SAAS,WAAW,KAAK,CAAC;CAE9B,GAAG,CAAC,OAAO,YAAY,CAAC;CAExB,MAAM,gBAAgB,SAAS,QAAQ,KAAK,IAAI;CAEhD,MAAM,yBAA+C;EACnD,MAAM,MAAM,OAAO,aAAa;EAChC,IAAI,CAAC,KAAK,cAAc,CAAC,aAAa,SAAS,OAAO;EAEtD,MAAM,QAAQ,IAAI,WAAW,CAAC;EAC9B,MAAM,UAAU,aAAa,QAAQ,iBAAiB,aAAa;EAEnE,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,IAAI,QAAQ,GAAG,SAAS,MAAM,cAAc,GAC1C,OAAO;GAAE,MAAM;GAAG,QAAQ,MAAM;EAAY;EAGhD,OAAO;CACT;CAEA,MAAM,4BAIM;EACV,MAAM,MAAM,OAAO,aAAa;EAChC,IAAI,CAAC,KAAK,cAAc,CAAC,aAAa,SAAS,OAAO;EAEtD,MAAM,QAAQ,IAAI,WAAW,CAAC;EAC9B,MAAM,UAAU,aAAa,QAAQ,iBAAiB,aAAa;EACnE,MAAM,eAAe,SAAS;EAE9B,MAAM,cAAc,MAAY,eAA+B;GAC7D,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,IAAI,QAAQ,GAAG,SAAS,IAAI,GAAG;IAC7B,IAAI,OAAO;IACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,aAAa,GAAG,SAAS;IAEnC,OAAO,OAAO,KAAK,IAAI,YAAY,aAAa,IAAI,UAAU,CAAC;GACjE;GAGF,IAAI,SAAS,aAAa,SAAS;IACjC,IAAI,eAAe,GAAG,OAAO;IAC7B,OAAO,aAAa,KAAK,IAAI,EAAE;GACjC;GACA,OAAO;EACT;EAEA,MAAM,QAAQ,WAAW,MAAM,gBAAgB,MAAM,WAAW;EAChE,MAAM,MAAM,WAAW,MAAM,cAAc,MAAM,SAAS;EAE1D,OAAO;GACL,OAAO,KAAK,IAAI,OAAO,GAAG;GAC1B,KAAK,KAAK,IAAI,OAAO,GAAG;GACxB,cAAc,CAAC,MAAM;EACvB;CACF;CAEA,MAAM,oBAAoB,QAAuB;EAC/C,IAAI,CAAC,aAAa,SAAS;EAG3B,MAAM,SADU,aAAa,QAAQ,iBAAiB,aACjC,EAAE,IAAI;EAC3B,IAAI,CAAC,QAAQ;EAEb,MAAM,WAAW,OAAO,cAAc,iBAAiB;EACvD,MAAM,OACJ,UAAU,cAAc,YAAY,OAAO,cAAc;EAE3D,MAAM,MAAM,OAAO,aAAa;EAChC,IAAI,CAAC,KAAK;EAEV,MAAM,QAAQ,SAAS,YAAY;EACnC,MAAM,SAAS,KAAK,IAAI,IAAI,QAAQ,KAAK,aAAa,UAAU,CAAC;EAEjE,IAAI;GACF,MAAM,SAAS,MAAM,MAAM;GAC3B,MAAM,SAAS,IAAI;GACnB,IAAI,gBAAgB;GACpB,IAAI,SAAS,KAAK;EACpB,QAAQ;GACN,MAAM,mBAAmB,IAAI;GAC7B,MAAM,SAAS,KAAK;GACpB,IAAI,gBAAgB;GACpB,IAAI,SAAS,KAAK;EACpB;CACF;CAEA,sBAAsB;EACpB,IAAI,gBAAgB,WAAW,aAAa,SAAS;GACnD,iBAAiB,gBAAgB,OAAO;GACxC,gBAAgB,UAAU;EAC5B;CACF,CAAC;CAED,MAAM,uBAAuB,QAA+B;EAC1D,MAAM,eAAe,SAAS;EAC9B,IAAI,SAAS;EACb,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,KAC5B,UAAU,aAAa,GAAG,SAAS;EAErC,OAAO,SAAS,IAAI;CACtB;CAEA,MAAM,uBACJ,MACA,gBACkB;EAClB,IAAI,MAAM;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;GAC3C,IAAI,OAAO,YAAY,GAAG,QACxB,OAAO;IAAE,MAAM;IAAG,QAAQ;GAAI;GAEhC,OAAO,YAAY,GAAG,SAAS;EACjC;EACA,OAAO;GACL,MAAM,YAAY,SAAS;GAC3B,QAAQ,YAAY,YAAY,SAAS,IAAI,UAAU;EACzD;CACF;CAEA,MAAM,wBAAgC;EACpC,MAAM,MAAM,iBAAiB;EAC7B,IAAI,CAAC,KAAK,OAAO;EACjB,OAAO,oBAAoB,GAAG;CAChC;;;;CAKA,MAAM,mBAAmB,SAAiB,gBAAwB;EAChE,MAAM,WAAW,WAAW,OAAO;EACnC,gBAAgB,UAAU,oBAAoB,aAAa,QAAQ;EACnE,SAAS,QAAQ;EACjB,WAAW,OAAO;CACpB;CAEA,MAAM,oBAAoB;EACxB,IAAI,gBAAgB,YAAY,MAAM;EACtC,IAAI,YAAY,CAAC,aAAa,SAAS;EAEvC,MAAM,WAAW,iBAAiB;EAClC,MAAM,UAAU,qBAAqB,aAAa,OAAO;EACzD,MAAM,WAAW,WAAW,OAAO;EAEnC,gBAAgB,UAAU;EAC1B,SAAS,QAAQ;EACjB,WAAW,OAAO;CACpB;CAEA,MAAM,iBAAiB,MAAqC;EAC1D,IAAI,UAAU;GACZ,EAAE,eAAe;GACjB;EACF;EAGA,IAAI,EAAE,YAAY,aAAa;EAG/B,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;GAC7C,EAAE,eAAe;GACjB;EACF;EAEA,MAAM,UAAU,oBAAoB;EACpC,IAAI,CAAC,SAAS;EAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;EAE9C,IAAI,EAAE,QAAQ,SAAS;GACrB,EAAE,eAAe;GAKjB,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,OACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,CAAC;GAC1C;EACF;EAEA,IAAI,EAAE,QAAQ,aAAa;GACzB,EAAE,eAAe;GAEjB,IAAI,QAAQ,cAGV,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;QACjC;IACL,IAAI,QAAQ,UAAU,GAAG;IAEzB,IAAI;IACJ,IAAI,EAAE,SAEJ,aAAa,UAAU,aAAa,QAAQ,KAAK;SAC5C,IAAI,EAAE,QAEX,aAAa,iBAAiB,aAAa,QAAQ,KAAK;SAGxD,aAAa,qBAAqB,aAAa,QAAQ,KAAK;IAK9D,gBADE,YAAY,MAAM,GAAG,UAAU,IAAI,YAAY,MAAM,QAAQ,KAAK,GAC3C,UAAU;GACrC;GACA;EACF;EAEA,IAAI,EAAE,QAAQ,UAAU;GACtB,EAAE,eAAe;GAEjB,IAAI,QAAQ,cAGV,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;QACjC;IACL,IAAI,QAAQ,SAAS,YAAY,QAAQ;IAEzC,IAAI;IACJ,IAAI,EAAE,SAEJ,WAAW,QAAQ,aAAa,QAAQ,KAAK;SACxC,IAAI,EAAE,QAEX,WAAW,iBAAiB,aAAa,QAAQ,KAAK;SAGtD,WAAW,qBAAqB,aAAa,QAAQ,KAAK;IAK5D,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GACzC,QAAQ,KAAK;GACxC;GACA;EACF;CACF;CAEA,MAAM,aAAa,MAAsC;EACvD,IAAI,UAAU;GACZ,EAAE,eAAe;GACjB;EACF;EAEA,EAAE,eAAe;EACjB,MAAM,UAAU,oBAAoB;EACpC,IAAI,CAAC,SAAS,cAAc;EAE5B,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;EAC9C,MAAM,eAAe,YAAY,MAAM,QAAQ,OAAO,QAAQ,GAAG;EAGjE,EAAE,cAAc,QAAQ,cAAc,YAAY;EAKlD,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;CACxC;CAEA,MAAM,eAAe,MAAsC;EACzD,IAAI,UAAU;GACZ,EAAE,eAAe;GACjB;EACF;EAEA,EAAE,eAAe;EACjB,MAAM,aAAa,EAAE,cAAc,QAAQ,YAAY;EACvD,IAAI,CAAC,YAAY;EAEjB,MAAM,UAAU,oBAAoB;EACpC,IAAI,CAAC,SAAS;EAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;EAK9C,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,aACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,WAAW,MAAM;CAC5D;CAEA,MAAM,qBAAqB,MAAkC;EAC3D,IAAI,UAAU;EAEd,MAAM,aAAa,EAAE;EAGrB,IAAI,WAAW,aAAa;EAE5B,MAAM,YAAY,WAAW;EAG7B,IAAI,cAAc,qBAAqB,cAAc,mBACnD;EAIF,IACE,cAAc,2BACd,cAAc,wBACd;GACA,EAAE,eAAe;GACjB,MAAM,UAAU,oBAAoB;GACpC,IAAI,CAAC,SAAS;GAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;GAE9C,IAAI,QAAQ,cAGV,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;QACjC,IAAI,cAAc,yBAAyB;IAChD,IAAI,QAAQ,UAAU,GAAG;IACzB,MAAM,aAAa,qBAAqB,aAAa,QAAQ,KAAK;IAGlE,gBADE,YAAY,MAAM,GAAG,UAAU,IAAI,YAAY,MAAM,QAAQ,KAAK,GAC3C,UAAU;GACrC,OAAO;IACL,IAAI,QAAQ,SAAS,YAAY,QAAQ;IACzC,MAAM,WAAW,qBAAqB,aAAa,QAAQ,KAAK;IAGhE,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GACzC,QAAQ,KAAK;GACxC;GACA;EACF;EAGA,IAAI,cAAc,yBAAyB;GACzC,EAAE,eAAe;GACjB,MAAM,UAAU,oBAAoB;GACpC,IAAI,CAAC,SAAS;GAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;GAC9C,MAAM,cACJ,WAAW,QAAQ,WAAW,cAAc,QAAQ,YAAY,KAAK;GAKvE,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,cACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,YAAY,MAAM;GAC3D;EACF;EAEA,IAAI,cAAc,gBAAgB,WAAW,MAAM;GACjD,EAAE,eAAe;GAEjB,MAAM,UAAU,oBAAoB;GACpC,IAAI,CAAC,SAAS;GAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;GAC9C,MAAM,WAAW,WAAW;GAK5B,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,WACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,SAAS,MAAM;EAC1D;CACF;CAEA,MAAM,cAAc,MAAiC;EAEnD,EAAE,eAAe;CACnB;CAEA,MAAM,kBAAkB,MAAiC;EACvD,EAAE,eAAe;CACnB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AASA,MAAM,QAAuB,EAAE,OAAO,MAAM,QAAQ,gBAClD,qBAAC,QAAD;CAAM,aAAW;CAAO,WAAU;WAAlC;EACE,oBAAC,QAAD;GAAM;aAAe,QAAQ;EAAe;EAC3C,aACC,oBAAC,QAAD;GACE;GACA,WAAU;GACV,eAAY;aAEX;EACG;EAEP,CAAC,UAAU,oBAAC,MAAD,CAAK;CACb;;AAmCR,MAAM,cAAc;AACpB,MAAM,eAAe;AAErB,MAAa,2BAA6D,EACxE,OACA,cACA,UACA,aACA,WAAW,OACX,UAAU,GACV,UAAU,KACV,WAAW,MACX,yBAAyB,OACzB,SACA,WACA,WACA,aACA,SACA,WACA,MAAM,QACN,KACA,GAAG,WACC;CACJ,MAAM,EACJ,OACA,cACA,SACA,aACA,mBACA,eACA,WACA,aACA,YACA,gBACA,iBACA,kBACA,wBACE,mBAAmB;EAAE;EAAO;EAAc;EAAU;CAAS,CAAC;CAElE,MAAM,QAAQ,OAA8B,IAAI;CAEhD,MAAM,UAAU,OAA8B;EAC5C,MAAM,UAAU;EAChB,AAAC,aAAyD,UAAU;CACtE;CAEA,oBAAoB,YAAY;EAC9B,oBAAoB,MAAM;EAC1B;EACA,aAAa,MAAM,SAAS,MAAM;EAClC;EACA,oBAAoB,WAAmB;GACrC,iBAAiB,oBAAoB,QAAQ,KAAK,CAAC;EACrD;CACF,EAAE;CAEF,sBAAsB;EACpB,IAAI,CAAC,YAAY,CAAC,MAAM,SAAS;EAEjC,MAAM,KAAK,MAAM;EACjB,MAAM,MAAM,cAAc,UAAU;EACpC,MAAM,MAAM,cAAc,UAAU;EAEpC,GAAG,MAAM,SAAS;EAClB,MAAM,KAAK,GAAG;EACd,GAAG,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,GAAG,EAAE;EACtD,GAAG,MAAM,YAAY,KAAK,MAAM,SAAS;CAC3C,GAAG;EAAC;EAAO;EAAU;EAAS;CAAO,CAAC;CAEtC,MAAM,UAAU,MAAM,WAAW,KAAK,MAAM,OAAO;CACnD,MAAM,WACJ,aAAa,cAAc,UAAa,gBAAgB;CAE1D,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,WAAW,eACV,oBAAC,OAAD;GACE,WAAU;GACV,eAAY;aAEX;EACE,IAGP,oBAAC,OAAD;GACE,GAAI;GACJ,KAAK;GACL,MAAK;GACL,kBAAe;GACf,oBAAkB;GAClB,iBAAe;GACf,qBAAmB,WAAW,WAAW;GACzC,UAAU,WAAW,KAAK;GAC1B,iBAAiB,CAAC;GAClB;GACK;GACL,SAAS;GACT,eAAe;GACf,WAAW;GACX,OAAO;GACP,SAAS;GACT,QAAQ;GACR,YAAY;GACH;GACT,WAAW,GACT,4DACA,cAAc;IACZ;IACA,wBAAwB,yBACpB,YACA;GACN,CAAC,GACD,YAAY,mBACZ,SACF;aAEC,MAAM,KAAK,MAAM,MAChB,oBAAC,MAAD;IAEE,OAAO;IACD;IACN,QAAQ,MAAM,MAAM,SAAS;IAC7B,WAAW,YAAY,cAAc,IAAI,YAAY;GACtD,GALM,CAKN,CACF;EACE,EACF;;AAET"}
1
+ {"version":3,"file":"ContentEditableTextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/ContentEditableTextArea.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport type { VariantProps } from 'class-variance-authority';\nimport {\n type ClipboardEvent,\n type DragEvent,\n type FC,\n type HTMLAttributes,\n type InputEvent,\n type KeyboardEvent,\n type Ref,\n type RefObject,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { inputVariants } from '../Input';\n\ntype CaretPosition = {\n line: number;\n offset: number;\n};\n\ntype UseContentEditableOptions = {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n};\n\nconst ZERO_WIDTH_SPACE = '\\u200B';\n\nconst getTextFromContainer = (container: HTMLDivElement): string => {\n const lineEls = container.querySelectorAll('[data-line]');\n if (lineEls.length === 0) {\n return (container.textContent ?? '').split(ZERO_WIDTH_SPACE).join('');\n }\n\n return Array.from(lineEls)\n .map((el) => {\n const editable = el.querySelector('[data-editable]');\n const raw = editable?.textContent ?? el.textContent ?? '';\n return raw === ZERO_WIDTH_SPACE\n ? ''\n : raw.split(ZERO_WIDTH_SPACE).join('');\n })\n .join('\\n');\n};\n\nconst splitLines = (text: string): string[] => {\n const lines = text.split('\\n');\n return lines.length === 0 ? [''] : lines;\n};\n\n// Cached Intl.Segmenter for grapheme-aware deletion (emoji, CJK, etc.)\n// Intl.Segmenter is ES2022+ but we feature-detect at runtime.\ntype GraphemeSegmenter = {\n segment: (input: string) => Iterable<{ segment: string }>;\n};\n\nconst createGraphemeSegmenter = (): GraphemeSegmenter | null => {\n if (typeof Intl === 'undefined' || !('Segmenter' in Intl)) return null;\n const SegmenterCtor = (\n Intl as unknown as Record<\n string,\n new (\n ...args: unknown[]\n ) => GraphemeSegmenter\n >\n ).Segmenter;\n return new SegmenterCtor(undefined, { granularity: 'grapheme' });\n};\n\nconst graphemeSegmenter = createGraphemeSegmenter();\n\n/**\n * Find the previous grapheme cluster boundary for safe deletion.\n * Falls back to code-point-aware deletion if Intl.Segmenter is unavailable.\n */\nconst prevGraphemeBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(0, offset))];\n const last = segments[segments.length - 1];\n return last ? offset - last.segment.length : offset - 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset - 1);\n if (code >= 0xdc00 && code <= 0xdfff && offset >= 2) {\n return offset - 2;\n }\n return offset - 1;\n};\n\n/**\n * Find the next grapheme cluster boundary for safe forward deletion.\n */\nconst nextGraphemeBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n\n if (graphemeSegmenter) {\n const segments = [...graphemeSegmenter.segment(text.slice(offset))];\n const first = segments[0];\n return first ? offset + first.segment.length : offset + 1;\n }\n\n // Fallback: handle surrogate pairs\n const code = text.charCodeAt(offset);\n if (code >= 0xd800 && code <= 0xdbff && offset + 1 < text.length) {\n return offset + 2;\n }\n return offset + 1;\n};\n\n/**\n * Find the previous word boundary for Option+Backspace.\n */\nconst prevWordBoundary = (text: string, offset: number): number => {\n if (offset <= 0) return 0;\n let i = offset - 1;\n // Skip whitespace\n while (i > 0 && /\\s/.test(text[i - 1])) i--;\n // Skip word characters\n while (i > 0 && /\\S/.test(text[i - 1])) i--;\n return i;\n};\n\n/**\n * Find the next word boundary for Option+Delete.\n */\nconst nextWordBoundary = (text: string, offset: number): number => {\n if (offset >= text.length) return text.length;\n let i = offset;\n // Skip word characters\n while (i < text.length && /\\S/.test(text[i])) i++;\n // Skip whitespace\n while (i < text.length && /\\s/.test(text[i])) i++;\n return i;\n};\n\n/**\n * Find the start of the current line (for Cmd+Backspace).\n */\nconst lineStart = (text: string, offset: number): number => {\n const before = text.slice(0, offset);\n const lastNewline = before.lastIndexOf('\\n');\n return lastNewline + 1;\n};\n\n/**\n * Find the end of the current line (for Cmd+Delete).\n */\nconst lineEnd = (text: string, offset: number): number => {\n const nextNewline = text.indexOf('\\n', offset);\n return nextNewline === -1 ? text.length : nextNewline;\n};\n\nexport const useContentEditable = ({\n value,\n defaultValue,\n onChange,\n disabled = false,\n}: UseContentEditableOptions) => {\n const initialValue = value ?? defaultValue ?? '';\n const [lines, setLines] = useState<string[]>(() => splitLines(initialValue));\n const containerRef = useRef<HTMLDivElement | null>(null);\n const pendingCaretRef = useRef<CaretPosition | null>(null);\n const isControlled = value !== undefined;\n\n // Keep a ref to the latest lines to avoid stale closures in rapid typing\n const linesRef = useRef(lines);\n linesRef.current = lines;\n\n useEffect(() => {\n if (isControlled && value !== undefined) {\n setLines(splitLines(value));\n }\n }, [value, isControlled]);\n\n const getText = () => linesRef.current.join('\\n');\n\n const getCaretPosition = (): CaretPosition | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(range.startContainer)) {\n return { line: i, offset: range.startOffset };\n }\n }\n return null;\n };\n\n const getSelectionOffsets = (): {\n start: number;\n end: number;\n hasSelection: boolean;\n } | null => {\n const sel = window.getSelection();\n if (!sel?.rangeCount || !containerRef.current) return null;\n\n const range = sel.getRangeAt(0);\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const currentLines = linesRef.current;\n\n const findOffset = (node: Node, nodeOffset: number): number => {\n for (let i = 0; i < lineEls.length; i++) {\n if (lineEls[i].contains(node)) {\n let flat = 0;\n for (let j = 0; j < i; j++) {\n flat += currentLines[j].length + 1;\n }\n return flat + Math.min(nodeOffset, currentLines[i]?.length ?? 0);\n }\n }\n // Selection is on the root container (e.g. select-all)\n if (node === containerRef.current) {\n if (nodeOffset === 0) return 0;\n return currentLines.join('\\n').length;\n }\n return 0;\n };\n\n const start = findOffset(range.startContainer, range.startOffset);\n const end = findOffset(range.endContainer, range.endOffset);\n\n return {\n start: Math.min(start, end),\n end: Math.max(start, end),\n hasSelection: !range.collapsed,\n };\n };\n\n const setCaretPosition = (pos: CaretPosition) => {\n if (!containerRef.current) return;\n\n const lineEls = containerRef.current.querySelectorAll('[data-line]');\n const lineEl = lineEls[pos.line];\n if (!lineEl) return;\n\n const editable = lineEl.querySelector('[data-editable]');\n const node =\n editable?.firstChild ?? editable ?? lineEl.firstChild ?? lineEl;\n\n const sel = window.getSelection();\n if (!sel) return;\n\n const range = document.createRange();\n const maxOff = Math.min(pos.offset, node.textContent?.length ?? 0);\n\n try {\n range.setStart(node, maxOff);\n range.collapse(true);\n sel.removeAllRanges();\n sel.addRange(range);\n } catch {\n range.selectNodeContents(node);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n }\n };\n\n useLayoutEffect(() => {\n if (pendingCaretRef.current && containerRef.current) {\n setCaretPosition(pendingCaretRef.current);\n pendingCaretRef.current = null;\n }\n });\n\n const flatOffsetFromCaret = (pos: CaretPosition): number => {\n const currentLines = linesRef.current;\n let offset = 0;\n for (let i = 0; i < pos.line; i++) {\n offset += currentLines[i].length + 1;\n }\n return offset + pos.offset;\n };\n\n const caretFromFlatOffset = (\n flat: number,\n targetLines: string[]\n ): CaretPosition => {\n let rem = flat;\n for (let i = 0; i < targetLines.length; i++) {\n if (rem <= targetLines[i].length) {\n return { line: i, offset: rem };\n }\n rem -= targetLines[i].length + 1;\n }\n return {\n line: targetLines.length - 1,\n offset: targetLines[targetLines.length - 1]?.length ?? 0,\n };\n };\n\n const getCursorOffset = (): number => {\n const pos = getCaretPosition();\n if (!pos) return 0;\n return flatOffsetFromCaret(pos);\n };\n\n /**\n * Applies a text mutation: computes new lines, sets pending caret, updates state.\n */\n const applyTextChange = (newText: string, caretOffset: number) => {\n const newLines = splitLines(newText);\n pendingCaretRef.current = caretFromFlatOffset(caretOffset, newLines);\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleInput = () => {\n if (pendingCaretRef.current !== null) return;\n if (disabled || !containerRef.current) return;\n\n const caretPos = getCaretPosition();\n const newText = getTextFromContainer(containerRef.current);\n const newLines = splitLines(newText);\n\n pendingCaretRef.current = caretPos;\n setLines(newLines);\n onChange?.(newText);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n // Don't intercept during IME composition (CJK input)\n if (e.nativeEvent.isComposing) return;\n\n // Block undo/redo - browser would mutate DOM out of sync with React\n if ((e.metaKey || e.ctrlKey) && e.key === 'z') {\n e.preventDefault();\n return;\n }\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (e.key === 'Enter') {\n e.preventDefault();\n const newText =\n currentText.slice(0, selInfo.start) +\n '\\n' +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + 1);\n return;\n }\n\n if (e.key === 'Backspace') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start === 0) return;\n\n let deleteFrom: number;\n if (e.metaKey) {\n // Cmd+Backspace: delete to start of line\n deleteFrom = lineStart(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Backspace: delete previous word\n deleteFrom = prevWordBoundary(currentText, selInfo.start);\n } else {\n // Regular backspace: delete one grapheme\n deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n }\n return;\n }\n\n if (e.key === 'Delete') {\n e.preventDefault();\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else {\n if (selInfo.start >= currentText.length) return;\n\n let deleteTo: number;\n if (e.metaKey) {\n // Cmd+Delete: delete to end of line\n deleteTo = lineEnd(currentText, selInfo.start);\n } else if (e.altKey) {\n // Option+Delete: delete next word\n deleteTo = nextWordBoundary(currentText, selInfo.start);\n } else {\n // Regular delete: delete one grapheme\n deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n }\n\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n };\n\n const handleCut = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo?.hasSelection) return;\n\n const currentText = linesRef.current.join('\\n');\n const selectedText = currentText.slice(selInfo.start, selInfo.end);\n\n // Write selected text to clipboard\n e.clipboardData.setData('text/plain', selectedText);\n\n // Delete the selected text\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n };\n\n const handlePaste = (e: ClipboardEvent<HTMLDivElement>) => {\n if (disabled) {\n e.preventDefault();\n return;\n }\n\n e.preventDefault();\n const pastedText = e.clipboardData.getData('text/plain');\n if (!pastedText) return;\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const newText =\n currentText.slice(0, selInfo.start) +\n pastedText +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + pastedText.length);\n };\n\n const handleBeforeInput = (e: InputEvent<HTMLDivElement>) => {\n if (disabled) return;\n\n const inputEvent = e.nativeEvent as InputEvent;\n\n // Don't intercept during IME composition (CJK input)\n if (inputEvent.isComposing) return;\n\n const inputType = inputEvent.inputType;\n\n // Skip types handled by handleKeyDown (when keydown fires)\n if (inputType === 'insertParagraph' || inputType === 'insertLineBreak') {\n return;\n }\n\n // Handle deletions as fallback for mobile keyboards that don't fire keydown\n if (\n inputType === 'deleteContentBackward' ||\n inputType === 'deleteContentForward'\n ) {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n\n if (selInfo.hasSelection) {\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start);\n } else if (inputType === 'deleteContentBackward') {\n if (selInfo.start === 0) return;\n const deleteFrom = prevGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, deleteFrom) + currentText.slice(selInfo.start);\n applyTextChange(newText, deleteFrom);\n } else {\n if (selInfo.start >= currentText.length) return;\n const deleteTo = nextGraphemeBoundary(currentText, selInfo.start);\n const newText =\n currentText.slice(0, selInfo.start) + currentText.slice(deleteTo);\n applyTextChange(newText, selInfo.start);\n }\n return;\n }\n\n // Handle spell-check replacements\n if (inputType === 'insertReplacementText') {\n e.preventDefault();\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const replacement =\n inputEvent.data ?? inputEvent.dataTransfer?.getData('text/plain') ?? '';\n const newText =\n currentText.slice(0, selInfo.start) +\n replacement +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + replacement.length);\n return;\n }\n\n if (inputType === 'insertText' && inputEvent.data) {\n e.preventDefault();\n\n const selInfo = getSelectionOffsets();\n if (!selInfo) return;\n\n const currentText = linesRef.current.join('\\n');\n const inserted = inputEvent.data;\n const newText =\n currentText.slice(0, selInfo.start) +\n inserted +\n currentText.slice(selInfo.end);\n applyTextChange(newText, selInfo.start + inserted.length);\n }\n };\n\n const handleDrop = (e: DragEvent<HTMLDivElement>) => {\n // Block drag-and-drop to prevent uncontrolled DOM mutations\n e.preventDefault();\n };\n\n const handleDragOver = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n };\n\n return {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCaretPosition,\n setCaretPosition,\n getCursorOffset,\n caretFromFlatOffset,\n };\n};\n\ntype LineProps = {\n index: number;\n text: string;\n isLast: boolean;\n ghostText?: string;\n};\n\nconst Line: FC<LineProps> = ({ index, text, isLast, ghostText }) => (\n <span data-line={index} className=\"block min-h-[1.5rem]\">\n <span data-editable>{text || '\\u200B'}</span>\n {ghostText && (\n <span\n data-ghost\n className=\"pointer-events-none select-none text-neutral\"\n aria-hidden=\"true\"\n >\n {ghostText}\n </span>\n )}\n {!isLast && <br />}\n </span>\n);\n\nexport type ContentEditableTextAreaHandle = {\n getContainer: () => HTMLDivElement | null;\n getText: () => string;\n focus: () => void;\n getCursorOffset: () => number;\n setCursorAtOffset: (offset: number) => void;\n};\n\nexport type ContentEditableTextAreaProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue'\n> & {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n minRows?: number;\n maxRows?: number;\n autoSize?: boolean;\n validationStyleEnabled?: boolean;\n variant?: InputVariant | `${InputVariant}`;\n ghostText?: string;\n ghostLine?: number;\n ghostOffset?: number;\n ref?: Ref<ContentEditableTextAreaHandle>;\n dir?: 'ltr' | 'rtl' | 'auto';\n} & Omit<\n VariantProps<typeof inputVariants>,\n 'validationStyleEnabled' | 'variant'\n >;\n\nconst LINE_HEIGHT = 24;\nconst LINE_PADDING = 12;\n\nexport const ContentEditableTextArea: FC<ContentEditableTextAreaProps> = ({\n value,\n defaultValue,\n onChange,\n placeholder,\n disabled = false,\n minRows = 1,\n maxRows = 999,\n autoSize = true,\n validationStyleEnabled = false,\n variant,\n ghostText,\n ghostLine,\n ghostOffset,\n onClick,\n className,\n dir = 'auto',\n ref,\n ...rest\n}) => {\n const {\n lines,\n containerRef,\n getText,\n handleInput,\n handleBeforeInput,\n handleKeyDown,\n handleCut,\n handlePaste,\n handleDrop,\n handleDragOver,\n getCursorOffset,\n setCaretPosition,\n caretFromFlatOffset,\n } = useContentEditable({ value, defaultValue, onChange, disabled });\n\n const elRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = (el: HTMLDivElement | null) => {\n elRef.current = el;\n (containerRef as RefObject<HTMLDivElement | null>).current = el;\n };\n\n useImperativeHandle(ref, () => ({\n getContainer: () => elRef.current,\n getText,\n focus: () => elRef.current?.focus(),\n getCursorOffset,\n setCursorAtOffset: (offset: number) => {\n setCaretPosition(caretFromFlatOffset(offset, lines));\n },\n }));\n\n useLayoutEffect(() => {\n if (!autoSize || !elRef.current) return;\n\n const el = elRef.current;\n const max = LINE_HEIGHT * maxRows + LINE_PADDING;\n const min = LINE_HEIGHT * minRows + LINE_PADDING;\n\n el.style.height = 'auto';\n const sh = el.scrollHeight;\n el.style.height = `${Math.max(Math.min(sh, max), min)}px`;\n el.style.overflowY = sh > max ? 'auto' : 'hidden';\n }, [lines, autoSize, maxRows, minRows]);\n\n const isEmpty = lines.length === 1 && lines[0] === '';\n const hasGhost =\n ghostText && ghostLine !== undefined && ghostOffset !== undefined;\n\n return (\n <div className=\"relative w-full\">\n {isEmpty && placeholder && (\n <div\n className=\"pointer-events-none absolute inset-0 select-none px-2 py-3 text-base text-neutral-400 leading-[1.5rem] md:py-2 md:text-sm\"\n aria-hidden=\"true\"\n >\n {placeholder}\n </div>\n )}\n\n <div\n {...rest}\n ref={setRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-placeholder={placeholder}\n aria-disabled={disabled}\n aria-autocomplete={hasGhost ? 'inline' : undefined}\n tabIndex={disabled ? -1 : 0}\n contentEditable={!disabled}\n suppressContentEditableWarning\n dir={dir}\n onInput={handleInput}\n onBeforeInput={handleBeforeInput}\n onKeyDown={handleKeyDown}\n onCut={handleCut}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onClick={onClick}\n className={cn(\n 'resize-none whitespace-pre-wrap break-words outline-none',\n inputVariants({\n variant,\n validationStyleEnabled: validationStyleEnabled\n ? 'enabled'\n : 'disabled',\n }),\n autoSize && 'overflow-y-auto',\n className\n )}\n >\n {lines.map((text, i) => (\n <Line\n key={i}\n index={i}\n text={text}\n isLast={i === lines.length - 1}\n ghostText={hasGhost && ghostLine === i ? ghostText : undefined}\n />\n ))}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;AAiCA,MAAM,mBAAmB;AAEzB,MAAM,wBAAwB,cAAsC;CAClE,MAAM,UAAU,UAAU,iBAAiB,aAAa;CACxD,IAAI,QAAQ,WAAW,GACrB,QAAQ,UAAU,eAAe,IAAI,MAAM,gBAAgB,EAAE,KAAK,EAAE;CAGtE,OAAO,MAAM,KAAK,OAAO,EACtB,KAAK,OAAO;EAEX,MAAM,MADW,GAAG,cAAc,iBACf,GAAG,eAAe,GAAG,eAAe;EACvD,OAAO,QAAQ,mBACX,KACA,IAAI,MAAM,gBAAgB,EAAE,KAAK,EAAE;CACzC,CAAC,EACA,KAAK,IAAI;AACd;AAEA,MAAM,cAAc,SAA2B;CAC7C,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,OAAO,MAAM,WAAW,IAAI,CAAC,EAAE,IAAI;AACrC;AAQA,MAAM,gCAA0D;CAC9D,IAAI,OAAO,SAAS,eAAe,EAAE,eAAe,OAAO,OAAO;CAClE,MAAM,gBACJ,KAMA;CACF,OAAO,IAAI,cAAc,QAAW,EAAE,aAAa,WAAW,CAAC;AACjE;AAEA,MAAM,oBAAoB,wBAAwB;;;;;AAMlD,MAAM,wBAAwB,MAAc,WAA2B;CACrE,IAAI,UAAU,GAAG,OAAO;CAExB,IAAI,mBAAmB;EACrB,MAAM,WAAW,CAAC,GAAG,kBAAkB,QAAQ,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC;EACrE,MAAM,OAAO,SAAS,SAAS,SAAS;EACxC,OAAO,OAAO,SAAS,KAAK,QAAQ,SAAS,SAAS;CACxD;CAGA,MAAM,OAAO,KAAK,WAAW,SAAS,CAAC;CACvC,IAAI,QAAQ,SAAU,QAAQ,SAAU,UAAU,GAChD,OAAO,SAAS;CAElB,OAAO,SAAS;AAClB;;;;AAKA,MAAM,wBAAwB,MAAc,WAA2B;CACrE,IAAI,UAAU,KAAK,QAAQ,OAAO,KAAK;CAEvC,IAAI,mBAAmB;EAErB,MAAM,QAAQ,CADI,GAAG,kBAAkB,QAAQ,KAAK,MAAM,MAAM,CAAC,CAC5C,EAAE;EACvB,OAAO,QAAQ,SAAS,MAAM,QAAQ,SAAS,SAAS;CAC1D;CAGA,MAAM,OAAO,KAAK,WAAW,MAAM;CACnC,IAAI,QAAQ,SAAU,QAAQ,SAAU,SAAS,IAAI,KAAK,QACxD,OAAO,SAAS;CAElB,OAAO,SAAS;AAClB;;;;AAKA,MAAM,oBAAoB,MAAc,WAA2B;CACjE,IAAI,UAAU,GAAG,OAAO;CACxB,IAAI,IAAI,SAAS;CAEjB,OAAO,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,GAAG;CAExC,OAAO,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE,GAAG;CACxC,OAAO;AACT;;;;AAKA,MAAM,oBAAoB,MAAc,WAA2B;CACjE,IAAI,UAAU,KAAK,QAAQ,OAAO,KAAK;CACvC,IAAI,IAAI;CAER,OAAO,IAAI,KAAK,UAAU,KAAK,KAAK,KAAK,EAAE,GAAG;CAE9C,OAAO,IAAI,KAAK,UAAU,KAAK,KAAK,KAAK,EAAE,GAAG;CAC9C,OAAO;AACT;;;;AAKA,MAAM,aAAa,MAAc,WAA2B;CAG1D,OAFe,KAAK,MAAM,GAAG,MACJ,EAAE,YAAY,IACtB,IAAI;AACvB;;;;AAKA,MAAM,WAAW,MAAc,WAA2B;CACxD,MAAM,cAAc,KAAK,QAAQ,MAAM,MAAM;CAC7C,OAAO,gBAAgB,KAAK,KAAK,SAAS;AAC5C;AAEA,MAAa,sBAAsB,EACjC,OACA,cACA,UACA,WAAW,YACoB;CAC/B,MAAM,eAAe,SAAS,gBAAgB;CAC9C,MAAM,CAAC,OAAO,YAAY,eAAyB,WAAW,YAAY,CAAC;CAC3E,MAAM,eAAe,OAA8B,IAAI;CACvD,MAAM,kBAAkB,OAA6B,IAAI;CACzD,MAAM,eAAe,UAAU;CAG/B,MAAM,WAAW,OAAO,KAAK;CAC7B,SAAS,UAAU;CAEnB,gBAAgB;EACd,IAAI,gBAAgB,UAAU,QAC5B,SAAS,WAAW,KAAK,CAAC;CAE9B,GAAG,CAAC,OAAO,YAAY,CAAC;CAExB,MAAM,gBAAgB,SAAS,QAAQ,KAAK,IAAI;CAEhD,MAAM,yBAA+C;EACnD,MAAM,MAAM,OAAO,aAAa;EAChC,IAAI,CAAC,KAAK,cAAc,CAAC,aAAa,SAAS,OAAO;EAEtD,MAAM,QAAQ,IAAI,WAAW,CAAC;EAC9B,MAAM,UAAU,aAAa,QAAQ,iBAAiB,aAAa;EAEnE,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,IAAI,QAAQ,GAAG,SAAS,MAAM,cAAc,GAC1C,OAAO;GAAE,MAAM;GAAG,QAAQ,MAAM;EAAY;EAGhD,OAAO;CACT;CAEA,MAAM,4BAIM;EACV,MAAM,MAAM,OAAO,aAAa;EAChC,IAAI,CAAC,KAAK,cAAc,CAAC,aAAa,SAAS,OAAO;EAEtD,MAAM,QAAQ,IAAI,WAAW,CAAC;EAC9B,MAAM,UAAU,aAAa,QAAQ,iBAAiB,aAAa;EACnE,MAAM,eAAe,SAAS;EAE9B,MAAM,cAAc,MAAY,eAA+B;GAC7D,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAClC,IAAI,QAAQ,GAAG,SAAS,IAAI,GAAG;IAC7B,IAAI,OAAO;IACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,QAAQ,aAAa,GAAG,SAAS;IAEnC,OAAO,OAAO,KAAK,IAAI,YAAY,aAAa,IAAI,UAAU,CAAC;GACjE;GAGF,IAAI,SAAS,aAAa,SAAS;IACjC,IAAI,eAAe,GAAG,OAAO;IAC7B,OAAO,aAAa,KAAK,IAAI,EAAE;GACjC;GACA,OAAO;EACT;EAEA,MAAM,QAAQ,WAAW,MAAM,gBAAgB,MAAM,WAAW;EAChE,MAAM,MAAM,WAAW,MAAM,cAAc,MAAM,SAAS;EAE1D,OAAO;GACL,OAAO,KAAK,IAAI,OAAO,GAAG;GAC1B,KAAK,KAAK,IAAI,OAAO,GAAG;GACxB,cAAc,CAAC,MAAM;EACvB;CACF;CAEA,MAAM,oBAAoB,QAAuB;EAC/C,IAAI,CAAC,aAAa,SAAS;EAG3B,MAAM,SADU,aAAa,QAAQ,iBAAiB,aACjC,EAAE,IAAI;EAC3B,IAAI,CAAC,QAAQ;EAEb,MAAM,WAAW,OAAO,cAAc,iBAAiB;EACvD,MAAM,OACJ,UAAU,cAAc,YAAY,OAAO,cAAc;EAE3D,MAAM,MAAM,OAAO,aAAa;EAChC,IAAI,CAAC,KAAK;EAEV,MAAM,QAAQ,SAAS,YAAY;EACnC,MAAM,SAAS,KAAK,IAAI,IAAI,QAAQ,KAAK,aAAa,UAAU,CAAC;EAEjE,IAAI;GACF,MAAM,SAAS,MAAM,MAAM;GAC3B,MAAM,SAAS,IAAI;GACnB,IAAI,gBAAgB;GACpB,IAAI,SAAS,KAAK;EACpB,QAAQ;GACN,MAAM,mBAAmB,IAAI;GAC7B,MAAM,SAAS,KAAK;GACpB,IAAI,gBAAgB;GACpB,IAAI,SAAS,KAAK;EACpB;CACF;CAEA,sBAAsB;EACpB,IAAI,gBAAgB,WAAW,aAAa,SAAS;GACnD,iBAAiB,gBAAgB,OAAO;GACxC,gBAAgB,UAAU;EAC5B;CACF,CAAC;CAED,MAAM,uBAAuB,QAA+B;EAC1D,MAAM,eAAe,SAAS;EAC9B,IAAI,SAAS;EACb,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,KAC5B,UAAU,aAAa,GAAG,SAAS;EAErC,OAAO,SAAS,IAAI;CACtB;CAEA,MAAM,uBACJ,MACA,gBACkB;EAClB,IAAI,MAAM;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;GAC3C,IAAI,OAAO,YAAY,GAAG,QACxB,OAAO;IAAE,MAAM;IAAG,QAAQ;GAAI;GAEhC,OAAO,YAAY,GAAG,SAAS;EACjC;EACA,OAAO;GACL,MAAM,YAAY,SAAS;GAC3B,QAAQ,YAAY,YAAY,SAAS,IAAI,UAAU;EACzD;CACF;CAEA,MAAM,wBAAgC;EACpC,MAAM,MAAM,iBAAiB;EAC7B,IAAI,CAAC,KAAK,OAAO;EACjB,OAAO,oBAAoB,GAAG;CAChC;;;;CAKA,MAAM,mBAAmB,SAAiB,gBAAwB;EAChE,MAAM,WAAW,WAAW,OAAO;EACnC,gBAAgB,UAAU,oBAAoB,aAAa,QAAQ;EACnE,SAAS,QAAQ;EACjB,WAAW,OAAO;CACpB;CAEA,MAAM,oBAAoB;EACxB,IAAI,gBAAgB,YAAY,MAAM;EACtC,IAAI,YAAY,CAAC,aAAa,SAAS;EAEvC,MAAM,WAAW,iBAAiB;EAClC,MAAM,UAAU,qBAAqB,aAAa,OAAO;EACzD,MAAM,WAAW,WAAW,OAAO;EAEnC,gBAAgB,UAAU;EAC1B,SAAS,QAAQ;EACjB,WAAW,OAAO;CACpB;CAEA,MAAM,iBAAiB,MAAqC;EAC1D,IAAI,UAAU;GACZ,EAAE,eAAe;GACjB;EACF;EAGA,IAAI,EAAE,YAAY,aAAa;EAG/B,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,KAAK;GAC7C,EAAE,eAAe;GACjB;EACF;EAEA,MAAM,UAAU,oBAAoB;EACpC,IAAI,CAAC,SAAS;EAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;EAE9C,IAAI,EAAE,QAAQ,SAAS;GACrB,EAAE,eAAe;GAKjB,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,OACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,CAAC;GAC1C;EACF;EAEA,IAAI,EAAE,QAAQ,aAAa;GACzB,EAAE,eAAe;GAEjB,IAAI,QAAQ,cAGV,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;QACjC;IACL,IAAI,QAAQ,UAAU,GAAG;IAEzB,IAAI;IACJ,IAAI,EAAE,SAEJ,aAAa,UAAU,aAAa,QAAQ,KAAK;SAC5C,IAAI,EAAE,QAEX,aAAa,iBAAiB,aAAa,QAAQ,KAAK;SAGxD,aAAa,qBAAqB,aAAa,QAAQ,KAAK;IAK9D,gBADE,YAAY,MAAM,GAAG,UAAU,IAAI,YAAY,MAAM,QAAQ,KAAK,GAC3C,UAAU;GACrC;GACA;EACF;EAEA,IAAI,EAAE,QAAQ,UAAU;GACtB,EAAE,eAAe;GAEjB,IAAI,QAAQ,cAGV,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;QACjC;IACL,IAAI,QAAQ,SAAS,YAAY,QAAQ;IAEzC,IAAI;IACJ,IAAI,EAAE,SAEJ,WAAW,QAAQ,aAAa,QAAQ,KAAK;SACxC,IAAI,EAAE,QAEX,WAAW,iBAAiB,aAAa,QAAQ,KAAK;SAGtD,WAAW,qBAAqB,aAAa,QAAQ,KAAK;IAK5D,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GACzC,QAAQ,KAAK;GACxC;GACA;EACF;CACF;CAEA,MAAM,aAAa,MAAsC;EACvD,IAAI,UAAU;GACZ,EAAE,eAAe;GACjB;EACF;EAEA,EAAE,eAAe;EACjB,MAAM,UAAU,oBAAoB;EACpC,IAAI,CAAC,SAAS,cAAc;EAE5B,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;EAC9C,MAAM,eAAe,YAAY,MAAM,QAAQ,OAAO,QAAQ,GAAG;EAGjE,EAAE,cAAc,QAAQ,cAAc,YAAY;EAKlD,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;CACxC;CAEA,MAAM,eAAe,MAAsC;EACzD,IAAI,UAAU;GACZ,EAAE,eAAe;GACjB;EACF;EAEA,EAAE,eAAe;EACjB,MAAM,aAAa,EAAE,cAAc,QAAQ,YAAY;EACvD,IAAI,CAAC,YAAY;EAEjB,MAAM,UAAU,oBAAoB;EACpC,IAAI,CAAC,SAAS;EAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;EAK9C,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,aACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,WAAW,MAAM;CAC5D;CAEA,MAAM,qBAAqB,MAAkC;EAC3D,IAAI,UAAU;EAEd,MAAM,aAAa,EAAE;EAGrB,IAAI,WAAW,aAAa;EAE5B,MAAM,YAAY,WAAW;EAG7B,IAAI,cAAc,qBAAqB,cAAc,mBACnD;EAIF,IACE,cAAc,2BACd,cAAc,wBACd;GACA,EAAE,eAAe;GACjB,MAAM,UAAU,oBAAoB;GACpC,IAAI,CAAC,SAAS;GAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;GAE9C,IAAI,QAAQ,cAGV,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GAAG,GAC5C,QAAQ,KAAK;QACjC,IAAI,cAAc,yBAAyB;IAChD,IAAI,QAAQ,UAAU,GAAG;IACzB,MAAM,aAAa,qBAAqB,aAAa,QAAQ,KAAK;IAGlE,gBADE,YAAY,MAAM,GAAG,UAAU,IAAI,YAAY,MAAM,QAAQ,KAAK,GAC3C,UAAU;GACrC,OAAO;IACL,IAAI,QAAQ,SAAS,YAAY,QAAQ;IACzC,MAAM,WAAW,qBAAqB,aAAa,QAAQ,KAAK;IAGhE,gBADE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAAI,YAAY,MAAM,QAAQ,GACzC,QAAQ,KAAK;GACxC;GACA;EACF;EAGA,IAAI,cAAc,yBAAyB;GACzC,EAAE,eAAe;GACjB,MAAM,UAAU,oBAAoB;GACpC,IAAI,CAAC,SAAS;GAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;GAC9C,MAAM,cACJ,WAAW,QAAQ,WAAW,cAAc,QAAQ,YAAY,KAAK;GAKvE,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,cACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,YAAY,MAAM;GAC3D;EACF;EAEA,IAAI,cAAc,gBAAgB,WAAW,MAAM;GACjD,EAAE,eAAe;GAEjB,MAAM,UAAU,oBAAoB;GACpC,IAAI,CAAC,SAAS;GAEd,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI;GAC9C,MAAM,WAAW,WAAW;GAK5B,gBAHE,YAAY,MAAM,GAAG,QAAQ,KAAK,IAClC,WACA,YAAY,MAAM,QAAQ,GAAG,GACN,QAAQ,QAAQ,SAAS,MAAM;EAC1D;CACF;CAEA,MAAM,cAAc,MAAiC;EAEnD,EAAE,eAAe;CACnB;CAEA,MAAM,kBAAkB,MAAiC;EACvD,EAAE,eAAe;CACnB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AASA,MAAM,QAAuB,EAAE,OAAO,MAAM,QAAQ,gBAClD,qBAAC,QAAD;CAAM,aAAW;CAAO,WAAU;WAAlC;EACE,oBAAC,QAAD;GAAM;aAAe,QAAQ;EAAe;EAC3C,aACC,oBAAC,QAAD;GACE;GACA,WAAU;GACV,eAAY;aAEX;EACG;EAEP,CAAC,UAAU,oBAAC,MAAD,CAAK;CACb;;AAmCR,MAAM,cAAc;AACpB,MAAM,eAAe;AAErB,MAAa,2BAA6D,EACxE,OACA,cACA,UACA,aACA,WAAW,OACX,UAAU,GACV,UAAU,KACV,WAAW,MACX,yBAAyB,OACzB,SACA,WACA,WACA,aACA,SACA,WACA,MAAM,QACN,KACA,GAAG,WACC;CACJ,MAAM,EACJ,OACA,cACA,SACA,aACA,mBACA,eACA,WACA,aACA,YACA,gBACA,iBACA,kBACA,wBACE,mBAAmB;EAAE;EAAO;EAAc;EAAU;CAAS,CAAC;CAElE,MAAM,QAAQ,OAA8B,IAAI;CAEhD,MAAM,UAAU,OAA8B;EAC5C,MAAM,UAAU;EAChB,AAAC,aAAkD,UAAU;CAC/D;CAEA,oBAAoB,YAAY;EAC9B,oBAAoB,MAAM;EAC1B;EACA,aAAa,MAAM,SAAS,MAAM;EAClC;EACA,oBAAoB,WAAmB;GACrC,iBAAiB,oBAAoB,QAAQ,KAAK,CAAC;EACrD;CACF,EAAE;CAEF,sBAAsB;EACpB,IAAI,CAAC,YAAY,CAAC,MAAM,SAAS;EAEjC,MAAM,KAAK,MAAM;EACjB,MAAM,MAAM,cAAc,UAAU;EACpC,MAAM,MAAM,cAAc,UAAU;EAEpC,GAAG,MAAM,SAAS;EAClB,MAAM,KAAK,GAAG;EACd,GAAG,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,GAAG,EAAE;EACtD,GAAG,MAAM,YAAY,KAAK,MAAM,SAAS;CAC3C,GAAG;EAAC;EAAO;EAAU;EAAS;CAAO,CAAC;CAEtC,MAAM,UAAU,MAAM,WAAW,KAAK,MAAM,OAAO;CACnD,MAAM,WACJ,aAAa,cAAc,UAAa,gBAAgB;CAE1D,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,WAAW,eACV,oBAAC,OAAD;GACE,WAAU;GACV,eAAY;aAEX;EACE,IAGP,oBAAC,OAAD;GACE,GAAI;GACJ,KAAK;GACL,MAAK;GACL,kBAAe;GACf,oBAAkB;GAClB,iBAAe;GACf,qBAAmB,WAAW,WAAW;GACzC,UAAU,WAAW,KAAK;GAC1B,iBAAiB,CAAC;GAClB;GACK;GACL,SAAS;GACT,eAAe;GACf,WAAW;GACX,OAAO;GACP,SAAS;GACT,QAAQ;GACR,YAAY;GACH;GACT,WAAW,GACT,4DACA,cAAc;IACZ;IACA,wBAAwB,yBACpB,YACA;GACN,CAAC,GACD,YAAY,mBACZ,SACF;aAEC,MAAM,KAAK,MAAM,MAChB,oBAAC,MAAD;IAEE,OAAO;IACD;IACN,QAAQ,MAAM,MAAM,SAAS;IAC7B,WAAW,YAAY,cAAc,IAAI,YAAY;GACtD,GALM,CAKN,CACF;EACE,EACF;;AAET"}
@@ -38,10 +38,10 @@ import { jsx } from "react/jsx-runtime";
38
38
  * <TextArea
39
39
  * value={content}
40
40
  * onChange={(e) => setContent(e.target.value)}
41
- * variant={hasError ? InputVariant.ERROR : InputVariant.SUCCESS}
41
+ * variant={hasError ? 'error' : 'success'}
42
42
  * validationStyleEnabled={true}
43
43
  * placeholder="Minimum 10 characters required"
44
- * className="min-h-[100px]"
44
+ * className="min-top-25"
45
45
  * />
46
46
  * ```
47
47
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/TextArea.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { VariantProps } from 'class-variance-authority';\nimport type { DetailedHTMLProps, FC, TextareaHTMLAttributes } from 'react';\nimport { type InputVariant, inputVariants } from '../Input';\n\n/**\n * Props for the TextArea component.\n *\n * Extends standard HTML textarea attributes with additional design system variants\n * and validation styling options.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <TextArea placeholder=\"Enter your message...\" />\n *\n * // With error validation styling\n * <TextArea\n * value={message}\n * onChange={handleChange}\n * variant={InputVariant.ERROR}\n * validationStyleEnabled={true}\n * placeholder=\"Message is required\"\n * />\n *\n * // Large multiline input\n * <TextArea\n * rows={6}\n * cols={50}\n * variant={InputVariant.DEFAULT}\n * className=\"min-h-[120px]\"\n * placeholder=\"Write a detailed description...\"\n * />\n * ```\n */\nexport type TextAreaProps = DetailedHTMLProps<\n DetailedHTMLProps<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n HTMLTextAreaElement\n >,\n HTMLTextAreaElement\n> & {\n /** Enable validation styling based on the variant prop */\n validationStyleEnabled?: boolean;\n} & Omit<\n VariantProps<typeof inputVariants>,\n 'validationStyleEnabled' | 'variant'\n > & {\n /** Visual variant of the textarea (default, success, error, warning, etc.) */\n variant?: InputVariant | `${InputVariant}`;\n };\n\n/**\n * TextArea Component\n *\n * A flexible textarea component that extends the standard HTML textarea with\n * design system styling variants, validation states, and consistent visual appearance.\n *\n * ## Features\n * - **Variant Support**: Multiple visual states (default, error, success, warning)\n * - **Validation Styling**: Optional validation feedback styling\n * - **Resize Control**: Disabled by default for consistent layout\n * - **Design System Integration**: Uses shared input variants for consistency\n * - **Accessibility**: Maintains all standard textarea accessibility features\n *\n * ## Use Cases\n * - Multi-line text input forms\n * - Comment and message composition\n * - Description and content fields\n * - Feedback and review forms\n * - Code snippet input (when combined with monospace styling)\n *\n * @example\n * ```tsx\n * // Basic textarea\n * <TextArea\n * placeholder=\"Enter your thoughts...\"\n * rows={4}\n * />\n *\n * // Controlled with validation\n * const [content, setContent] = useState('');\n * const hasError = content.length < 10;\n *\n * <TextArea\n * value={content}\n * onChange={(e) => setContent(e.target.value)}\n * variant={hasError ? InputVariant.ERROR : InputVariant.SUCCESS}\n * validationStyleEnabled={true}\n * placeholder=\"Minimum 10 characters required\"\n * className=\"min-h-[100px]\"\n * />\n * ```\n */\nexport const TextArea: FC<TextAreaProps> = ({\n className,\n variant,\n validationStyleEnabled = false,\n ...props\n}) => (\n <textarea\n className={cn(\n 'resize-none',\n inputVariants({\n variant,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n className,\n })\n )}\n {...props}\n />\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8FA,MAAa,YAA+B,EAC1C,WACA,SACA,yBAAyB,OACzB,GAAG,YAEH,oBAAC,YAAD;CACE,WAAW,GACT,eACA,cAAc;EACZ;EACA,wBAAwB,yBAAyB,YAAY;EAC7D;CACF,CAAC,CACH;CACA,GAAI;AACL"}
1
+ {"version":3,"file":"TextArea.mjs","names":[],"sources":["../../../../src/components/TextArea/TextArea.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { VariantProps } from 'class-variance-authority';\nimport type { DetailedHTMLProps, FC, TextareaHTMLAttributes } from 'react';\nimport { inputVariants } from '../Input';\n\n/**\n * Props for the TextArea component.\n *\n * Extends standard HTML textarea attributes with additional design system variants\n * and validation styling options.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <TextArea placeholder=\"Enter your message...\" />\n *\n * // With error validation styling\n * <TextArea\n * value={message}\n * onChange={handleChange}\n * variant=\"error\"\n * validationStyleEnabled={true}\n * placeholder=\"Message is required\"\n * />\n *\n * // Large multiline input\n * <TextArea\n * rows={6}\n * cols={50}\n * variant=\"default\"\n * className=\"min-h-[120px]\"\n * placeholder=\"Write a detailed description...\"\n * />\n * ```\n */\nexport type TextAreaProps = DetailedHTMLProps<\n DetailedHTMLProps<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n HTMLTextAreaElement\n >,\n HTMLTextAreaElement\n> & {\n /** Enable validation styling based on the variant prop */\n validationStyleEnabled?: boolean;\n} & Omit<\n VariantProps<typeof inputVariants>,\n 'validationStyleEnabled' | 'variant'\n > & {\n /** Visual variant of the textarea (default, success, error, warning, etc.) */\n variant?: InputVariant;\n };\n\n/**\n * TextArea Component\n *\n * A flexible textarea component that extends the standard HTML textarea with\n * design system styling variants, validation states, and consistent visual appearance.\n *\n * ## Features\n * - **Variant Support**: Multiple visual states (default, error, success, warning)\n * - **Validation Styling**: Optional validation feedback styling\n * - **Resize Control**: Disabled by default for consistent layout\n * - **Design System Integration**: Uses shared input variants for consistency\n * - **Accessibility**: Maintains all standard textarea accessibility features\n *\n * ## Use Cases\n * - Multi-line text input forms\n * - Comment and message composition\n * - Description and content fields\n * - Feedback and review forms\n * - Code snippet input (when combined with monospace styling)\n *\n * @example\n * ```tsx\n * // Basic textarea\n * <TextArea\n * placeholder=\"Enter your thoughts...\"\n * rows={4}\n * />\n *\n * // Controlled with validation\n * const [content, setContent] = useState('');\n * const hasError = content.length < 10;\n *\n * <TextArea\n * value={content}\n * onChange={(e) => setContent(e.target.value)}\n * variant={hasError ? 'error' : 'success'}\n * validationStyleEnabled={true}\n * placeholder=\"Minimum 10 characters required\"\n * className=\"min-top-25\"\n * />\n * ```\n */\nexport const TextArea: FC<TextAreaProps> = ({\n className,\n variant,\n validationStyleEnabled = false,\n ...props\n}) => (\n <textarea\n className={cn(\n 'resize-none',\n inputVariants({\n variant,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n className,\n })\n )}\n {...props}\n />\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8FA,MAAa,YAA+B,EAC1C,WACA,SACA,yBAAyB,OACzB,GAAG,YAEH,oBAAC,YAAD;CACE,WAAW,GACT,eACA,cAAc;EACZ;EACA,wBAAwB,yBAAyB,YAAY;EAC7D;CACF,CAAC,CACH;CACA,GAAI;AACL"}
@@ -1,6 +1,6 @@
1
- import { ContentEditableTextArea, useContentEditable } from "./ContentEditableTextArea.mjs";
2
- import { AutoCompleteTextarea } from "./AutocompleteTextArea.mjs";
3
1
  import { TextArea } from "./TextArea.mjs";
4
2
  import { AutoSizedTextArea } from "./AutoSizeTextArea.mjs";
3
+ import { ContentEditableTextArea, useContentEditable } from "./ContentEditableTextArea.mjs";
4
+ import { AutoCompleteTextarea } from "./AutocompleteTextArea.mjs";
5
5
 
6
6
  export { AutoCompleteTextarea, AutoSizedTextArea, ContentEditableTextArea, TextArea, useContentEditable };
@@ -1,9 +1,8 @@
1
1
  'use client';
2
2
 
3
+ import { Button } from "../Button/Button.mjs";
3
4
  import { Container } from "../Container/index.mjs";
4
- import { Button, ButtonVariant } from "../Button/Button.mjs";
5
5
  import { DropDown } from "../DropDown/index.mjs";
6
- import { Modes } from "./types.mjs";
7
6
  import { useState } from "react";
8
7
  import { CircleDashed, Moon, Sun } from "lucide-react";
9
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"DesktopThemeSwitcher.mjs","names":[],"sources":["../../../../src/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.tsx"],"sourcesContent":["'use client';\n\nimport { CircleDashed, Moon, Sun } from 'lucide-react';\nimport { type FC, useState } from 'react';\nimport { Button, type ButtonProps, ButtonVariant } from '../Button';\nimport { Container } from '../Container';\nimport { DropDown } from '../DropDown';\nimport { Modes } from './types';\n\nconst ButtonItem: FC<ButtonProps> = ({ Icon, children, ...props }) => (\n <div className=\"relative w-full p-0.5\">\n <Button\n className=\"w-full cursor-pointer rounded-lg p-1 text-left hover:bg-text/10 focus:bg-text-opposite/20 focus:outline-hidden disabled:text-white/25\"\n Icon={Icon}\n data-mode=\"system\"\n role=\"option\"\n variant={ButtonVariant.NONE}\n {...props}\n >\n {children}\n </Button>\n </div>\n);\n\ntype DesktopThemeSwitcherProps = {\n theme: Modes;\n setTheme: (theme: Modes) => void;\n systemTheme: Modes;\n};\n\nexport const DesktopThemeSwitcher: FC<DesktopThemeSwitcherProps> = ({\n theme,\n setTheme,\n systemTheme,\n}) => {\n const isThemeSystemTheme = systemTheme === theme;\n const defaultMode = isThemeSystemTheme ? Modes.system : theme;\n\n const [mode, setMode] = useState<Modes>(defaultMode);\n\n const switchMode = (mode: Modes) => {\n if (mode === Modes.system) {\n setTheme(systemTheme ?? Modes.light);\n } else {\n setTheme(mode);\n }\n setMode(mode);\n };\n\n const panelIdentifier = 'theme-switcher';\n\n return (\n <DropDown identifier={panelIdentifier}>\n <DropDown.Trigger\n className=\"p-2\"\n identifier={panelIdentifier}\n aria-label=\"Theme selector\"\n >\n {mode === Modes.system && <CircleDashed data-mode=\"system\" />}\n {mode === Modes.light && <Sun data-mode=\"light\" />}\n {mode === Modes.dark && <Moon data-mode=\"dark\" />}\n </DropDown.Trigger>\n\n <DropDown.Panel identifier={panelIdentifier} isFocusable isOverable>\n <Container className=\"min-w-[100px] items-start p-1\" separator=\"y\">\n <ButtonItem\n Icon={CircleDashed}\n onClick={() => switchMode(Modes.system)}\n isActive={mode === Modes.system}\n label=\"Restore to system mode\"\n >\n System\n </ButtonItem>\n <ButtonItem\n Icon={Sun}\n onClick={() => switchMode(Modes.light)}\n isActive={mode === Modes.light}\n label=\"Switch to light mode\"\n >\n Light\n </ButtonItem>\n <ButtonItem\n Icon={Moon}\n onClick={() => switchMode(Modes.dark)}\n isActive={mode === Modes.dark}\n label=\"Switch to dark mode\"\n >\n Dark\n </ButtonItem>\n </Container>\n </DropDown.Panel>\n </DropDown>\n );\n};\n"],"mappings":";;;;;;;;;;;AASA,MAAM,cAA+B,EAAE,MAAM,UAAU,GAAG,YACxD,oBAAC,OAAD;CAAK,WAAU;WACb,oBAAC,QAAD;EACE,WAAU;EACJ;EACN,aAAU;EACV,MAAK;EACL;EACA,GAAI;EAEH;CACK;AACL;AASP,MAAa,wBAAuD,EAClE,OACA,UACA,kBACI;CAIJ,MAAM,CAAC,MAAM,WAAW,SAHG,gBAAgB,mBACa,KAEL;CAEnD,MAAM,cAAc,SAAgB;EAClC,IAAI,mBACF,SAAS,sBAA0B;OAEnC,SAAS,IAAI;EAEf,QAAQ,IAAI;CACd;CAEA,MAAM,kBAAkB;CAExB,OACE,qBAAC,UAAD;EAAU,YAAY;YAAtB,CACE,qBAAC,SAAS,SAAV;GACE,WAAU;GACV,YAAY;GACZ,cAAW;aAHb;IAKG,qBAAyB,oBAAC,cAAD,EAAc,aAAU,SAAU;IAC3D,oBAAwB,oBAAC,KAAD,EAAK,aAAU,QAAS;IAChD,mBAAuB,oBAAC,MAAD,EAAM,aAAU,OAAQ;GAChC;MAElB,oBAAC,SAAS,OAAV;GAAgB,YAAY;GAAiB;GAAY;aACvD,qBAAC,WAAD;IAAW,WAAU;IAAgC,WAAU;cAA/D;KACE,oBAAC,YAAD;MACE,MAAM;MACN,eAAe,mBAAuB;MACtC,UAAU;MACV,OAAM;gBACP;KAEW;KACZ,oBAAC,YAAD;MACE,MAAM;MACN,eAAe,kBAAsB;MACrC,UAAU;MACV,OAAM;gBACP;KAEW;KACZ,oBAAC,YAAD;MACE,MAAM;MACN,eAAe,iBAAqB;MACpC,UAAU;MACV,OAAM;gBACP;KAEW;IACH;;EACG,EACR;;AAEd"}
1
+ {"version":3,"file":"DesktopThemeSwitcher.mjs","names":[],"sources":["../../../../src/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.tsx"],"sourcesContent":["'use client';\n\nimport { CircleDashed, Moon, Sun } from 'lucide-react';\nimport { type FC, useState } from 'react';\nimport { Button, type ButtonProps } from '../Button';\nimport { Container } from '../Container';\nimport { DropDown } from '../DropDown';\nimport type { Modes } from './types';\n\nconst ButtonItem: FC<ButtonProps> = ({ Icon, children, ...props }) => (\n <div className=\"relative w-full p-0.5\">\n <Button\n className=\"w-full cursor-pointer rounded-lg p-1 text-left hover:bg-text/10 focus:bg-text-opposite/20 focus:outline-hidden disabled:text-white/25\"\n Icon={Icon}\n data-mode=\"system\"\n role=\"option\"\n variant=\"none\"\n {...props}\n >\n {children}\n </Button>\n </div>\n);\n\ntype DesktopThemeSwitcherProps = {\n theme: Modes;\n setTheme: (theme: Modes) => void;\n systemTheme: Modes;\n};\n\nexport const DesktopThemeSwitcher: FC<DesktopThemeSwitcherProps> = ({\n theme,\n setTheme,\n systemTheme,\n}) => {\n const isThemeSystemTheme = systemTheme === theme;\n const defaultMode = isThemeSystemTheme ? 'system' : theme;\n\n const [mode, setMode] = useState<Modes>(defaultMode);\n\n const switchMode = (mode: Modes) => {\n if (mode === 'system') {\n setTheme(systemTheme ?? 'light');\n } else {\n setTheme(mode);\n }\n setMode(mode);\n };\n\n const panelIdentifier = 'theme-switcher';\n\n return (\n <DropDown identifier={panelIdentifier}>\n <DropDown.Trigger\n className=\"p-2\"\n identifier={panelIdentifier}\n aria-label=\"Theme selector\"\n >\n {mode === 'system' && <CircleDashed data-mode=\"system\" />}\n {mode === 'light' && <Sun data-mode=\"light\" />}\n {mode === 'dark' && <Moon data-mode=\"dark\" />}\n </DropDown.Trigger>\n\n <DropDown.Panel identifier={panelIdentifier} isFocusable isOverable>\n <Container className=\"min-w-[100px] items-start p-1\" separator=\"y\">\n <ButtonItem\n Icon={CircleDashed}\n onClick={() => switchMode('system')}\n isActive={mode === 'system'}\n label=\"Restore to system mode\"\n >\n System\n </ButtonItem>\n <ButtonItem\n Icon={Sun}\n onClick={() => switchMode('light')}\n isActive={mode === 'light'}\n label=\"Switch to light mode\"\n >\n Light\n </ButtonItem>\n <ButtonItem\n Icon={Moon}\n onClick={() => switchMode('dark')}\n isActive={mode === 'dark'}\n label=\"Switch to dark mode\"\n >\n Dark\n </ButtonItem>\n </Container>\n </DropDown.Panel>\n </DropDown>\n );\n};\n"],"mappings":";;;;;;;;;;AASA,MAAM,cAA+B,EAAE,MAAM,UAAU,GAAG,YACxD,oBAAC,OAAD;CAAK,WAAU;WACb,oBAAC,QAAD;EACE,WAAU;EACJ;EACN,aAAU;EACV,MAAK;EACL,SAAQ;EACR,GAAI;EAEH;CACK;AACL;AASP,MAAa,wBAAuD,EAClE,OACA,UACA,kBACI;CAIJ,MAAM,CAAC,MAAM,WAAW,SAHG,gBAAgB,QACF,WAAW,KAED;CAEnD,MAAM,cAAc,SAAgB;EAClC,IAAI,SAAS,UACX,SAAS,eAAe,OAAO;OAE/B,SAAS,IAAI;EAEf,QAAQ,IAAI;CACd;CAEA,MAAM,kBAAkB;CAExB,OACE,qBAAC,UAAD;EAAU,YAAY;YAAtB,CACE,qBAAC,SAAS,SAAV;GACE,WAAU;GACV,YAAY;GACZ,cAAW;aAHb;IAKG,SAAS,YAAY,oBAAC,cAAD,EAAc,aAAU,SAAU;IACvD,SAAS,WAAW,oBAAC,KAAD,EAAK,aAAU,QAAS;IAC5C,SAAS,UAAU,oBAAC,MAAD,EAAM,aAAU,OAAQ;GAC5B;MAElB,oBAAC,SAAS,OAAV;GAAgB,YAAY;GAAiB;GAAY;aACvD,qBAAC,WAAD;IAAW,WAAU;IAAgC,WAAU;cAA/D;KACE,oBAAC,YAAD;MACE,MAAM;MACN,eAAe,WAAW,QAAQ;MAClC,UAAU,SAAS;MACnB,OAAM;gBACP;KAEW;KACZ,oBAAC,YAAD;MACE,MAAM;MACN,eAAe,WAAW,OAAO;MACjC,UAAU,SAAS;MACnB,OAAM;gBACP;KAEW;KACZ,oBAAC,YAAD;MACE,MAAM;MACN,eAAe,WAAW,MAAM;MAChC,UAAU,SAAS;MACnB,OAAM;gBACP;KAEW;IACH;;EACG,EACR;;AAEd"}
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import { cn } from "../../utils/cn.mjs";
4
- import { Modes } from "./types.mjs";
5
4
  import { useState } from "react";
6
5
  import { CircleDashed, Moon, Sun } from "lucide-react";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"MobileThemeSwitcher.mjs","names":[],"sources":["../../../../src/components/ThemeSwitcherDropDown/MobileThemeSwitcher.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { CircleDashed, Moon, Sun } from 'lucide-react';\nimport { type FC, useState } from 'react';\nimport { Modes } from './types';\n\ntype MobileThemeSwitcherProps = {\n theme: Modes;\n systemTheme: Modes;\n setTheme: (theme: Modes) => void;\n};\n\nconst getIconStyle = ({\n isCurrentMode,\n isNextMode,\n}: {\n isCurrentMode: boolean;\n isNextMode: boolean;\n}) =>\n cn(\n `absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2`,\n `opacity-0 transition-opacity duration-300 ease-in-out`,\n isCurrentMode && `opacity-100 group-hover:opacity-0`,\n isNextMode && `group-hover:opacity-100`\n );\n\nexport const MobileThemeSwitcher: FC<MobileThemeSwitcherProps> = ({\n theme,\n systemTheme,\n setTheme,\n}) => {\n const isThemeSystemTheme = systemTheme === theme;\n const defaultMode = isThemeSystemTheme ? Modes.system : theme;\n\n const [mode, setMode] = useState<Modes>(defaultMode);\n\n const nextMode =\n // Start loop\n // If mode is system, toggle the theme inverse of the system theme\n mode === Modes.system\n ? theme === Modes.dark\n ? Modes.light\n : Modes.dark\n : // Close loop\n // If current theme same as system theme, reset by toggle the system theme\n isThemeSystemTheme\n ? Modes.system\n : // Go to next step\n // Otherwise, toggle the remaining theme\n mode === Modes.light\n ? Modes.dark\n : Modes.light;\n\n const toggleMode = () => {\n if (nextMode === Modes.system) {\n setTheme(systemTheme ?? Modes.light);\n } else {\n setTheme(nextMode);\n }\n setMode(nextMode);\n };\n\n return (\n <button className=\"group relative size-10\" aria-label=\"Theme selector\">\n <CircleDashed\n className={getIconStyle({\n isCurrentMode: mode === Modes.system,\n isNextMode: nextMode === Modes.system,\n })}\n onClick={toggleMode}\n data-mode=\"system\"\n />\n\n <Moon\n className={getIconStyle({\n isCurrentMode: mode === Modes.light,\n isNextMode: nextMode === Modes.light,\n })}\n onClick={toggleMode}\n data-mode=\"light\"\n />\n\n <Sun\n className={getIconStyle({\n isCurrentMode: mode === Modes.dark,\n isNextMode: nextMode === Modes.dark,\n })}\n onClick={toggleMode}\n data-mode=\"dark\"\n />\n </button>\n );\n};\n"],"mappings":";;;;;;;;;AAaA,MAAM,gBAAgB,EACpB,eACA,iBAKA,GACE,+DACA,yDACA,iBAAiB,qCACjB,cAAc,yBAChB;AAEF,MAAa,uBAAqD,EAChE,OACA,aACA,eACI;CACJ,MAAM,qBAAqB,gBAAgB;CAG3C,MAAM,CAAC,MAAM,WAAW,SAFJ,gCAAoC,KAEL;CAEnD,MAAM,WAGJ,oBACI,sCAKA,gCAIE;CAIR,MAAM,mBAAmB;EACvB,IAAI,uBACF,SAAS,sBAA0B;OAEnC,SAAS,QAAQ;EAEnB,QAAQ,QAAQ;CAClB;CAEA,OACE,qBAAC,UAAD;EAAQ,WAAU;EAAyB,cAAW;YAAtD;GACE,oBAAC,cAAD;IACE,WAAW,aAAa;KACtB,eAAe;KACf,YAAY;IACd,CAAC;IACD,SAAS;IACT,aAAU;GACX;GAED,oBAAC,MAAD;IACE,WAAW,aAAa;KACtB,eAAe;KACf,YAAY;IACd,CAAC;IACD,SAAS;IACT,aAAU;GACX;GAED,oBAAC,KAAD;IACE,WAAW,aAAa;KACtB,eAAe;KACf,YAAY;IACd,CAAC;IACD,SAAS;IACT,aAAU;GACX;EACK;;AAEZ"}
1
+ {"version":3,"file":"MobileThemeSwitcher.mjs","names":[],"sources":["../../../../src/components/ThemeSwitcherDropDown/MobileThemeSwitcher.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { CircleDashed, Moon, Sun } from 'lucide-react';\nimport { type FC, useState } from 'react';\nimport type { Modes } from './types';\n\ntype MobileThemeSwitcherProps = {\n theme: Modes;\n systemTheme: Modes;\n setTheme: (theme: Modes) => void;\n};\n\nconst getIconStyle = ({\n isCurrentMode,\n isNextMode,\n}: {\n isCurrentMode: boolean;\n isNextMode: boolean;\n}) =>\n cn(\n `absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2`,\n `opacity-0 transition-opacity duration-300 ease-in-out`,\n isCurrentMode && `opacity-100 group-hover:opacity-0`,\n isNextMode && `group-hover:opacity-100`\n );\n\nexport const MobileThemeSwitcher: FC<MobileThemeSwitcherProps> = ({\n theme,\n systemTheme,\n setTheme,\n}) => {\n const isThemeSystemTheme = systemTheme === theme;\n const defaultMode = isThemeSystemTheme ? 'system' : theme;\n\n const [mode, setMode] = useState<Modes>(defaultMode);\n\n const nextMode =\n // Start loop\n // If mode is system, toggle the theme inverse of the system theme\n mode === 'system'\n ? theme === 'dark'\n ? 'light'\n : 'dark'\n : // Close loop\n // If current theme same as system theme, reset by toggle the system theme\n isThemeSystemTheme\n ? 'system'\n : // Go to next step\n // Otherwise, toggle the remaining theme\n mode === 'light'\n ? 'dark'\n : 'light';\n\n const toggleMode = () => {\n if (nextMode === 'system') {\n setTheme(systemTheme ?? 'light');\n } else {\n setTheme(nextMode);\n }\n setMode(nextMode);\n };\n\n return (\n <button className=\"group relative size-10\" aria-label=\"Theme selector\">\n <CircleDashed\n className={getIconStyle({\n isCurrentMode: mode === 'system',\n isNextMode: nextMode === 'system',\n })}\n onClick={toggleMode}\n data-mode=\"system\"\n />\n\n <Moon\n className={getIconStyle({\n isCurrentMode: mode === 'light',\n isNextMode: nextMode === 'light',\n })}\n onClick={toggleMode}\n data-mode=\"light\"\n />\n\n <Sun\n className={getIconStyle({\n isCurrentMode: mode === 'dark',\n isNextMode: nextMode === 'dark',\n })}\n onClick={toggleMode}\n data-mode=\"dark\"\n />\n </button>\n );\n};\n"],"mappings":";;;;;;;;AAaA,MAAM,gBAAgB,EACpB,eACA,iBAKA,GACE,+DACA,yDACA,iBAAiB,qCACjB,cAAc,yBAChB;AAEF,MAAa,uBAAqD,EAChE,OACA,aACA,eACI;CACJ,MAAM,qBAAqB,gBAAgB;CAG3C,MAAM,CAAC,MAAM,WAAW,SAFJ,qBAAqB,WAAW,KAED;CAEnD,MAAM,WAGJ,SAAS,WACL,UAAU,SACR,UACA,SAGF,qBACE,WAGA,SAAS,UACP,SACA;CAEV,MAAM,mBAAmB;EACvB,IAAI,aAAa,UACf,SAAS,eAAe,OAAO;OAE/B,SAAS,QAAQ;EAEnB,QAAQ,QAAQ;CAClB;CAEA,OACE,qBAAC,UAAD;EAAQ,WAAU;EAAyB,cAAW;YAAtD;GACE,oBAAC,cAAD;IACE,WAAW,aAAa;KACtB,eAAe,SAAS;KACxB,YAAY,aAAa;IAC3B,CAAC;IACD,SAAS;IACT,aAAU;GACX;GAED,oBAAC,MAAD;IACE,WAAW,aAAa;KACtB,eAAe,SAAS;KACxB,YAAY,aAAa;IAC3B,CAAC;IACD,SAAS;IACT,aAAU;GACX;GAED,oBAAC,KAAD;IACE,WAAW,aAAa;KACtB,eAAe,SAAS;KACxB,YAAY,aAAa;IAC3B,CAAC;IACD,SAAS;IACT,aAAU;GACX;EACK;;AAEZ"}
@@ -1,5 +1,4 @@
1
- import { Modes } from "./types.mjs";
2
1
  import { DesktopThemeSwitcher } from "./DesktopThemeSwitcher.mjs";
3
2
  import { MobileThemeSwitcher } from "./MobileThemeSwitcher.mjs";
4
3
 
5
- export { DesktopThemeSwitcher, MobileThemeSwitcher, Modes };
4
+ export { DesktopThemeSwitcher, MobileThemeSwitcher };
@@ -1,11 +0,0 @@
1
- //#region src/components/ThemeSwitcherDropDown/types.ts
2
- let Modes = /* @__PURE__ */ function(Modes) {
3
- Modes["dark"] = "dark";
4
- Modes["light"] = "light";
5
- Modes["system"] = "system";
6
- return Modes;
7
- }({});
8
-
9
- //#endregion
10
- export { Modes };
11
- //# sourceMappingURL=types.mjs.map
@@ -1,58 +1,61 @@
1
1
  import { Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, toastVariants } from "./Toaster/Toast.mjs";
2
2
  import { reducer, toast, useToast } from "./Toaster/useToast.mjs";
3
3
  import { Toaster } from "./Toaster/Toaster.mjs";
4
- import { Container, ContainerBackground, ContainerBorderColor, ContainerGap, ContainerPadding, ContainerRoundedSize, ContainerSeparator, ContainerTransparency, containerVariants } from "./Container/index.mjs";
5
4
  import { Loader } from "./Loader/index.mjs";
6
- import { Button, ButtonColor, ButtonSize, ButtonTextAlign, ButtonVariant, buttonVariants } from "./Button/Button.mjs";
5
+ import { Button, buttonVariants } from "./Button/Button.mjs";
7
6
  import { MaxHeightSmoother } from "./MaxHeightSmoother/index.mjs";
8
7
  import { Accordion } from "./Accordion/Accordion.mjs";
9
8
  import { Avatar, getCapitals } from "./Avatar/index.mjs";
10
- import { Badge, BadgeColor, BadgeSize, BadgeVariant, badgeVariants } from "./Badge/index.mjs";
11
- import { Link, LinkColor, LinkRoundedSize, LinkSize, LinkUnderlined, LinkVariant, checkIsExternalLink, isTextChildren, linkVariants } from "./Link/Link.mjs";
9
+ import { Badge, badgeVariants } from "./Badge/index.mjs";
10
+ import { Link, checkIsExternalLink, isTextChildren, linkVariants } from "./Link/Link.mjs";
12
11
  import { Breadcrumb } from "./Breadcrumb/index.mjs";
12
+ import { Container, containerVariants } from "./Container/index.mjs";
13
13
  import { ClickOutsideDiv } from "./ClickOutsideDiv/index.mjs";
14
- import { DropDown, DropDownAlign, DropDownYAlign } from "./DropDown/index.mjs";
15
- import { Checkbox, CheckboxColor, CheckboxSize, checkboxVariants } from "./Input/Checkbox.mjs";
16
- import { Input, InputSize, InputVariant, inputVariants } from "./Input/Input.mjs";
14
+ import { DropDown } from "./DropDown/index.mjs";
15
+ import { Checkbox, checkboxVariants } from "./Input/Checkbox.mjs";
16
+ import { Input, inputVariants } from "./Input/Input.mjs";
17
17
  import { InputPassword } from "./Input/InputPassword.mjs";
18
18
  import { InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, OTPInput, OTPInputContext, inputSlotVariants, usePasswordManagerBadge, usePrevious } from "./Input/OTPInput.mjs";
19
+ import { Radio, radioVariants } from "./Input/Radio.mjs";
19
20
  import { SearchInput } from "./Input/SearchInput.mjs";
20
21
  import { Browser } from "./Browser/Browser.mjs";
21
- import { KeyList, KeyboardShortcut } from "./KeyboardShortcut/KeyboardShortcut.mjs";
22
- import { Detail, PopoverStatic, PopoverXAlign, PopoverYAlign } from "./Popover/static.mjs";
22
+ import { KeyboardShortcut } from "./KeyboardShortcut/KeyboardShortcut.mjs";
23
+ import { Detail, PopoverStatic } from "./Popover/static.mjs";
23
24
  import { Popover } from "./Popover/dynamic.mjs";
24
25
  import { Carousel } from "./Carousel/index.mjs";
25
26
  import { CollapsibleTable } from "./CollapsibleTable/CollapsibleTable.mjs";
26
27
  import { Command, CommandRoot } from "./Command/index.mjs";
28
+ import { TextArea } from "./TextArea/TextArea.mjs";
29
+ import { AutoSizedTextArea } from "./TextArea/AutoSizeTextArea.mjs";
30
+ import { ContentEditor } from "./ContentEditor/ContentEditor.mjs";
31
+ import { ContentEditorInput } from "./ContentEditor/ContentEditorInput.mjs";
32
+ import { ContentEditableTextArea, useContentEditable } from "./TextArea/ContentEditableTextArea.mjs";
33
+ import { AutoCompleteTextarea } from "./TextArea/AutocompleteTextArea.mjs";
34
+ import { ContentEditorTextArea } from "./ContentEditor/ContentEditorTextArea.mjs";
27
35
  import { PressableSpan } from "./PressableSpan/PressableSpan.mjs";
28
36
  import { ContentSelector } from "./ContentSelector/ContentSelector.mjs";
29
37
  import { CopyButton } from "./CopyButton/index.mjs";
30
38
  import { CopyToClipboard, useCopyToClipboard } from "./CopyToClipboard/index.mjs";
31
- import { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, choiceVariant, defaultChoices, indicatorVariant, switchSelectorVariant } from "./SwitchSelector/SwitchSelector.mjs";
39
+ import { SwitchSelector, choiceVariant, defaultChoices, indicatorVariant, switchSelectorVariant } from "./SwitchSelector/SwitchSelector.mjs";
32
40
  import { VerticalSwitchSelector } from "./SwitchSelector/VerticalSwitchSelector.mjs";
33
41
  import { EditableFieldInput } from "./EditableField/EditableFieldInput.mjs";
34
- import { ContentEditableTextArea, useContentEditable } from "./TextArea/ContentEditableTextArea.mjs";
35
- import { AutoCompleteTextarea } from "./TextArea/AutocompleteTextArea.mjs";
36
- import { TextArea } from "./TextArea/TextArea.mjs";
37
- import { AutoSizedTextArea } from "./TextArea/AutoSizeTextArea.mjs";
38
42
  import { EditableFieldTextArea } from "./EditableField/EditableFieldTextArea.mjs";
39
43
  import { DictionaryEditor } from "./DictionaryEditor/DictionaryEditor.mjs";
40
44
  import { LocaleSwitcherContentProvider, useLocaleSwitcherContent } from "./LocaleSwitcherContentDropDown/LocaleSwitcherContentContext.mjs";
41
45
  import { LocaleSwitcherContent } from "./LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs";
42
46
  import { Label } from "./Label/index.mjs";
43
47
  import { MultiSelect } from "./Select/Multiselect.mjs";
44
- import { Select, SelectContent, SelectContentPosition, SelectLabel, SelectSeparator } from "./Select/Select.mjs";
48
+ import { Select, SelectContent, SelectLabel, SelectSeparator } from "./Select/Select.mjs";
45
49
  import { TextEditor, TextEditorContainer, traceKeys } from "./DictionaryFieldEditor/ContentEditorView/TextEditor.mjs";
46
50
  import { KeyPathBreadcrumb } from "./DictionaryFieldEditor/KeyPathBreadcrumb.mjs";
47
- import { ContentEditor } from "./DictionaryFieldEditor/ContentEditor.mjs";
48
51
  import { useFormField } from "./Form/FormField.mjs";
49
52
  import { InformationTag } from "./InformationTag/index.mjs";
50
53
  import { useForm } from "./Form/FormBase.mjs";
51
54
  import { Form } from "./Form/Form.mjs";
52
55
  import { DictionaryCreationForm } from "./DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs";
53
- import { TabSelector, TabSelectorColor } from "./TabSelector/TabSelector.mjs";
56
+ import { TabSelector } from "./TabSelector/TabSelector.mjs";
54
57
  import { H1, H2, H3, H4, H5, H6 } from "./Headers/index.mjs";
55
- import { Modal, ModalSize } from "./Modal/Modal.mjs";
58
+ import { Modal } from "./Modal/Modal.mjs";
56
59
  import { SaveForm } from "./DictionaryFieldEditor/SaveForm/SaveForm.mjs";
57
60
  import { DictionaryFieldEditor } from "./DictionaryFieldEditor/DictionaryFieldEditor.mjs";
58
61
  import { VersionSwitcherProvider, useVersionSwitcher } from "./DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcherContext.mjs";
@@ -102,7 +105,7 @@ import { Burger } from "./Navbar/Burger.mjs";
102
105
  import { MobileNavbar } from "./Navbar/MobileNavbar.mjs";
103
106
  import { Navbar } from "./Navbar/index.mjs";
104
107
  import { NumberItemsSelector } from "./Pagination/NumberItemsSelector.mjs";
105
- import { Pagination, PaginationSize, PaginationVariant, paginationVariants } from "./Pagination/Pagination.mjs";
108
+ import { Pagination, paginationVariants } from "./Pagination/Pagination.mjs";
106
109
  import { ShowingResultsNumberItems } from "./Pagination/ShowingResultsNumberItems.mjs";
107
110
  import { DotPattern } from "./Pattern/DotPattern.mjs";
108
111
  import { GridPattern } from "./Pattern/GridPattern.mjs";
@@ -110,13 +113,11 @@ import { Spotlight } from "./Pattern/SpotLight.mjs";
110
113
  import { drawerManager, useRightDrawer } from "./RightDrawer/useRightDrawer.mjs";
111
114
  import { RightDrawer } from "./RightDrawer/RightDrawer.mjs";
112
115
  import { Step, Steps } from "./Steps/index.mjs";
113
- import { Tag, TagBackground, TagBorder, TagColor, TagRoundedSize, TagSize } from "./Tag/index.mjs";
114
- import { TechLogoName } from "./TechLogo/types.mjs";
116
+ import { Tag } from "./Tag/index.mjs";
115
117
  import { TechLogo } from "./TechLogo/TechLogo.mjs";
116
118
  import { techLogos_exports } from "./TechLogo/techLogos.mjs";
117
119
  import { Terminal } from "./Terminal/Terminal.mjs";
118
- import { Modes } from "./ThemeSwitcherDropDown/types.mjs";
119
120
  import { DesktopThemeSwitcher } from "./ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs";
120
121
  import { MobileThemeSwitcher } from "./ThemeSwitcherDropDown/MobileThemeSwitcher.mjs";
121
122
 
122
- export { Accordion, AutoCompleteTextarea, AutoSizedTextArea, Avatar, Badge, BadgeColor, BadgeSize, BadgeVariant, BitbucketLogo, Breadcrumb, Browser, Burger, Button, ButtonColor, ButtonSize, ButtonTextAlign, ButtonVariant, Carousel, Checkbox, CheckboxColor, CheckboxSize, ClickOutsideDiv, Code, CodeBlock, CodeDefault, CollapsibleTable, Command, CommandRoot, Container, ContainerBackground, ContainerBorderColor, ContainerGap, ContainerPadding, ContainerRoundedSize, ContainerSeparator, ContainerTransparency, ContentEditableTextArea, ContentEditor, ContentSelector, CopyButton, CopyToClipboard, DesktopNavbar, DesktopThemeSwitcher, Detail, DictionaryCreationForm, DictionaryEditor, DictionaryFieldEditor, DiscordLogo, DotPattern, DropDown, DropDownAlign, DropDownYAlign, EditableFieldInput, EditableFieldTextArea, ExpandCollapse, FacebookLogo, FileList, Flag, flags_exports as Flags, Footer, Form, GitHubLogo, GitLabLogo, GoogleLogo, GridPattern, H1, H2, H3, H4, H5, H6, HTMLRenderer, HeightResizer, HideShow, Hr, IDE, InformationTag, Input, InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputPassword, InputSize, InputVariant, InstagramLogo, KeyList, KeyPathBreadcrumb, KeyboardScreenAdapter, KeyboardShortcut, Label, LanguageBackground, LanguageSection, Link, LinkColor, LinkRoundedSize, LinkSize, LinkUnderlined, LinkVariant, LinkedInLogo, Loader, LocaleSwitcher, LocaleSwitcherContent, LocaleSwitcherContentProvider, Logo, LogoTextOnly, LogoWithText, LogoWithTextBelow, MarkDownIframe, MarkdownRenderer, MaxHeightSmoother, MaxWidthSmoother, MobileNavbar, MobileThemeSwitcher, Modal, ModalSize, Modes, MultiSelect, Navbar, NumberItemsSelector, OTPInput, OTPInputContext, Pagination, PaginationSize, PaginationVariant, Popover, PopoverStatic, PopoverXAlign, PopoverYAlign, PressableSpan, ProductHuntLogo, RightDrawer, SaveForm, SearchInput, Select, SelectContent, SelectContentPosition, SelectLabel, SelectSeparator, ShowingResultsNumberItems, SmartTable, SocialNetworks, Spotlight, Step, Steps, SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, Tab, TabSelector, TabSelectorColor, Table, Tag, TagBackground, TagBorder, TagColor, TagRoundedSize, TagSize, Td, TechLogo, TechLogoName, techLogos_exports as TechLogos, Terminal, TextArea, TextEditor, TextEditorContainer, Th, TiktokLogo, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Tr, VersionSwitcher, VersionSwitcherProvider, VerticalSwitchSelector, WithResizer, XLogo, YoutubeLogo, badgeVariants, baseMarkdownComponents, buttonVariants, checkIsExternalLink, checkboxVariants, choiceVariant, containerVariants, defaultChoices, drawerManager, getCapitals, getIntlayerHTMLOptions, getIntlayerMarkdownOptions, indicatorVariant, inputSlotVariants, inputVariants, isTextChildren, linkVariants, paginationVariants, reducer, switchSelectorVariant, toast, toastVariants, traceKeys, useContentEditable, useCopyToClipboard, useForm, useFormField, useLocaleSwitcherContent, usePasswordManagerBadge, usePrevious, useRightDrawer, useToast, useVersionSwitcher };
123
+ export { Accordion, AutoCompleteTextarea, AutoSizedTextArea, Avatar, Badge, BitbucketLogo, Breadcrumb, Browser, Burger, Button, Carousel, Checkbox, ClickOutsideDiv, Code, CodeBlock, CodeDefault, CollapsibleTable, Command, CommandRoot, Container, ContentEditableTextArea, ContentEditorInput, ContentEditorTextArea, ContentSelector, CopyButton, CopyToClipboard, DesktopNavbar, DesktopThemeSwitcher, Detail, DictionaryCreationForm, DictionaryEditor, DictionaryFieldEditor, DiscordLogo, DotPattern, DropDown, EditableFieldInput, EditableFieldTextArea, ExpandCollapse, FacebookLogo, FileList, Flag, flags_exports as Flags, Footer, Form, GitHubLogo, GitLabLogo, GoogleLogo, GridPattern, H1, H2, H3, H4, H5, H6, HTMLRenderer, HeightResizer, HideShow, Hr, IDE, InformationTag, Input, InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputPassword, InstagramLogo, KeyPathBreadcrumb, KeyboardScreenAdapter, KeyboardShortcut, Label, LanguageBackground, LanguageSection, Link, LinkedInLogo, Loader, LocaleSwitcher, LocaleSwitcherContent, LocaleSwitcherContentProvider, Logo, LogoTextOnly, LogoWithText, LogoWithTextBelow, MarkDownIframe, MarkdownRenderer, MaxHeightSmoother, MaxWidthSmoother, MobileNavbar, MobileThemeSwitcher, Modal, MultiSelect, Navbar, NumberItemsSelector, OTPInput, OTPInputContext, Pagination, Popover, PopoverStatic, PressableSpan, ProductHuntLogo, Radio, RightDrawer, SaveForm, SearchInput, Select, SelectContent, SelectLabel, SelectSeparator, ShowingResultsNumberItems, SmartTable, SocialNetworks, Spotlight, Step, Steps, SwitchSelector, Tab, TabSelector, Table, Tag, Td, TechLogo, techLogos_exports as TechLogos, Terminal, TextArea, TextEditor, TextEditorContainer, Th, TiktokLogo, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Tr, VersionSwitcher, VersionSwitcherProvider, VerticalSwitchSelector, WithResizer, XLogo, YoutubeLogo, badgeVariants, baseMarkdownComponents, buttonVariants, checkIsExternalLink, checkboxVariants, choiceVariant, containerVariants, defaultChoices, drawerManager, getCapitals, getIntlayerHTMLOptions, getIntlayerMarkdownOptions, indicatorVariant, inputSlotVariants, inputVariants, isTextChildren, linkVariants, paginationVariants, radioVariants, reducer, switchSelectorVariant, toast, toastVariants, traceKeys, useContentEditable, useCopyToClipboard, useForm, useFormField, useLocaleSwitcherContent, usePasswordManagerBadge, usePrevious, useRightDrawer, useToast, useVersionSwitcher };
@@ -15,9 +15,16 @@ declare const useGetCIConfig: (options?: Partial<UseQueryOptions>) => QueryObser
15
15
  declare const usePushCIConfig: () => any;
16
16
  declare const useTriggerBuild: () => any;
17
17
  declare const useTriggerWebhook: () => any;
18
+ declare const useAddEnvironment: () => any;
19
+ declare const useUpdateEnvironment: () => any;
20
+ declare const useDeleteEnvironment: () => any;
21
+ declare const useSelectEnvironment: () => any;
22
+ declare const useResetToProductionEnvironment: () => any;
23
+ declare const useMigrateEnvironment: () => any;
18
24
  declare const useAddNewAccessKey: () => any;
19
25
  declare const useDeleteAccessKey: () => any;
20
26
  declare const useRefreshAccessKey: () => any;
27
+ declare const useUpdateMemberAccess: () => any;
21
28
  //#endregion
22
- export { useAddNewAccessKey, useAddProject, useDeleteAccessKey, useDeleteProject, useDeleteProjectById, useGetCIConfig, useGetProjects, usePushCIConfig, usePushProjectConfiguration, useRefreshAccessKey, useSelectProject, useTriggerBuild, useTriggerWebhook, useUnselectProject, useUpdateProject, useUpdateProjectMembers };
29
+ export { useAddEnvironment, useAddNewAccessKey, useAddProject, useDeleteAccessKey, useDeleteEnvironment, useDeleteProject, useDeleteProjectById, useGetCIConfig, useGetProjects, useMigrateEnvironment, usePushCIConfig, usePushProjectConfiguration, useRefreshAccessKey, useResetToProductionEnvironment, useSelectEnvironment, useSelectProject, useTriggerBuild, useTriggerWebhook, useUnselectProject, useUpdateEnvironment, useUpdateMemberAccess, useUpdateProject, useUpdateProjectMembers };
23
30
  //# sourceMappingURL=project.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.ts","names":[],"sources":["../../../../src/api/hooks/project.ts"],"mappings":";;;;cAqBa,cAAA,GACX,OAAA,GAAU,iBAAA,EACV,OAAA,GAAU,OAAA,CAAQ,eAAA,MAAgB,mBAAA,CAAA,KAAA,EAAA,MAAA;AAAA,cAcvB,aAAA;AAAA,cAYA,gBAAA;AAAA,cAqBA,2BAAA;AAAA,cAmBA,uBAAA;AAAA,cAaA,gBAAA;AAAA,cAYA,oBAAA;AAAA,cAaA,gBAAA;AAAA,cA4BA,kBAAA;AAAA,cA4BA,cAAA,GAAkB,OAAA,GAAU,OAAA,CAAQ,eAAA,MAAgB,mBAAA,CAAA,KAAA,EAAA,MAAA;AAAA,cAWpD,eAAA;AAAA,cAYA,eAAA;AAAA,cAYA,iBAAA;AAAA,cAaA,kBAAA;AAAA,cAYA,kBAAA;AAAA,cAYA,mBAAA"}
1
+ {"version":3,"file":"project.d.ts","names":[],"sources":["../../../../src/api/hooks/project.ts"],"mappings":";;;;cAyBa,cAAA,GACX,OAAA,GAAU,iBAAA,EACV,OAAA,GAAU,OAAA,CAAQ,eAAA,MAAgB,mBAAA,CAAA,KAAA,EAAA,MAAA;AAAA,cAcvB,aAAA;AAAA,cAYA,gBAAA;AAAA,cAqBA,2BAAA;AAAA,cAmBA,uBAAA;AAAA,cAaA,gBAAA;AAAA,cAYA,oBAAA;AAAA,cAaA,gBAAA;AAAA,cA4BA,kBAAA;AAAA,cA4BA,cAAA,GAAkB,OAAA,GAAU,OAAA,CAAQ,eAAA,MAAgB,mBAAA,CAAA,KAAA,EAAA,MAAA;AAAA,cAWpD,eAAA;AAAA,cAYA,eAAA;AAAA,cAYA,iBAAA;AAAA,cAaA,iBAAA;AAAA,cAqBA,oBAAA;AAAA,cAyBA,oBAAA;AAAA,cAsBA,oBAAA;AAAA,cAmBA,+BAAA;AAAA,cAkBA,qBAAA;AAAA,cAaA,kBAAA;AAAA,cAYA,kBAAA;AAAA,cAYA,mBAAA;AAAA,cAaA,qBAAA"}