@copilotkit/react-textarea 0.24.0 → 0.26.0-alpha.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 (277) hide show
  1. package/.turbo/turbo-build.log +313 -309
  2. package/CHANGELOG.md +22 -0
  3. package/dist/components/base-copilot-textarea/base-copilot-textarea.d.ts +29 -0
  4. package/dist/components/base-copilot-textarea/base-copilot-textarea.mjs +1745 -35
  5. package/dist/components/base-copilot-textarea/base-copilot-textarea.mjs.map +1 -1
  6. package/dist/components/base-copilot-textarea/render-element.mjs +51 -3
  7. package/dist/components/base-copilot-textarea/render-element.mjs.map +1 -1
  8. package/dist/components/base-copilot-textarea/render-placeholder.mjs +49 -3
  9. package/dist/components/base-copilot-textarea/render-placeholder.mjs.map +1 -1
  10. package/dist/components/base-copilot-textarea/track-cursor-moved-since-last-text-change.mjs +86 -4
  11. package/dist/components/base-copilot-textarea/track-cursor-moved-since-last-text-change.mjs.map +1 -1
  12. package/dist/components/base-copilot-textarea/use-add-branding-css.mjs +57 -3
  13. package/dist/components/base-copilot-textarea/use-add-branding-css.mjs.map +1 -1
  14. package/dist/components/copilot-textarea/copilot-textarea.d.ts +3 -0
  15. package/dist/components/copilot-textarea/copilot-textarea.mjs +2202 -47
  16. package/dist/components/copilot-textarea/copilot-textarea.mjs.map +1 -1
  17. package/dist/components/hovering-toolbar/hovering-editor-provider.d.ts +7 -3
  18. package/dist/components/hovering-toolbar/hovering-editor-provider.mjs +17 -3
  19. package/dist/components/hovering-toolbar/hovering-editor-provider.mjs.map +1 -1
  20. package/dist/components/hovering-toolbar/hovering-toolbar-components.mjs +137 -3
  21. package/dist/components/hovering-toolbar/hovering-toolbar-components.mjs.map +1 -1
  22. package/dist/components/hovering-toolbar/hovering-toolbar.mjs +875 -18
  23. package/dist/components/hovering-toolbar/hovering-toolbar.mjs.map +1 -1
  24. package/dist/components/hovering-toolbar/text-insertion-prompt-box/hovering-insertion-prompt-box-core.mjs +558 -12
  25. package/dist/components/hovering-toolbar/text-insertion-prompt-box/hovering-insertion-prompt-box-core.mjs.map +1 -1
  26. package/dist/components/hovering-toolbar/text-insertion-prompt-box/hovering-insertion-prompt-box.mjs +581 -13
  27. package/dist/components/hovering-toolbar/text-insertion-prompt-box/hovering-insertion-prompt-box.mjs.map +1 -1
  28. package/dist/components/hovering-toolbar/text-insertion-prompt-box/included-files-preview.mjs +102 -5
  29. package/dist/components/hovering-toolbar/text-insertion-prompt-box/included-files-preview.mjs.map +1 -1
  30. package/dist/components/hovering-toolbar/text-insertion-prompt-box/index.mjs +581 -14
  31. package/dist/components/hovering-toolbar/text-insertion-prompt-box/index.mjs.map +1 -1
  32. package/dist/components/index.mjs +2203 -48
  33. package/dist/components/index.mjs.map +1 -1
  34. package/dist/components/manual-ui/chip-with-icon.mjs +11 -27
  35. package/dist/components/manual-ui/chip-with-icon.mjs.map +1 -1
  36. package/dist/components/source-search-box/source-search-box.mjs +211 -6
  37. package/dist/components/source-search-box/source-search-box.mjs.map +1 -1
  38. package/dist/components/ui/button.mjs +85 -4
  39. package/dist/components/ui/button.mjs.map +1 -1
  40. package/dist/components/ui/card.mjs +96 -52
  41. package/dist/components/ui/card.mjs.map +1 -1
  42. package/dist/components/ui/command.mjs +244 -5
  43. package/dist/components/ui/command.mjs.map +1 -1
  44. package/dist/components/ui/dialog.mjs +144 -4
  45. package/dist/components/ui/dialog.mjs.map +1 -1
  46. package/dist/components/ui/label.mjs +60 -4
  47. package/dist/components/ui/label.mjs.map +1 -1
  48. package/dist/components/ui/separator.mjs +58 -15
  49. package/dist/components/ui/separator.mjs.map +1 -1
  50. package/dist/components/ui/textarea.mjs +58 -14
  51. package/dist/components/ui/textarea.mjs.map +1 -1
  52. package/dist/context/index.d.ts +1 -0
  53. package/dist/context/index.mjs +0 -2
  54. package/dist/context/index.mjs.map +1 -1
  55. package/dist/hooks/base-copilot-textarea-implementation/use-autosuggestions.d.ts +1 -1
  56. package/dist/hooks/base-copilot-textarea-implementation/use-autosuggestions.mjs +158 -6
  57. package/dist/hooks/base-copilot-textarea-implementation/use-autosuggestions.mjs.map +1 -1
  58. package/dist/hooks/base-copilot-textarea-implementation/use-copilot-textarea-editor.mjs +168 -4
  59. package/dist/hooks/base-copilot-textarea-implementation/use-copilot-textarea-editor.mjs.map +1 -1
  60. package/dist/hooks/base-copilot-textarea-implementation/use-populate-copilot-textarea-ref.mjs +148 -5
  61. package/dist/hooks/base-copilot-textarea-implementation/use-populate-copilot-textarea-ref.mjs.map +1 -1
  62. package/dist/hooks/index.d.ts +1 -0
  63. package/dist/hooks/index.mjs +0 -2
  64. package/dist/hooks/index.mjs.map +1 -1
  65. package/dist/hooks/make-autosuggestions-function/use-make-standard-autosuggestions-function.mjs +147 -14
  66. package/dist/hooks/make-autosuggestions-function/use-make-standard-autosuggestions-function.mjs.map +1 -1
  67. package/dist/hooks/make-autosuggestions-function/use-make-standard-insertion-function.mjs +193 -14
  68. package/dist/hooks/make-autosuggestions-function/use-make-standard-insertion-function.mjs.map +1 -1
  69. package/dist/hooks/misc/use-autosize-textarea.mjs +15 -3
  70. package/dist/hooks/misc/use-autosize-textarea.mjs.map +1 -1
  71. package/dist/index.mjs +2206 -50
  72. package/dist/index.mjs.map +1 -1
  73. package/dist/lib/debouncer.mjs +51 -3
  74. package/dist/lib/debouncer.mjs.map +1 -1
  75. package/dist/lib/editor-to-text.mjs +43 -3
  76. package/dist/lib/editor-to-text.mjs.map +1 -1
  77. package/dist/lib/get-text-around-cursor.mjs +102 -3
  78. package/dist/lib/get-text-around-cursor.mjs.map +1 -1
  79. package/dist/lib/retry.mjs +17 -3
  80. package/dist/lib/retry.mjs.map +1 -1
  81. package/dist/lib/slatejs-edits/add-autocompletions.mjs +25 -3
  82. package/dist/lib/slatejs-edits/add-autocompletions.mjs.map +1 -1
  83. package/dist/lib/slatejs-edits/clear-autocompletions.mjs +20 -3
  84. package/dist/lib/slatejs-edits/clear-autocompletions.mjs.map +1 -1
  85. package/dist/lib/slatejs-edits/replace-text.mjs +27 -3
  86. package/dist/lib/slatejs-edits/replace-text.mjs.map +1 -1
  87. package/dist/lib/slatejs-edits/with-partial-history.mjs +106 -3
  88. package/dist/lib/slatejs-edits/with-partial-history.mjs.map +1 -1
  89. package/dist/lib/stream-promise-flatten.mjs +47 -3
  90. package/dist/lib/stream-promise-flatten.mjs.map +1 -1
  91. package/dist/lib/utils.mjs +71 -3
  92. package/dist/lib/utils.mjs.map +1 -1
  93. package/dist/lib/utils.test.d.ts +1 -0
  94. package/dist/lib/utils.test.mjs +0 -1
  95. package/dist/lib/utils.test.mjs.map +1 -1
  96. package/dist/types/autosuggestions-config/autosuggestions-config-user-specified.mjs +0 -2
  97. package/dist/types/autosuggestions-config/autosuggestions-config-user-specified.mjs.map +1 -1
  98. package/dist/types/autosuggestions-config/autosuggestions-config.mjs +265 -8
  99. package/dist/types/autosuggestions-config/autosuggestions-config.mjs.map +1 -1
  100. package/dist/types/autosuggestions-config/editing-api-config.mjs +81 -3
  101. package/dist/types/autosuggestions-config/editing-api-config.mjs.map +1 -1
  102. package/dist/types/autosuggestions-config/index.mjs +327 -10
  103. package/dist/types/autosuggestions-config/index.mjs.map +1 -1
  104. package/dist/types/autosuggestions-config/insertions-api-config.mjs +75 -3
  105. package/dist/types/autosuggestions-config/insertions-api-config.mjs.map +1 -1
  106. package/dist/types/autosuggestions-config/subtypes/chatlike-api-endpoint.mjs +83 -3
  107. package/dist/types/autosuggestions-config/subtypes/chatlike-api-endpoint.mjs.map +1 -1
  108. package/dist/types/autosuggestions-config/subtypes/make-system-prompt.mjs +0 -2
  109. package/dist/types/autosuggestions-config/subtypes/make-system-prompt.mjs.map +1 -1
  110. package/dist/types/autosuggestions-config/subtypes/minimal-chat-gpt-message.mjs +0 -2
  111. package/dist/types/autosuggestions-config/subtypes/minimal-chat-gpt-message.mjs.map +1 -1
  112. package/dist/types/autosuggestions-config/suggestions-api-config.mjs +64 -3
  113. package/dist/types/autosuggestions-config/suggestions-api-config.mjs.map +1 -1
  114. package/dist/types/base/autosuggestion-state.mjs +0 -2
  115. package/dist/types/base/autosuggestion-state.mjs.map +1 -1
  116. package/dist/types/base/autosuggestions-bare-function.mjs +0 -2
  117. package/dist/types/base/autosuggestions-bare-function.mjs.map +1 -1
  118. package/dist/types/base/base-autosuggestions-config.d.ts +55 -2
  119. package/dist/types/base/base-autosuggestions-config.mjs +26 -3
  120. package/dist/types/base/base-autosuggestions-config.mjs.map +1 -1
  121. package/dist/types/base/base-copilot-textarea-props.mjs +0 -2
  122. package/dist/types/base/base-copilot-textarea-props.mjs.map +1 -1
  123. package/dist/types/base/custom-editor.mjs +0 -2
  124. package/dist/types/base/custom-editor.mjs.map +1 -1
  125. package/dist/types/base/editor-autocomplete-state.mjs +17 -4
  126. package/dist/types/base/editor-autocomplete-state.mjs.map +1 -1
  127. package/dist/types/base/index.mjs +26 -4
  128. package/dist/types/base/index.mjs.map +1 -1
  129. package/dist/types/html-copilot-textarea-element.mjs +0 -2
  130. package/dist/types/html-copilot-textarea-element.mjs.map +1 -1
  131. package/dist/types/index.mjs +328 -12
  132. package/dist/types/index.mjs.map +1 -1
  133. package/package.json +7 -7
  134. package/src/components/base-copilot-textarea/base-copilot-textarea.tsx +79 -45
  135. package/src/components/base-copilot-textarea/render-element.tsx +3 -5
  136. package/src/components/base-copilot-textarea/render-placeholder.tsx +2 -4
  137. package/src/components/base-copilot-textarea/track-cursor-moved-since-last-text-change.tsx +22 -3
  138. package/src/components/base-copilot-textarea/use-add-branding-css.tsx +2 -4
  139. package/src/components/copilot-textarea/copilot-textarea.tsx +14 -18
  140. package/src/components/hovering-toolbar/hovering-editor-provider.tsx +7 -5
  141. package/src/components/hovering-toolbar/hovering-toolbar-components.tsx +14 -31
  142. package/src/components/hovering-toolbar/hovering-toolbar.tsx +4 -16
  143. package/src/components/hovering-toolbar/text-insertion-prompt-box/hovering-insertion-prompt-box-core.tsx +11 -25
  144. package/src/components/hovering-toolbar/text-insertion-prompt-box/included-files-preview.tsx +2 -7
  145. package/src/components/manual-ui/chip-with-icon.tsx +3 -12
  146. package/src/components/source-search-box/source-search-box.tsx +2 -12
  147. package/src/components/ui/button.tsx +6 -13
  148. package/src/components/ui/card.tsx +35 -65
  149. package/src/components/ui/command.tsx +8 -21
  150. package/src/components/ui/dialog.tsx +8 -29
  151. package/src/components/ui/label.tsx +3 -8
  152. package/src/components/ui/separator.tsx +13 -18
  153. package/src/components/ui/textarea.tsx +3 -4
  154. package/src/hooks/base-copilot-textarea-implementation/use-autosuggestions.ts +13 -27
  155. package/src/hooks/base-copilot-textarea-implementation/use-copilot-textarea-editor.tsx +1 -5
  156. package/src/hooks/base-copilot-textarea-implementation/use-populate-copilot-textarea-ref.ts +4 -11
  157. package/src/hooks/make-autosuggestions-function/use-make-standard-autosuggestions-function.tsx +5 -10
  158. package/src/hooks/make-autosuggestions-function/use-make-standard-insertion-function.tsx +15 -35
  159. package/src/hooks/misc/use-autosize-textarea.tsx +1 -4
  160. package/src/lib/debouncer.ts +1 -3
  161. package/src/lib/editor-to-text.ts +4 -7
  162. package/src/lib/get-text-around-cursor.ts +2 -14
  163. package/src/lib/retry.tsx +1 -1
  164. package/src/lib/slatejs-edits/add-autocompletions.ts +2 -2
  165. package/src/lib/slatejs-edits/clear-autocompletions.ts +1 -4
  166. package/src/lib/slatejs-edits/replace-text.ts +1 -1
  167. package/src/lib/slatejs-edits/with-partial-history.ts +4 -11
  168. package/src/lib/stream-promise-flatten.ts +1 -3
  169. package/src/lib/utils.ts +4 -8
  170. package/src/types/autosuggestions-config/autosuggestions-config-user-specified.tsx +3 -7
  171. package/src/types/autosuggestions-config/autosuggestions-config.tsx +5 -18
  172. package/src/types/autosuggestions-config/editing-api-config.tsx +3 -5
  173. package/src/types/autosuggestions-config/insertions-api-config.tsx +2 -3
  174. package/src/types/autosuggestions-config/subtypes/chatlike-api-endpoint.tsx +18 -26
  175. package/src/types/autosuggestions-config/subtypes/make-system-prompt.ts +1 -4
  176. package/src/types/autosuggestions-config/suggestions-api-config.tsx +2 -3
  177. package/src/types/base/autosuggestions-bare-function.ts +2 -2
  178. package/src/types/base/base-autosuggestions-config.tsx +80 -3
  179. package/src/types/base/editor-autocomplete-state.ts +1 -1
  180. package/dist/chunk-2NURR2DX.mjs +0 -47
  181. package/dist/chunk-2NURR2DX.mjs.map +0 -1
  182. package/dist/chunk-3L6CNVCE.mjs +0 -108
  183. package/dist/chunk-3L6CNVCE.mjs.map +0 -1
  184. package/dist/chunk-463BFNUP.mjs +0 -77
  185. package/dist/chunk-463BFNUP.mjs.map +0 -1
  186. package/dist/chunk-4HHYJGZE.mjs +0 -117
  187. package/dist/chunk-4HHYJGZE.mjs.map +0 -1
  188. package/dist/chunk-4LOLCQGR.mjs +0 -50
  189. package/dist/chunk-4LOLCQGR.mjs.map +0 -1
  190. package/dist/chunk-4S5ZJH3I.mjs +0 -18
  191. package/dist/chunk-4S5ZJH3I.mjs.map +0 -1
  192. package/dist/chunk-4UYKBG35.mjs +0 -57
  193. package/dist/chunk-4UYKBG35.mjs.map +0 -1
  194. package/dist/chunk-5EJ5XOGP.mjs +0 -22
  195. package/dist/chunk-5EJ5XOGP.mjs.map +0 -1
  196. package/dist/chunk-5FO6ISW4.mjs +0 -3
  197. package/dist/chunk-5FO6ISW4.mjs.map +0 -1
  198. package/dist/chunk-6Z2ATUNY.mjs +0 -15
  199. package/dist/chunk-6Z2ATUNY.mjs.map +0 -1
  200. package/dist/chunk-AQHORK66.mjs +0 -49
  201. package/dist/chunk-AQHORK66.mjs.map +0 -1
  202. package/dist/chunk-AXN37AHC.mjs +0 -80
  203. package/dist/chunk-AXN37AHC.mjs.map +0 -1
  204. package/dist/chunk-CSGFJU3L.mjs +0 -65
  205. package/dist/chunk-CSGFJU3L.mjs.map +0 -1
  206. package/dist/chunk-DE5K76I2.mjs +0 -3
  207. package/dist/chunk-DE5K76I2.mjs.map +0 -1
  208. package/dist/chunk-F3MHL6ZY.mjs +0 -25
  209. package/dist/chunk-F3MHL6ZY.mjs.map +0 -1
  210. package/dist/chunk-GCMQHIRF.mjs +0 -29
  211. package/dist/chunk-GCMQHIRF.mjs.map +0 -1
  212. package/dist/chunk-GIJ3JZ4P.mjs +0 -224
  213. package/dist/chunk-GIJ3JZ4P.mjs.map +0 -1
  214. package/dist/chunk-GUH3Y2H4.mjs +0 -19
  215. package/dist/chunk-GUH3Y2H4.mjs.map +0 -1
  216. package/dist/chunk-H4VKQGVU.mjs +0 -3
  217. package/dist/chunk-H4VKQGVU.mjs.map +0 -1
  218. package/dist/chunk-IU3WTXLQ.mjs +0 -3
  219. package/dist/chunk-IU3WTXLQ.mjs.map +0 -1
  220. package/dist/chunk-IXJ2HCOA.mjs +0 -101
  221. package/dist/chunk-IXJ2HCOA.mjs.map +0 -1
  222. package/dist/chunk-JAFCXEPU.mjs +0 -10
  223. package/dist/chunk-JAFCXEPU.mjs.map +0 -1
  224. package/dist/chunk-JHTAOLEW.mjs +0 -63
  225. package/dist/chunk-JHTAOLEW.mjs.map +0 -1
  226. package/dist/chunk-JYVC4AW3.mjs +0 -205
  227. package/dist/chunk-JYVC4AW3.mjs.map +0 -1
  228. package/dist/chunk-KCHYD3EB.mjs +0 -107
  229. package/dist/chunk-KCHYD3EB.mjs.map +0 -1
  230. package/dist/chunk-KGKLUWKW.mjs +0 -47
  231. package/dist/chunk-KGKLUWKW.mjs.map +0 -1
  232. package/dist/chunk-L7VVZH4Q.mjs +0 -3
  233. package/dist/chunk-L7VVZH4Q.mjs.map +0 -1
  234. package/dist/chunk-LNAIMEB2.mjs +0 -34
  235. package/dist/chunk-LNAIMEB2.mjs.map +0 -1
  236. package/dist/chunk-MMVDU6DF.mjs +0 -3
  237. package/dist/chunk-MMVDU6DF.mjs.map +0 -1
  238. package/dist/chunk-MPME5BW2.mjs +0 -59
  239. package/dist/chunk-MPME5BW2.mjs.map +0 -1
  240. package/dist/chunk-MRXNTQOX.mjs +0 -55
  241. package/dist/chunk-MRXNTQOX.mjs.map +0 -1
  242. package/dist/chunk-ND5PXTAW.mjs +0 -17
  243. package/dist/chunk-ND5PXTAW.mjs.map +0 -1
  244. package/dist/chunk-NKW5OU2S.mjs +0 -33
  245. package/dist/chunk-NKW5OU2S.mjs.map +0 -1
  246. package/dist/chunk-O4MHJSK2.mjs +0 -21
  247. package/dist/chunk-O4MHJSK2.mjs.map +0 -1
  248. package/dist/chunk-O5OWT5GE.mjs +0 -114
  249. package/dist/chunk-O5OWT5GE.mjs.map +0 -1
  250. package/dist/chunk-OD7ZMOVE.mjs +0 -45
  251. package/dist/chunk-OD7ZMOVE.mjs.map +0 -1
  252. package/dist/chunk-OELUUJZY.mjs +0 -16
  253. package/dist/chunk-OELUUJZY.mjs.map +0 -1
  254. package/dist/chunk-QJDMIGLU.mjs +0 -38
  255. package/dist/chunk-QJDMIGLU.mjs.map +0 -1
  256. package/dist/chunk-RQHOUUXQ.mjs +0 -29
  257. package/dist/chunk-RQHOUUXQ.mjs.map +0 -1
  258. package/dist/chunk-RR6OQGTI.mjs +0 -74
  259. package/dist/chunk-RR6OQGTI.mjs.map +0 -1
  260. package/dist/chunk-UHD44NC5.mjs +0 -101
  261. package/dist/chunk-UHD44NC5.mjs.map +0 -1
  262. package/dist/chunk-WADHCMPK.mjs +0 -3
  263. package/dist/chunk-WADHCMPK.mjs.map +0 -1
  264. package/dist/chunk-WJHSY5T6.mjs +0 -3
  265. package/dist/chunk-WJHSY5T6.mjs.map +0 -1
  266. package/dist/chunk-WJYQWL4I.mjs +0 -27
  267. package/dist/chunk-WJYQWL4I.mjs.map +0 -1
  268. package/dist/chunk-WLPYYGES.mjs +0 -109
  269. package/dist/chunk-WLPYYGES.mjs.map +0 -1
  270. package/dist/chunk-XHUMROEY.mjs +0 -91
  271. package/dist/chunk-XHUMROEY.mjs.map +0 -1
  272. package/dist/chunk-YQU7WG7T.mjs +0 -83
  273. package/dist/chunk-YQU7WG7T.mjs.map +0 -1
  274. package/dist/chunk-YTOPHPSG.mjs +0 -45
  275. package/dist/chunk-YTOPHPSG.mjs.map +0 -1
  276. package/dist/chunk-YW3REYX6.mjs +0 -23
  277. package/dist/chunk-YW3REYX6.mjs.map +0 -1
@@ -1,11 +1,9 @@
1
1
  import { RenderElementProps, RenderPlaceholderProps } from "slate-react";
2
2
 
3
- export type RenderPlaceholderFunction = (
4
- props: RenderPlaceholderProps
5
- ) => JSX.Element;
3
+ export type RenderPlaceholderFunction = (props: RenderPlaceholderProps) => JSX.Element;
6
4
 
7
5
  export function makeRenderPlaceholderFunction(
8
- placeholderStyle?: React.CSSProperties
6
+ placeholderStyle?: React.CSSProperties,
9
7
  ): RenderPlaceholderFunction {
10
8
  return (props: RenderPlaceholderProps) => {
11
9
  const { style, ...restAttributes } = props.attributes;
@@ -8,7 +8,7 @@ interface TrackerTextEditedSinceLastCursorMovementProps {
8
8
  setCursorMovedSinceLastTextChange: (value: boolean) => void;
9
9
  }
10
10
  export function TrackerTextEditedSinceLastCursorMovement(
11
- props: TrackerTextEditedSinceLastCursorMovementProps
11
+ props: TrackerTextEditedSinceLastCursorMovementProps,
12
12
  ): JSX.Element {
13
13
  const cursorState: RelevantEditorState = useSlateSelector((state) => ({
14
14
  selection: state.selection,
@@ -29,14 +29,16 @@ export function TrackerTextEditedSinceLastCursorMovement(
29
29
 
30
30
  return <></>;
31
31
  }
32
+
32
33
  type RelevantEditorState = {
33
34
  selection: BaseSelection;
34
35
  text: string;
35
36
  };
37
+
36
38
  const cursorChangedWithoutTextChanged = (
37
39
  prev: RelevantEditorState,
38
- next: RelevantEditorState
39
- ) => {
40
+ next: RelevantEditorState,
41
+ ): boolean => {
40
42
  // Check if the selection has changed
41
43
  const isSelectionChanged = !isSelectionEqual(prev.selection, next.selection);
42
44
 
@@ -45,11 +47,28 @@ const cursorChangedWithoutTextChanged = (
45
47
 
46
48
  return isSelectionChanged && isTextSame;
47
49
  };
50
+
48
51
  const isSelectionEqual = (a: BaseSelection, b: BaseSelection) => {
49
52
  if (!a && !b) return true;
50
53
  if (!a || !b) return false;
51
54
  return Range.equals(a, b);
52
55
  };
56
+
57
+ /**
58
+ * Easily keep track of the *previous* value of a variable.
59
+ *
60
+ * Example:
61
+ * ```
62
+ * const [count, setCount] = useState(0);
63
+ * const prevCount = usePrevious(count);
64
+ *
65
+ * useEffect(() => {
66
+ * if (count > prevCount) {
67
+ * console.log('Now I know that count is bigger than before');
68
+ * }
69
+ * }, [count, prevCount]);
70
+ * ```
71
+ */
53
72
  function usePrevious<T>(value: T): T | undefined {
54
73
  const ref = useRef<T>();
55
74
 
@@ -2,7 +2,7 @@ import { useEffect } from "react";
2
2
 
3
3
  export function useAddBrandingCss(
4
4
  suggestionStyleAugmented: React.CSSProperties,
5
- disableBranding: boolean | undefined
5
+ disableBranding: boolean | undefined,
6
6
  ) {
7
7
  const cssSelector = ".copilot-textarea.with-branding";
8
8
  useEffect(() => {
@@ -18,9 +18,7 @@ export function useAddBrandingCss(
18
18
  // Build the CSS string dynamically
19
19
  let dynamicStyles = Object.entries(suggestionStyleAugmented)
20
20
  .map(([key, value]) => {
21
- const kebabCaseKey = key
22
- .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2")
23
- .toLowerCase();
21
+ const kebabCaseKey = key.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
24
22
  return `${kebabCaseKey}: ${value};`;
25
23
  })
26
24
  .join(" ");
@@ -19,35 +19,31 @@ export interface CopilotTextareaProps
19
19
  autosuggestionsConfig: AutosuggestionsConfigUserSpecified;
20
20
  }
21
21
 
22
+ /**
23
+ * A copilot textarea that uses the standard autosuggestions function.
24
+ */
22
25
  export const CopilotTextarea = React.forwardRef(
23
- (
24
- props: CopilotTextareaProps,
25
- ref: React.Ref<HTMLCopilotTextAreaElement>
26
- ): JSX.Element => {
26
+ (props: CopilotTextareaProps, ref: React.Ref<HTMLCopilotTextAreaElement>): JSX.Element => {
27
27
  // separate the AutosuggestionsConfigUserSpecified from the rest of the props
28
- const {
29
- autosuggestionsConfig: autosuggestionsConfigUserSpecified,
30
- ...forwardedProps
31
- } = props;
28
+ const { autosuggestionsConfig: autosuggestionsConfigUserSpecified, ...forwardedProps } = props;
32
29
 
33
30
  const autosuggestionsConfig: AutosuggestionsConfig = merge(
34
31
  defaultAutosuggestionsConfig,
35
- autosuggestionsConfigUserSpecified
32
+ autosuggestionsConfigUserSpecified,
36
33
  );
37
34
 
38
35
  const autosuggestionsFunction = useMakeStandardAutosuggestionFunction(
39
36
  autosuggestionsConfig.textareaPurpose,
40
37
  autosuggestionsConfig.contextCategories,
41
- autosuggestionsConfig.chatApiConfigs.suggestionsApiConfig
38
+ autosuggestionsConfig.chatApiConfigs.suggestionsApiConfig,
42
39
  );
43
40
 
44
- const insertionOrEditingFunction =
45
- useMakeStandardInsertionOrEditingFunction(
46
- autosuggestionsConfig.textareaPurpose,
47
- autosuggestionsConfig.contextCategories,
48
- autosuggestionsConfig.chatApiConfigs.insertionApiConfig,
49
- autosuggestionsConfig.chatApiConfigs.editingApiConfig
50
- );
41
+ const insertionOrEditingFunction = useMakeStandardInsertionOrEditingFunction(
42
+ autosuggestionsConfig.textareaPurpose,
43
+ autosuggestionsConfig.contextCategories,
44
+ autosuggestionsConfig.chatApiConfigs.insertionApiConfig,
45
+ autosuggestionsConfig.chatApiConfigs.editingApiConfig,
46
+ );
51
47
 
52
48
  return (
53
49
  <>
@@ -64,5 +60,5 @@ export const CopilotTextarea = React.forwardRef(
64
60
  />
65
61
  </>
66
62
  );
67
- }
63
+ },
68
64
  );
@@ -10,14 +10,16 @@ const HoveringEditorContext = createContext<HoveringEditorContextProps>({
10
10
  setIsDisplayed: () => {},
11
11
  });
12
12
 
13
- interface HoveringEditorProviderProps {
13
+ export interface HoveringEditorProviderProps {
14
14
  children: ReactNode;
15
15
  }
16
16
 
17
- export const HoveringEditorProvider = ({
18
- children,
19
- }: HoveringEditorProviderProps) => {
20
- const [isDisplayed, setIsDisplayed] = useState(false);
17
+ /**
18
+ * A context provider for the hovering editor over the `CopilotTextarea`
19
+ * (used to edit and insert text into the `CopilotTextarea`).
20
+ */
21
+ export const HoveringEditorProvider: React.FC<HoveringEditorProviderProps> = ({ children }) => {
22
+ const [isDisplayed, setIsDisplayed] = useState<boolean>(false);
21
23
 
22
24
  return (
23
25
  <HoveringEditorContext.Provider value={{ isDisplayed, setIsDisplayed }}>
@@ -20,7 +20,7 @@ export const Button = React.forwardRef(
20
20
  reversed: boolean;
21
21
  } & BaseProps
22
22
  >,
23
- ref: Ref<HTMLSpanElement | null>
23
+ ref: Ref<HTMLSpanElement | null>,
24
24
  ) => (
25
25
  <span
26
26
  {...props}
@@ -29,24 +29,15 @@ export const Button = React.forwardRef(
29
29
  className,
30
30
  css`
31
31
  cursor: pointer;
32
- color: ${reversed
33
- ? active
34
- ? "white"
35
- : "#aaa"
36
- : active
37
- ? "black"
38
- : "#ccc"};
39
- `
32
+ color: ${reversed ? (active ? "white" : "#aaa") : active ? "black" : "#ccc"};
33
+ `,
40
34
  )}
41
35
  />
42
- )
36
+ ),
43
37
  );
44
38
 
45
39
  export const Icon = React.forwardRef(
46
- (
47
- { className, ...props }: PropsWithChildren<BaseProps>,
48
- ref: Ref<HTMLSpanElement | null>
49
- ) => (
40
+ ({ className, ...props }: PropsWithChildren<BaseProps>, ref: Ref<HTMLSpanElement | null>) => (
50
41
  <span
51
42
  {...props}
52
43
  ref={ref as Ref<HTMLSpanElement>}
@@ -56,17 +47,14 @@ export const Icon = React.forwardRef(
56
47
  css`
57
48
  font-size: 18px;
58
49
  vertical-align: text-bottom;
59
- `
50
+ `,
60
51
  )}
61
52
  />
62
- )
53
+ ),
63
54
  );
64
55
 
65
56
  export const Menu = React.forwardRef(
66
- (
67
- { className, ...props }: PropsWithChildren<BaseProps>,
68
- ref: Ref<HTMLDivElement | null>
69
- ) => (
57
+ ({ className, ...props }: PropsWithChildren<BaseProps>, ref: Ref<HTMLDivElement | null>) => (
70
58
  <div
71
59
  {...props}
72
60
  data-test-id="menu"
@@ -81,22 +69,17 @@ export const Menu = React.forwardRef(
81
69
  & > * + * {
82
70
  margin-left: 15px;
83
71
  }
84
- `
72
+ `,
85
73
  )}
86
74
  />
87
- )
75
+ ),
88
76
  );
89
77
  export const Portal = ({ children }: { children: React.ReactNode }) => {
90
- return typeof document === "object"
91
- ? ReactDOM.createPortal(children, document.body)
92
- : null;
78
+ return typeof document === "object" ? ReactDOM.createPortal(children, document.body) : null;
93
79
  };
94
80
 
95
81
  export const Toolbar = React.forwardRef(
96
- (
97
- { className, ...props }: PropsWithChildren<BaseProps>,
98
- ref?: Ref<HTMLDivElement>
99
- ) => (
82
+ ({ className, ...props }: PropsWithChildren<BaseProps>, ref?: Ref<HTMLDivElement>) => (
100
83
  <Menu
101
84
  {...props}
102
85
  ref={ref}
@@ -108,8 +91,8 @@ export const Toolbar = React.forwardRef(
108
91
  margin: 0 -20px;
109
92
  border-bottom: 2px solid #eee;
110
93
  margin-bottom: 20px;
111
- `
94
+ `,
112
95
  )}
113
96
  />
114
- )
97
+ ),
115
98
  );
@@ -20,9 +20,7 @@ export interface HoveringToolbarProps {
20
20
  hoverMenuClassname: string | undefined;
21
21
  }
22
22
 
23
- export const HoveringToolbar: (
24
- props: HoveringToolbarProps
25
- ) => JSX.Element | null = (props) => {
23
+ export const HoveringToolbar: (props: HoveringToolbarProps) => JSX.Element | null = (props) => {
26
24
  const ref = useRef<HTMLDivElement>(null);
27
25
  const editor = useSlate();
28
26
  const selection = useSlateSelection();
@@ -59,20 +57,14 @@ export const HoveringToolbar: (
59
57
  // but inside the hovering window.
60
58
  //
61
59
  // in such case, we simply do nothing.
62
- if (
63
- rect.top === 0 &&
64
- rect.left === 0 &&
65
- rect.width === 0 &&
66
- rect.height === 0
67
- ) {
60
+ if (rect.top === 0 && rect.left === 0 && rect.width === 0 && rect.height === 0) {
68
61
  return;
69
62
  }
70
63
 
71
64
  const minGapFromEdge = 60;
72
65
  const verticalOffsetFromCorner = 35;
73
66
  const horizontalOffsetFromCorner = 15;
74
- let top =
75
- rect.top + window.scrollY - el.offsetHeight + verticalOffsetFromCorner;
67
+ let top = rect.top + window.scrollY - el.offsetHeight + verticalOffsetFromCorner;
76
68
  // make sure top is in the viewport and not too close to the edge
77
69
  if (top < minGapFromEdge) {
78
70
  top = rect.bottom + window.scrollY + minGapFromEdge;
@@ -81,11 +73,7 @@ export const HoveringToolbar: (
81
73
  }
82
74
 
83
75
  let left =
84
- rect.left +
85
- window.scrollX -
86
- el.offsetWidth / 2 +
87
- rect.width / 2 +
88
- horizontalOffsetFromCorner;
76
+ rect.left + window.scrollX - el.offsetWidth / 2 + rect.width / 2 + horizontalOffsetFromCorner;
89
77
  // make sure left is in the viewport and not too close to the edge
90
78
  if (left < minGapFromEdge) {
91
79
  left = minGapFromEdge;
@@ -8,13 +8,7 @@ import { SourceSearchBox } from "../../source-search-box/source-search-box";
8
8
  import { DocumentPointer } from "@copilotkit/react-core";
9
9
  import { Button } from "../../ui/button";
10
10
  import { Label } from "../../ui/label";
11
- import React, {
12
- useCallback,
13
- useContext,
14
- useEffect,
15
- useRef,
16
- useState,
17
- } from "react";
11
+ import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
18
12
 
19
13
  import { streamPromiseFlatten } from "../../../lib/stream-promise-flatten";
20
14
  import { CopilotContext } from "@copilotkit/react-core";
@@ -31,9 +25,7 @@ export interface HoveringInsertionPromptBoxCoreProps {
31
25
  contextCategories: string[];
32
26
  }
33
27
 
34
- export const HoveringInsertionPromptBoxCore: React.FC<
35
- HoveringInsertionPromptBoxCoreProps
36
- > = ({
28
+ export const HoveringInsertionPromptBoxCore: React.FC<HoveringInsertionPromptBoxCoreProps> = ({
37
29
  performInsertion,
38
30
  state,
39
31
  insertionOrEditingFunction,
@@ -42,13 +34,13 @@ export const HoveringInsertionPromptBoxCore: React.FC<
42
34
  const { getDocumentsContext } = useContext(CopilotContext);
43
35
 
44
36
  const [editSuggestion, setEditSuggestion] = useState<string>("");
45
- const [suggestionIsLoading, setSuggestionIsLoading] =
46
- useState<boolean>(false);
37
+ const [suggestionIsLoading, setSuggestionIsLoading] = useState<boolean>(false);
47
38
 
48
39
  const [adjustmentPrompt, setAdjustmentPrompt] = useState<string>("");
49
40
 
50
- const [generatingSuggestion, setGeneratingSuggestion] =
51
- useState<ReadableStream<string> | null>(null);
41
+ const [generatingSuggestion, setGeneratingSuggestion] = useState<ReadableStream<string> | null>(
42
+ null,
43
+ );
52
44
 
53
45
  const adjustmentTextAreaRef = useRef<HTMLTextAreaElement>(null);
54
46
  const suggestionTextAreaRef = useRef<HTMLTextAreaElement>(null);
@@ -97,8 +89,7 @@ export const HoveringInsertionPromptBoxCore: React.FC<
97
89
 
98
90
  // Scroll to the bottom of the textarea. We call this here to make sure scroll-to-bottom is synchronous with the state update.
99
91
  if (suggestionTextAreaRef.current) {
100
- suggestionTextAreaRef.current.scrollTop =
101
- suggestionTextAreaRef.current.scrollHeight;
92
+ suggestionTextAreaRef.current.scrollTop = suggestionTextAreaRef.current.scrollHeight;
102
93
  }
103
94
  return newSuggestion;
104
95
  });
@@ -141,10 +132,10 @@ export const HoveringInsertionPromptBoxCore: React.FC<
141
132
  modificationState,
142
133
  adjustmentPrompt,
143
134
  filePointers,
144
- new AbortController().signal
135
+ new AbortController().signal,
145
136
  );
146
137
  const adjustmentSuggestionTextStream = streamPromiseFlatten(
147
- adjustmentSuggestionTextStreamPromise
138
+ adjustmentSuggestionTextStreamPromise,
148
139
  );
149
140
 
150
141
  setGeneratingSuggestion(adjustmentSuggestionTextStream);
@@ -255,19 +246,14 @@ export const HoveringInsertionPromptBoxCore: React.FC<
255
246
  <div className="w-full flex flex-col items-start relative gap-2">
256
247
  {AdjustmentPromptComponent}
257
248
  {filePointers.length > 0 && (
258
- <IncludedFilesPreview
259
- includedFiles={filePointers}
260
- setIncludedFiles={setFilePointers}
261
- />
249
+ <IncludedFilesPreview includedFiles={filePointers} setIncludedFiles={setFilePointers} />
262
250
  )}
263
251
  {sourceSearchWord !== undefined && (
264
252
  <SourceSearchBox
265
253
  searchTerm={sourceSearchWord}
266
254
  suggestedFiles={suggestedFiles}
267
255
  onSelectedFile={(filePointer) => {
268
- setAdjustmentPrompt(
269
- adjustmentPrompt.replace(new RegExp(`@${sourceSearchWord}$`), "")
270
- );
256
+ setAdjustmentPrompt(adjustmentPrompt.replace(new RegExp(`@${sourceSearchWord}$`), ""));
271
257
  setFilePointers((prev) => [...prev, filePointer]);
272
258
 
273
259
  // focus back on the adjustment prompt, and move the cursor to the end
@@ -23,9 +23,7 @@ export const IncludedFilesPreview: React.FC<IncludedFilesPreviewProps> = ({
23
23
  key={`file-${filePointer.sourceApplication}.${filePointer.name}`}
24
24
  filePointer={filePointer}
25
25
  onDelete={() => {
26
- setIncludedFiles((prev) =>
27
- prev.filter((fp) => fp !== filePointer)
28
- );
26
+ setIncludedFiles((prev) => prev.filter((fp) => fp !== filePointer));
29
27
  }}
30
28
  />
31
29
  );
@@ -40,10 +38,7 @@ export interface FileChipPreviewProp {
40
38
  onDelete: () => void;
41
39
  }
42
40
 
43
- export const FileChipPreview: React.FC<FileChipPreviewProp> = ({
44
- filePointer,
45
- onDelete,
46
- }) => {
41
+ export const FileChipPreview: React.FC<FileChipPreviewProp> = ({ filePointer, onDelete }) => {
47
42
  return (
48
43
  <Chip
49
44
  label={filePointer.name}
@@ -6,21 +6,12 @@ export interface ChipWithIconProps {
6
6
  iconUrl: string;
7
7
  }
8
8
 
9
- export const ChipWithIcon: React.FC<ChipWithIconProps> = ({
10
- label,
11
- onDelete,
12
- iconUrl,
13
- }) => {
9
+ export const ChipWithIcon: React.FC<ChipWithIconProps> = ({ label, onDelete, iconUrl }) => {
14
10
  return (
15
11
  <span className="inline-flex items-center px-3 py-1 rounded-full bg-slate-200 text-sm font-medium text-white">
16
- {iconUrl && (
17
- <img src={iconUrl} alt="icon" className="w-4 h-4 rounded-full mr-2" />
18
- )}
12
+ {iconUrl && <img src={iconUrl} alt="icon" className="w-4 h-4 rounded-full mr-2" />}
19
13
  {label}
20
- <button
21
- className="ml-2 text-white hover:text-gray-200 focus:outline-none"
22
- onClick={onDelete}
23
- >
14
+ <button className="ml-2 text-white hover:text-gray-200 focus:outline-none" onClick={onDelete}>
24
15
  x
25
16
  </button>
26
17
  </span>
@@ -11,14 +11,7 @@ import {
11
11
  CommandShortcut,
12
12
  } from "../ui/command";
13
13
 
14
- import {
15
- Calculator,
16
- Calendar,
17
- CreditCard,
18
- Settings,
19
- Smile,
20
- User,
21
- } from "lucide-react";
14
+ import { Calculator, Calendar, CreditCard, Settings, Smile, User } from "lucide-react";
22
15
 
23
16
  import { DocumentPointer } from "@copilotkit/react-core";
24
17
 
@@ -117,10 +110,7 @@ export function Logo({
117
110
  height: string;
118
111
  }) {
119
112
  return (
120
- <div
121
- className="flex items-center justify-center"
122
- style={{ width: width, height: height }}
123
- >
113
+ <div className="flex items-center justify-center" style={{ width: width, height: height }}>
124
114
  {children}
125
115
  </div>
126
116
  );
@@ -10,12 +10,9 @@ const buttonVariants = cva(
10
10
  variants: {
11
11
  variant: {
12
12
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
- destructive:
14
- "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15
- outline:
16
- "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17
- secondary:
18
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
13
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
14
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
15
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
16
  ghost: "hover:bg-accent hover:text-accent-foreground",
20
17
  link: "text-primary underline-offset-4 hover:underline",
21
18
  },
@@ -30,7 +27,7 @@ const buttonVariants = cva(
30
27
  variant: "default",
31
28
  size: "default",
32
29
  },
33
- }
30
+ },
34
31
  );
35
32
 
36
33
  export interface ButtonProps
@@ -43,13 +40,9 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43
40
  ({ className, variant, size, asChild = false, ...props }, ref) => {
44
41
  const Comp = asChild ? Slot : "button";
45
42
  return (
46
- <Comp
47
- className={cn(buttonVariants({ variant, size, className }))}
48
- ref={ref}
49
- {...props}
50
- />
43
+ <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
51
44
  );
52
- }
45
+ },
53
46
  );
54
47
  Button.displayName = "Button";
55
48
 
@@ -2,85 +2,55 @@ import * as React from "react";
2
2
 
3
3
  import { cn } from "../../lib/utils";
4
4
 
5
- const Card = React.forwardRef<
6
- HTMLDivElement,
7
- React.HTMLAttributes<HTMLDivElement>
8
- >(({ className, ...props }, ref) => (
9
- <div
10
- ref={ref}
11
- className={cn(
12
- "rounded-lg border bg-card text-card-foreground shadow-sm",
13
- className
14
- )}
15
- {...props}
16
- />
17
- ));
5
+ const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
6
+ ({ className, ...props }, ref) => (
7
+ <div
8
+ ref={ref}
9
+ className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
10
+ {...props}
11
+ />
12
+ ),
13
+ );
18
14
  Card.displayName = "Card";
19
15
 
20
- const CardHeader = React.forwardRef<
21
- HTMLDivElement,
22
- React.HTMLAttributes<HTMLDivElement>
23
- >(({ className, ...props }, ref) => (
24
- <div
25
- ref={ref}
26
- className={cn("flex flex-col space-y-1.5 p-6", className)}
27
- {...props}
28
- />
29
- ));
16
+ const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
17
+ ({ className, ...props }, ref) => (
18
+ <div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
19
+ ),
20
+ );
30
21
  CardHeader.displayName = "CardHeader";
31
22
 
32
- const CardTitle = React.forwardRef<
33
- HTMLParagraphElement,
34
- React.HTMLAttributes<HTMLHeadingElement>
35
- >(({ className, ...props }, ref) => (
36
- <h3
37
- ref={ref}
38
- className={cn(
39
- "text-2xl font-semibold leading-none tracking-tight",
40
- className
41
- )}
42
- {...props}
43
- />
44
- ));
23
+ const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
24
+ ({ className, ...props }, ref) => (
25
+ <h3
26
+ ref={ref}
27
+ className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
28
+ {...props}
29
+ />
30
+ ),
31
+ );
45
32
  CardTitle.displayName = "CardTitle";
46
33
 
47
34
  const CardDescription = React.forwardRef<
48
35
  HTMLParagraphElement,
49
36
  React.HTMLAttributes<HTMLParagraphElement>
50
37
  >(({ className, ...props }, ref) => (
51
- <p
52
- ref={ref}
53
- className={cn("text-sm text-muted-foreground", className)}
54
- {...props}
55
- />
38
+ <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
56
39
  ));
57
40
  CardDescription.displayName = "CardDescription";
58
41
 
59
- const CardContent = React.forwardRef<
60
- HTMLDivElement,
61
- React.HTMLAttributes<HTMLDivElement>
62
- >(({ className, ...props }, ref) => (
63
- <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
64
- ));
42
+ const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
43
+ ({ className, ...props }, ref) => (
44
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
45
+ ),
46
+ );
65
47
  CardContent.displayName = "CardContent";
66
48
 
67
- const CardFooter = React.forwardRef<
68
- HTMLDivElement,
69
- React.HTMLAttributes<HTMLDivElement>
70
- >(({ className, ...props }, ref) => (
71
- <div
72
- ref={ref}
73
- className={cn("flex items-center p-6 pt-0", className)}
74
- {...props}
75
- />
76
- ));
49
+ const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
50
+ ({ className, ...props }, ref) => (
51
+ <div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
52
+ ),
53
+ );
77
54
  CardFooter.displayName = "CardFooter";
78
55
 
79
- export {
80
- Card,
81
- CardHeader,
82
- CardFooter,
83
- CardTitle,
84
- CardDescription,
85
- CardContent,
86
- };
56
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };