@lark-apaas/coding-templates 0.1.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 (216) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +128 -0
  3. package/meta.json +22 -0
  4. package/package.json +22 -0
  5. package/template-html/README.md +148 -0
  6. package/template-html/_gitignore +2 -0
  7. package/template-html/index.html +22 -0
  8. package/template-html/package.json +12 -0
  9. package/template-html/routes.json +1 -0
  10. package/template-html/scripts/build.sh +31 -0
  11. package/template-nextjs-fullstack/README.md +169 -0
  12. package/template-nextjs-fullstack/_env.local.example +1 -0
  13. package/template-nextjs-fullstack/_gitignore +41 -0
  14. package/template-nextjs-fullstack/components.json +25 -0
  15. package/template-nextjs-fullstack/drizzle.config.ts +10 -0
  16. package/template-nextjs-fullstack/eslint.config.js +15 -0
  17. package/template-nextjs-fullstack/next.config.ts +5 -0
  18. package/template-nextjs-fullstack/package.json +85 -0
  19. package/template-nextjs-fullstack/postcss.config.js +8 -0
  20. package/template-nextjs-fullstack/scripts/build.sh +37 -0
  21. package/template-nextjs-fullstack/src/app/favicon.ico +0 -0
  22. package/template-nextjs-fullstack/src/app/globals.css +130 -0
  23. package/template-nextjs-fullstack/src/app/layout.tsx +24 -0
  24. package/template-nextjs-fullstack/src/app/page.tsx +69 -0
  25. package/template-nextjs-fullstack/src/app/todos/actions.ts +37 -0
  26. package/template-nextjs-fullstack/src/app/todos/page.tsx +26 -0
  27. package/template-nextjs-fullstack/src/app/todos/todo-form.tsx +27 -0
  28. package/template-nextjs-fullstack/src/app/todos/todo-list.tsx +44 -0
  29. package/template-nextjs-fullstack/src/components/header.tsx +32 -0
  30. package/template-nextjs-fullstack/src/components/theme-provider.tsx +8 -0
  31. package/template-nextjs-fullstack/src/components/ui/README.md +134 -0
  32. package/template-nextjs-fullstack/src/components/ui/accordion.tsx +66 -0
  33. package/template-nextjs-fullstack/src/components/ui/alert-dialog.tsx +157 -0
  34. package/template-nextjs-fullstack/src/components/ui/alert.tsx +71 -0
  35. package/template-nextjs-fullstack/src/components/ui/aspect-ratio.tsx +11 -0
  36. package/template-nextjs-fullstack/src/components/ui/avatar.tsx +53 -0
  37. package/template-nextjs-fullstack/src/components/ui/badge.tsx +42 -0
  38. package/template-nextjs-fullstack/src/components/ui/breadcrumb.tsx +109 -0
  39. package/template-nextjs-fullstack/src/components/ui/button-group.tsx +83 -0
  40. package/template-nextjs-fullstack/src/components/ui/button.tsx +69 -0
  41. package/template-nextjs-fullstack/src/components/ui/calendar.tsx +213 -0
  42. package/template-nextjs-fullstack/src/components/ui/card.tsx +82 -0
  43. package/template-nextjs-fullstack/src/components/ui/carousel.tsx +241 -0
  44. package/template-nextjs-fullstack/src/components/ui/chart.tsx +357 -0
  45. package/template-nextjs-fullstack/src/components/ui/checkbox.tsx +32 -0
  46. package/template-nextjs-fullstack/src/components/ui/collapsible.tsx +33 -0
  47. package/template-nextjs-fullstack/src/components/ui/command.tsx +208 -0
  48. package/template-nextjs-fullstack/src/components/ui/context-menu.tsx +324 -0
  49. package/template-nextjs-fullstack/src/components/ui/dialog.tsx +143 -0
  50. package/template-nextjs-fullstack/src/components/ui/drawer.tsx +135 -0
  51. package/template-nextjs-fullstack/src/components/ui/dropdown-menu.tsx +329 -0
  52. package/template-nextjs-fullstack/src/components/ui/empty.tsx +104 -0
  53. package/template-nextjs-fullstack/src/components/ui/field.tsx +248 -0
  54. package/template-nextjs-fullstack/src/components/ui/form.tsx +167 -0
  55. package/template-nextjs-fullstack/src/components/ui/hover-card.tsx +44 -0
  56. package/template-nextjs-fullstack/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  57. package/template-nextjs-fullstack/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  58. package/template-nextjs-fullstack/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  59. package/template-nextjs-fullstack/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  60. package/template-nextjs-fullstack/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  61. package/template-nextjs-fullstack/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  62. package/template-nextjs-fullstack/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  63. package/template-nextjs-fullstack/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  64. package/template-nextjs-fullstack/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  65. package/template-nextjs-fullstack/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  66. package/template-nextjs-fullstack/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  67. package/template-nextjs-fullstack/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  68. package/template-nextjs-fullstack/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  69. package/template-nextjs-fullstack/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  70. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  71. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  72. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  73. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  74. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  75. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  76. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  77. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  78. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  79. package/template-nextjs-fullstack/src/components/ui/image.tsx +183 -0
  80. package/template-nextjs-fullstack/src/components/ui/input-group.tsx +166 -0
  81. package/template-nextjs-fullstack/src/components/ui/input-otp.tsx +77 -0
  82. package/template-nextjs-fullstack/src/components/ui/input.tsx +21 -0
  83. package/template-nextjs-fullstack/src/components/ui/item.tsx +193 -0
  84. package/template-nextjs-fullstack/src/components/ui/kbd.tsx +28 -0
  85. package/template-nextjs-fullstack/src/components/ui/label.tsx +24 -0
  86. package/template-nextjs-fullstack/src/components/ui/menubar.tsx +348 -0
  87. package/template-nextjs-fullstack/src/components/ui/native-select.tsx +48 -0
  88. package/template-nextjs-fullstack/src/components/ui/navigation-menu.tsx +168 -0
  89. package/template-nextjs-fullstack/src/components/ui/pagination.tsx +127 -0
  90. package/template-nextjs-fullstack/src/components/ui/popover.tsx +48 -0
  91. package/template-nextjs-fullstack/src/components/ui/progress.tsx +31 -0
  92. package/template-nextjs-fullstack/src/components/ui/radio-group.tsx +45 -0
  93. package/template-nextjs-fullstack/src/components/ui/resizable.tsx +56 -0
  94. package/template-nextjs-fullstack/src/components/ui/scroll-area.tsx +58 -0
  95. package/template-nextjs-fullstack/src/components/ui/select.tsx +243 -0
  96. package/template-nextjs-fullstack/src/components/ui/separator.tsx +28 -0
  97. package/template-nextjs-fullstack/src/components/ui/sheet.tsx +139 -0
  98. package/template-nextjs-fullstack/src/components/ui/sidebar.tsx +727 -0
  99. package/template-nextjs-fullstack/src/components/ui/skeleton.tsx +13 -0
  100. package/template-nextjs-fullstack/src/components/ui/slider.tsx +87 -0
  101. package/template-nextjs-fullstack/src/components/ui/sonner.tsx +67 -0
  102. package/template-nextjs-fullstack/src/components/ui/spinner.tsx +16 -0
  103. package/template-nextjs-fullstack/src/components/ui/streamdown.tsx +186 -0
  104. package/template-nextjs-fullstack/src/components/ui/switch.tsx +31 -0
  105. package/template-nextjs-fullstack/src/components/ui/table.tsx +116 -0
  106. package/template-nextjs-fullstack/src/components/ui/tabs.tsx +66 -0
  107. package/template-nextjs-fullstack/src/components/ui/textarea.tsx +18 -0
  108. package/template-nextjs-fullstack/src/components/ui/toggle-group.tsx +83 -0
  109. package/template-nextjs-fullstack/src/components/ui/toggle.tsx +47 -0
  110. package/template-nextjs-fullstack/src/components/ui/tooltip.tsx +61 -0
  111. package/template-nextjs-fullstack/src/db/index.ts +8 -0
  112. package/template-nextjs-fullstack/src/db/schema.ts +11 -0
  113. package/template-nextjs-fullstack/src/hooks/use-mobile.ts +19 -0
  114. package/template-nextjs-fullstack/src/lib/utils.ts +6 -0
  115. package/template-nextjs-fullstack/tailwind.config.ts +10 -0
  116. package/template-nextjs-fullstack/tsconfig.json +34 -0
  117. package/template-nextjs-static/README.md +80 -0
  118. package/template-nextjs-static/_gitignore +41 -0
  119. package/template-nextjs-static/components.json +25 -0
  120. package/template-nextjs-static/eslint.config.js +15 -0
  121. package/template-nextjs-static/next.config.ts +8 -0
  122. package/template-nextjs-static/package.json +77 -0
  123. package/template-nextjs-static/postcss.config.js +8 -0
  124. package/template-nextjs-static/public/favicon.ico +0 -0
  125. package/template-nextjs-static/scripts/build.sh +36 -0
  126. package/template-nextjs-static/src/components/header.tsx +30 -0
  127. package/template-nextjs-static/src/components/theme-provider.tsx +6 -0
  128. package/template-nextjs-static/src/components/ui/README.md +134 -0
  129. package/template-nextjs-static/src/components/ui/accordion.tsx +66 -0
  130. package/template-nextjs-static/src/components/ui/alert-dialog.tsx +157 -0
  131. package/template-nextjs-static/src/components/ui/alert.tsx +71 -0
  132. package/template-nextjs-static/src/components/ui/aspect-ratio.tsx +11 -0
  133. package/template-nextjs-static/src/components/ui/avatar.tsx +53 -0
  134. package/template-nextjs-static/src/components/ui/badge.tsx +42 -0
  135. package/template-nextjs-static/src/components/ui/breadcrumb.tsx +109 -0
  136. package/template-nextjs-static/src/components/ui/button-group.tsx +83 -0
  137. package/template-nextjs-static/src/components/ui/button.tsx +69 -0
  138. package/template-nextjs-static/src/components/ui/calendar.tsx +213 -0
  139. package/template-nextjs-static/src/components/ui/card.tsx +82 -0
  140. package/template-nextjs-static/src/components/ui/carousel.tsx +241 -0
  141. package/template-nextjs-static/src/components/ui/chart.tsx +357 -0
  142. package/template-nextjs-static/src/components/ui/checkbox.tsx +32 -0
  143. package/template-nextjs-static/src/components/ui/collapsible.tsx +33 -0
  144. package/template-nextjs-static/src/components/ui/command.tsx +208 -0
  145. package/template-nextjs-static/src/components/ui/context-menu.tsx +324 -0
  146. package/template-nextjs-static/src/components/ui/dialog.tsx +143 -0
  147. package/template-nextjs-static/src/components/ui/drawer.tsx +135 -0
  148. package/template-nextjs-static/src/components/ui/dropdown-menu.tsx +329 -0
  149. package/template-nextjs-static/src/components/ui/empty.tsx +104 -0
  150. package/template-nextjs-static/src/components/ui/field.tsx +248 -0
  151. package/template-nextjs-static/src/components/ui/form.tsx +167 -0
  152. package/template-nextjs-static/src/components/ui/hover-card.tsx +44 -0
  153. package/template-nextjs-static/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  154. package/template-nextjs-static/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  155. package/template-nextjs-static/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  156. package/template-nextjs-static/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  157. package/template-nextjs-static/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  158. package/template-nextjs-static/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  159. package/template-nextjs-static/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  160. package/template-nextjs-static/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  161. package/template-nextjs-static/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  162. package/template-nextjs-static/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  163. package/template-nextjs-static/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  164. package/template-nextjs-static/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  165. package/template-nextjs-static/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  166. package/template-nextjs-static/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  167. package/template-nextjs-static/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  168. package/template-nextjs-static/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  169. package/template-nextjs-static/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  170. package/template-nextjs-static/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  171. package/template-nextjs-static/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  172. package/template-nextjs-static/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  173. package/template-nextjs-static/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  174. package/template-nextjs-static/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  175. package/template-nextjs-static/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  176. package/template-nextjs-static/src/components/ui/image.tsx +183 -0
  177. package/template-nextjs-static/src/components/ui/input-group.tsx +166 -0
  178. package/template-nextjs-static/src/components/ui/input-otp.tsx +77 -0
  179. package/template-nextjs-static/src/components/ui/input.tsx +21 -0
  180. package/template-nextjs-static/src/components/ui/item.tsx +193 -0
  181. package/template-nextjs-static/src/components/ui/kbd.tsx +28 -0
  182. package/template-nextjs-static/src/components/ui/label.tsx +24 -0
  183. package/template-nextjs-static/src/components/ui/menubar.tsx +348 -0
  184. package/template-nextjs-static/src/components/ui/native-select.tsx +48 -0
  185. package/template-nextjs-static/src/components/ui/navigation-menu.tsx +168 -0
  186. package/template-nextjs-static/src/components/ui/pagination.tsx +127 -0
  187. package/template-nextjs-static/src/components/ui/popover.tsx +48 -0
  188. package/template-nextjs-static/src/components/ui/progress.tsx +31 -0
  189. package/template-nextjs-static/src/components/ui/radio-group.tsx +45 -0
  190. package/template-nextjs-static/src/components/ui/resizable.tsx +56 -0
  191. package/template-nextjs-static/src/components/ui/scroll-area.tsx +58 -0
  192. package/template-nextjs-static/src/components/ui/select.tsx +243 -0
  193. package/template-nextjs-static/src/components/ui/separator.tsx +28 -0
  194. package/template-nextjs-static/src/components/ui/sheet.tsx +139 -0
  195. package/template-nextjs-static/src/components/ui/sidebar.tsx +727 -0
  196. package/template-nextjs-static/src/components/ui/skeleton.tsx +13 -0
  197. package/template-nextjs-static/src/components/ui/slider.tsx +87 -0
  198. package/template-nextjs-static/src/components/ui/sonner.tsx +67 -0
  199. package/template-nextjs-static/src/components/ui/spinner.tsx +16 -0
  200. package/template-nextjs-static/src/components/ui/streamdown.tsx +186 -0
  201. package/template-nextjs-static/src/components/ui/switch.tsx +31 -0
  202. package/template-nextjs-static/src/components/ui/table.tsx +116 -0
  203. package/template-nextjs-static/src/components/ui/tabs.tsx +66 -0
  204. package/template-nextjs-static/src/components/ui/textarea.tsx +18 -0
  205. package/template-nextjs-static/src/components/ui/toggle-group.tsx +83 -0
  206. package/template-nextjs-static/src/components/ui/toggle.tsx +47 -0
  207. package/template-nextjs-static/src/components/ui/tooltip.tsx +61 -0
  208. package/template-nextjs-static/src/hooks/use-mobile.ts +19 -0
  209. package/template-nextjs-static/src/lib/utils.ts +6 -0
  210. package/template-nextjs-static/src/pages/_app.tsx +11 -0
  211. package/template-nextjs-static/src/pages/_document.tsx +13 -0
  212. package/template-nextjs-static/src/pages/hello.tsx +32 -0
  213. package/template-nextjs-static/src/pages/index.tsx +76 -0
  214. package/template-nextjs-static/src/styles/globals.css +143 -0
  215. package/template-nextjs-static/tailwind.config.ts +10 -0
  216. package/template-nextjs-static/tsconfig.json +34 -0
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiImageColorfulIcon(
4
+ props: React.SVGProps<SVGSVGElement>,
5
+ ) {
6
+ return (
7
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
8
+ <path
9
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
10
+ fill="#FFC60A"
11
+ />
12
+ <path
13
+ opacity="0.8"
14
+ d="M15 1.48284C15 1.30466 15.2154 1.21543 15.3414 1.34142L20.6586 6.65858C20.7846 6.78457 20.6953 7 20.5172 7H17C15.8954 7 15 6.10457 15 5V1.48284Z"
15
+ fill="#D99904"
16
+ />
17
+ <path
18
+ d="M8.37168 10C7.81939 10 7.37168 10.4477 7.37168 11V11.1818C7.37168 11.7341 7.81939 12.1818 8.37168 12.1818H8.5535C9.10578 12.1818 9.5535 11.7341 9.5535 11.1818V11C9.5535 10.4477 9.10578 10 8.5535 10H8.37168Z"
19
+ fill="white"
20
+ />
21
+ <path
22
+ d="M16.6951 12.7598C17.0658 12.3594 17.7353 12.6217 17.7353 13.1675V18.5C17.7353 18.7761 17.5115 19 17.2353 19L7.40077 19C7.06108 19 6.876 18.6033 7.09423 18.343L10.0198 14.8533C10.4194 14.3765 11.1528 14.3765 11.5524 14.8533L13.075 16.6695L16.6951 12.7598Z"
23
+ fill="white"
24
+ />
25
+ </svg>
26
+ );
27
+ }
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiPdfColorfulIcon(props: React.SVGProps<SVGSVGElement>) {
4
+ return (
5
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
6
+ <path
7
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
8
+ fill="#F54A45"
9
+ />
10
+ <path
11
+ d="M15 1.48284C15 1.30466 15.2154 1.21543 15.3414 1.34142L20.6586 6.65858C20.7846 6.78457 20.6953 7 20.5172 7H17C15.8954 7 15 6.10457 15 5V1.48284Z"
12
+ fill="#C02A26"
13
+ />
14
+ <path
15
+ d="M17.5508 15.5512C17.3026 15.2606 16.7937 15.1194 15.9949 15.1194C15.5306 15.1194 14.891 15.131 14.2482 15.2264C12.4925 13.9607 12.081 12.6011 12.081 12.6011C12.081 12.6011 12.3809 11.8484 12.3999 10.6191C12.412 9.84198 12.2888 9.2624 11.9746 9.01323C11.8407 8.9071 11.6464 8.81836 11.4508 8.81836C11.2981 8.81836 11.1551 8.86258 11.0379 8.94711C10.1252 9.6056 11.1217 12.7099 11.1484 12.7926C10.7177 13.8377 10.1751 14.945 9.61664 15.918C9.43518 16.2341 9.43519 16.2402 9.31331 16.3837C9.31331 16.3837 7.71563 17.1761 6.96645 18.0546C6.54317 18.551 6.52943 18.8919 6.5519 19.1473C6.58812 19.4536 6.9786 19.7275 7.3717 19.7275C7.388 19.7275 7.40441 19.727 7.42048 19.726C7.81999 19.7017 8.26439 19.5917 8.75891 19.124C9.11691 18.7853 9.51949 17.8657 10.037 16.9658C11.5219 16.5493 12.8287 16.2526 13.9239 16.0835C14.727 16.5096 15.9219 16.9922 16.7352 16.9922C17.0081 16.9922 17.2276 16.9374 17.3876 16.8292C17.579 16.6999 17.6604 16.5387 17.7109 16.2402C17.7614 15.9418 17.6911 15.7154 17.5508 15.5512ZM15.8051 16.0184C16.5467 16.0184 16.9482 16.1492 17.1545 16.259C17.2181 16.2928 17.2644 16.3255 17.2972 16.3528C17.2391 16.3978 17.1248 16.4547 16.9181 16.4547C16.5755 16.4547 16.1258 16.3096 15.5773 16.0223C15.6553 16.0197 15.7313 16.0184 15.8051 16.0184ZM11.5458 9.47602L11.5471 9.47293C11.6629 9.5582 11.7169 10.157 11.7061 10.5043C11.6915 10.9702 11.688 11.1503 11.6295 11.4366C11.471 10.8397 11.4597 9.76694 11.5458 9.47602ZM11.5824 13.8366C11.9441 14.4323 12.4028 15.0357 12.9196 15.4964C11.9109 15.7126 11.0733 15.911 10.4706 16.122C11.1166 15.0032 11.54 13.9474 11.5824 13.8366ZM7.50945 18.8845C7.60073 18.7495 7.85011 18.4878 8.48254 17.982C8.14312 18.7639 7.76193 18.8845 7.40757 19.0729C7.43432 19.0109 7.46797 18.9458 7.50945 18.8845Z"
16
+ fill="white"
17
+ />
18
+ </svg>
19
+ );
20
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiPptColorfulIcon(props: React.SVGProps<SVGSVGElement>) {
4
+ return (
5
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
6
+ <path
7
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
8
+ fill="#FF811A"
9
+ />
10
+ <path
11
+ opacity="0.8"
12
+ d="M15 1.48284C15 1.30466 15.2154 1.21543 15.3414 1.34142L20.6586 6.65858C20.7846 6.78457 20.6953 7 20.5172 7H17C15.8954 7 15 6.10457 15 5V1.48284Z"
13
+ fill="#ED6D0C"
14
+ />
15
+ <path
16
+ d="M10.3828 18.4952V14.9087H12.0847C12.4937 14.9087 12.9007 14.8728 13.3055 14.8009C13.7179 14.7277 14.088 14.599 14.4152 14.4147C14.7482 14.2271 15.0198 13.9703 15.2285 13.6458C15.4405 13.3164 15.5452 12.9033 15.5452 12.4089C15.5452 12.0831 15.5013 11.7708 15.4134 11.4725C15.3228 11.1651 15.1629 10.8928 14.9347 10.6574C14.7055 10.4209 14.3974 10.2371 14.0123 10.1049C13.6308 9.97386 13.1526 9.90918 12.5769 9.90918H9.41376C9.33572 9.90918 9.27246 9.97244 9.27246 10.0505V18.4952C9.27246 18.5732 9.33572 18.6365 9.41376 18.6365H10.2415C10.3196 18.6365 10.3828 18.5732 10.3828 18.4952ZM13.1182 13.8731C12.8221 13.9188 12.4855 13.9417 12.1087 13.9417H10.3828V10.8762H12.3488C13.0952 10.8762 13.6309 11.0055 13.9567 11.2557C14.2753 11.5005 14.4348 11.8608 14.4348 12.3503C14.4348 12.6888 14.3811 12.9582 14.2767 13.1586C14.1727 13.3581 14.027 13.5143 13.8378 13.6293C13.6434 13.7475 13.4038 13.8291 13.1182 13.8731Z"
17
+ fill="white"
18
+ />
19
+ </svg>
20
+ );
21
+ }
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiTextColorfulIcon(props: React.SVGProps<SVGSVGElement>) {
4
+ return (
5
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
6
+ <path
7
+ d="M12.5455 10.7271V18.2271C12.5455 18.3025 12.4845 18.3635 12.4092 18.3635H11.591C11.5157 18.3635 11.4546 18.3025 11.4546 18.2271V10.7271H8.04554C7.97023 10.7271 7.90918 10.6661 7.90918 10.5908V9.77259C7.90918 9.69728 7.97023 9.63623 8.04554 9.63623H15.9546C16.0299 9.63623 16.091 9.69728 16.091 9.77259V10.5908C16.091 10.6661 16.0299 10.7271 15.9546 10.7271H12.5455Z"
8
+ fill="white"
9
+ />
10
+ </svg>
11
+ );
12
+ }
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiUnknownColorfulIcon(
4
+ props: React.SVGProps<SVGSVGElement>,
5
+ ) {
6
+ return (
7
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
8
+ <path
9
+ d="M14.288 9.86441C13.7422 9.34739 13.026 9.09082 12.1353 9.09082C11.1347 9.09082 10.3505 9.41162 9.78235 10.065C9.30108 10.6265 9.04179 11.1646 9.00471 12.013C9.00384 12.033 9.00309 12.0697 9.00247 12.1122C9.00043 12.2508 9.11287 12.3635 9.25147 12.3635H9.84253C9.98 12.3635 10.0914 12.2525 10.0936 12.1151C10.0943 12.0737 10.0951 12.038 10.0961 12.0189C10.1251 11.4328 10.278 11.1262 10.5508 10.7851C10.8953 10.3259 11.4006 10.0999 12.0943 10.0999C12.7134 10.0999 13.1776 10.2578 13.4979 10.5782C13.8033 10.8963 13.9625 11.3294 13.9625 11.8726C13.9625 12.2435 13.8281 12.5967 13.5549 12.948C13.4678 13.0568 13.3425 13.1862 12.9388 13.5899C12.3012 14.1474 11.9073 14.601 11.6993 15.0468C11.5282 15.3888 11.441 15.7775 11.441 16.1954V16.4772C11.441 16.6153 11.5529 16.7272 11.691 16.7272H12.2956C12.4336 16.7272 12.5456 16.6153 12.5456 16.4772V16.1954C12.5456 15.8413 12.6327 15.5237 12.8133 15.2141C12.9486 14.9841 13.1223 14.8038 13.4251 14.5389C14.0321 13.9897 14.3689 13.6625 14.5198 13.4705C14.8821 12.9923 15.0671 12.4446 15.0671 11.8454C15.0671 11.0185 14.8075 10.355 14.288 9.86441ZM11.7046 17.8181C11.5666 17.8181 11.4546 17.93 11.4546 18.0681V18.659C11.4546 18.7971 11.5666 18.909 11.7046 18.909H12.2956C12.4336 18.909 12.5456 18.7971 12.5456 18.659V18.0681C12.5456 17.93 12.4336 17.8181 12.2956 17.8181H11.7046Z"
10
+ fill="white"
11
+ />
12
+ </svg>
13
+ );
14
+ }
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiVideoColorfulIcon(
4
+ props: React.SVGProps<SVGSVGElement>,
5
+ ) {
6
+ return (
7
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
8
+ <path
9
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
10
+ fill="#336DF4"
11
+ />
12
+ <path
13
+ opacity="0.7"
14
+ d="M15 1.48287C15 1.30469 15.2154 1.21546 15.3414 1.34145L20.6586 6.65861C20.7846 6.7846 20.6953 7.00003 20.5172 7.00003H17C15.8954 7.00003 15 6.1046 15 5.00003V1.48287Z"
15
+ fill="#0442D2"
16
+ />
17
+ <path
18
+ d="M7 10.75C7 10.3358 7.33579 10 7.75 10H13C13.4142 10 13.75 10.3358 13.75 10.75V11.6406L14.8823 11.0037C15.3823 10.7225 16 11.0838 16 11.6574V15.0926C16 15.6662 15.3823 16.0275 14.8823 15.7463L13.75 15.1094V16C13.75 16.4142 13.4142 16.75 13 16.75H7.75C7.33579 16.75 7 16.4142 7 16V10.75ZM9.25 13C9.66421 13 10 12.6642 10 12.25C10 11.8358 9.66421 11.5 9.25 11.5C8.83579 11.5 8.5 11.8358 8.5 12.25C8.5 12.6642 8.83579 13 9.25 13Z"
19
+ fill="white"
20
+ />
21
+ </svg>
22
+ );
23
+ }
@@ -0,0 +1,38 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiWordColorfulIcon(props: React.SVGProps<SVGSVGElement>) {
4
+ return (
5
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
6
+ <path
7
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
8
+ fill="#336DF4"
9
+ />
10
+ <path
11
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
12
+ fill="#336DF4"
13
+ />
14
+ <path
15
+ opacity="0.7"
16
+ d="M15 1.48284C15 1.30466 15.2154 1.21543 15.3414 1.34142L20.6586 6.65858C20.7846 6.78457 20.6953 7 20.5172 7H17C15.8954 7 15 6.10457 15 5V1.48284Z"
17
+ fill="#0442D2"
18
+ />
19
+ <path
20
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
21
+ fill="#336DF4"
22
+ />
23
+ <path
24
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
25
+ fill="#336DF4"
26
+ />
27
+ <path
28
+ opacity="0.7"
29
+ d="M15 1.48284C15 1.30466 15.2154 1.21543 15.3414 1.34142L20.6586 6.65858C20.7846 6.78457 20.6953 7 20.5172 7H17C15.8954 7 15 6.10457 15 5V1.48284Z"
30
+ fill="#0442D2"
31
+ />
32
+ <path
33
+ d="M12.0043 12.2495L10.5297 17.706C10.5118 17.7722 10.4517 17.8182 10.3831 17.8182H9.51468C9.44677 17.8182 9.38711 17.7731 9.3686 17.7078L7.36907 10.6478C7.34622 10.5671 7.3931 10.4832 7.47377 10.4603C7.48723 10.4565 7.50116 10.4546 7.51515 10.4546H8.38612C8.45534 10.4546 8.51579 10.5014 8.53312 10.5684L9.956 16.0718L11.4336 10.5671C11.4514 10.5007 11.5116 10.4546 11.5803 10.4546H12.429C12.4978 10.4546 12.5579 10.5008 12.5757 10.5673L14.0438 16.0704L15.4663 10.5684C15.4837 10.5014 15.5441 10.4546 15.6133 10.4546H16.4843C16.5682 10.4546 16.6361 10.5226 16.6361 10.6064C16.6361 10.6204 16.6342 10.6343 16.6304 10.6478L14.6309 17.7078C14.6124 17.7731 14.5527 17.8182 14.4848 17.8182H13.6163C13.5476 17.8182 13.4875 17.7721 13.4697 17.7058L12.0043 12.2495Z"
34
+ fill="white"
35
+ />
36
+ </svg>
37
+ );
38
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+
3
+ export function FileWikiZipColorfulIcon(props: React.SVGProps<SVGSVGElement>) {
4
+ return (
5
+ <svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
6
+ <path
7
+ d="M3 3C3 1.89543 3.89543 1 5 1H14.5858C14.851 1 15.1054 1.10536 15.2929 1.29289L20.7071 6.70711C20.8946 6.89464 21 7.149 21 7.41421V21C21 22.1046 20.1046 23 19 23H5C3.89543 23 3 22.1046 3 21V3Z"
8
+ fill="#336DF4"
9
+ />
10
+ <path
11
+ opacity="0.7"
12
+ d="M15 1.48284C15 1.30466 15.2154 1.21543 15.3414 1.34142L20.6586 6.65858C20.7846 6.78457 20.6953 7 20.5172 7H17C15.8954 7 15 6.10457 15 5V1.48284Z"
13
+ fill="#0442D2"
14
+ />
15
+ <path
16
+ d="M15.4286 9.5C15.7442 9.5 16 9.75184 16 10.0625V17.9375C16 18.2482 15.7442 18.5 15.4286 18.5H8.57143C8.25584 18.5 8 18.2482 8 17.9375V10.0625C8 9.75184 8.25584 9.5 8.57143 9.5H15.4286ZM13.1429 15.6875H10.8571V17.6562H13.1429V15.6875ZM12.5714 16.25V16.9009H11.4286V16.25H12.5714ZM13.1692 11.75H12V12.875H10.8571V14H12V15.125H13.1692V14H12.0264V12.875H13.1692V11.75ZM12 10.625H10.8571V11.75H12V10.625Z"
17
+ fill="white"
18
+ />
19
+ </svg>
20
+ );
21
+ }
@@ -0,0 +1,183 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { cn } from '@/lib/utils';
5
+ type ImageFormat = 'jpg' | 'png' | 'webp' | 'bmp' | 'gif' | 'tiff';
6
+
7
+ type NativeImgProps = React.ComponentPropsWithoutRef<'img'>;
8
+
9
+ export interface ImageProps extends NativeImgProps {
10
+ quality?: number;
11
+ format?: ImageFormat;
12
+ breakpoints?: Array<number>;
13
+ }
14
+
15
+ const DEFAULT_QUALITY = 80;
16
+ const DEFAULT_RESOLUTIONS: number[] = [
17
+ 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048,
18
+ 3840,
19
+ ];
20
+
21
+ const SRC_ALLOWLIST = [
22
+ '/runtime/api/v1/storage/object/',
23
+ '/aily/api/v1/feisuda/attachments/',
24
+ '/aily/api/v1/files/static/',
25
+ ];
26
+
27
+ function getClosestResolution(target: number): number {
28
+ return DEFAULT_RESOLUTIONS.reduce((prev, curr) => {
29
+ return Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev;
30
+ });
31
+ }
32
+
33
+ function applyParamsToUrl(
34
+ src: string,
35
+ params: Record<string, string | number | undefined>,
36
+ ): string {
37
+ const search = Object.entries(params)
38
+ .filter(([, v]) => v !== undefined && v !== null && v !== '')
39
+ .map(([k, v]) => {
40
+ return `${k},${v}`;
41
+ })
42
+ .join('/');
43
+ if (!search) return src;
44
+
45
+ const [pathAndQuery = '', hash] = src.split('#');
46
+ const [base, query] = pathAndQuery.split('?');
47
+ const urlParams = new URLSearchParams(query);
48
+ urlParams.set('x-tos-process', `image/${search}`);
49
+
50
+ return `${base}?${urlParams.toString()}${hash ? '#' + hash : ''}`;
51
+ }
52
+
53
+ function isTargetSrc(originSrc: string) {
54
+ return SRC_ALLOWLIST.some((item) => originSrc.includes(item));
55
+ }
56
+
57
+ function supportWebp() {
58
+ try {
59
+ return (
60
+ document
61
+ .createElement('canvas')
62
+ .toDataURL('image/webp')
63
+ .indexOf('data:image/webp') === 0
64
+ );
65
+ } catch (err) {
66
+ return false;
67
+ }
68
+ }
69
+
70
+ function buildSrcSet(
71
+ src: string,
72
+ widths: number[],
73
+ format: ImageFormat | undefined,
74
+ quality: number,
75
+ width?: number,
76
+ sizes?: string,
77
+ ): string | undefined {
78
+ if (!widths || widths.length === 0 || (!width && !sizes)) return undefined;
79
+ const fmt = format;
80
+ if (width) {
81
+ return [1, 2]
82
+ .map((dpr) => {
83
+ const targetWidth = getClosestResolution(width * dpr);
84
+ return `${applyParamsToUrl(src, { resize: `w_${targetWidth}`, quality: `Q_${quality}`, format: fmt })} ${dpr}x`;
85
+ })
86
+ .join(', ');
87
+ }
88
+ return widths
89
+ .map(
90
+ (w) =>
91
+ `${applyParamsToUrl(src, { resize: `w_${w}`, quality: `Q_${quality}`, format: fmt })} ${w}w`,
92
+ )
93
+ .join(', ');
94
+ }
95
+
96
+ export const Image = React.forwardRef<HTMLImageElement, ImageProps>(
97
+ (
98
+ {
99
+ src,
100
+ width,
101
+ height,
102
+ quality = DEFAULT_QUALITY,
103
+ format,
104
+ sizes,
105
+ srcSet: userSrcSet,
106
+ breakpoints = DEFAULT_RESOLUTIONS,
107
+ className,
108
+ loading = 'lazy',
109
+ decoding = 'async',
110
+ ...rest
111
+ },
112
+ ref,
113
+ ) => {
114
+ const defaultFormat = React.useMemo(
115
+ () => (supportWebp() ? 'webp' : undefined),
116
+ [],
117
+ );
118
+
119
+ // 当 src 不在白名单时,直接渲染原生 img,保留所有原生属性
120
+ if (typeof src !== 'string' || !isTargetSrc(src)) {
121
+ return (
122
+ <img
123
+ {...rest}
124
+ ref={ref}
125
+ src={src}
126
+ width={width}
127
+ height={height}
128
+ sizes={sizes}
129
+ srcSet={userSrcSet}
130
+ className={cn(
131
+ 'bg-linear-to-b from-gray-50/20 to-gray-200/20',
132
+ className,
133
+ )}
134
+ loading={loading}
135
+ decoding={decoding}
136
+ />
137
+ );
138
+ }
139
+
140
+ // 只有当 width 是数字类型时才进行 srcSet 优化
141
+ const numericWidth = typeof width === 'number' ? width : undefined;
142
+
143
+ // 用户传入的 srcSet 优先,否则生成优化的 srcSet
144
+ const srcSet =
145
+ userSrcSet ??
146
+ buildSrcSet(
147
+ src,
148
+ breakpoints,
149
+ format ?? (defaultFormat as ImageFormat),
150
+ quality,
151
+ numericWidth,
152
+ sizes,
153
+ );
154
+
155
+ const baseSrc = applyParamsToUrl(src, {
156
+ resize: numericWidth ? `w_${numericWidth}` : undefined,
157
+ quality: `Q_${quality}`,
158
+ format: format ?? defaultFormat,
159
+ });
160
+
161
+ return (
162
+ <img
163
+ {...rest}
164
+ ref={ref}
165
+ src={baseSrc}
166
+ width={width}
167
+ height={height}
168
+ sizes={sizes}
169
+ srcSet={srcSet}
170
+ className={cn(
171
+ 'bg-linear-to-b from-gray-50/20 to-gray-200/20',
172
+ className,
173
+ )}
174
+ loading={loading}
175
+ decoding={decoding}
176
+ />
177
+ );
178
+ },
179
+ );
180
+
181
+ Image.displayName = 'Image';
182
+
183
+ export default Image;
@@ -0,0 +1,166 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Button } from "@/components/ui/button"
8
+ import { Input } from "@/components/ui/input"
9
+ import { Textarea } from "@/components/ui/textarea"
10
+
11
+ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
+ return (
13
+ <div
14
+ data-slot="input-group"
15
+ role="group"
16
+ className={cn(
17
+ "group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border transition-[color,box-shadow] outline-none",
18
+ "h-9 min-w-0 has-[>textarea]:h-auto",
19
+
20
+ // Variants based on alignment.
21
+ "has-[>[data-align=inline-start]]:[&>input]:pl-2",
22
+ "has-[>[data-align=inline-end]]:[&>input]:pr-2",
23
+ "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
24
+ "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
25
+
26
+ // Focus state.
27
+ "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/20 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
28
+
29
+ // Error state.
30
+ "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
31
+
32
+ className
33
+ )}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ const inputGroupAddonVariants = cva(
40
+ "text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
41
+ {
42
+ variants: {
43
+ align: {
44
+ "inline-start":
45
+ "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
46
+ "inline-end":
47
+ "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
48
+ "block-start":
49
+ "order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
50
+ "block-end":
51
+ "order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
52
+ },
53
+ },
54
+ defaultVariants: {
55
+ align: "inline-start",
56
+ },
57
+ }
58
+ )
59
+
60
+ function InputGroupAddon({
61
+ className,
62
+ align = "inline-start",
63
+ ...props
64
+ }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
65
+ return (
66
+ <div
67
+ role="group"
68
+ data-slot="input-group-addon"
69
+ data-align={align}
70
+ className={cn(inputGroupAddonVariants({ align }), className)}
71
+ onClick={(e) => {
72
+ if ((e.target as HTMLElement).closest("button")) {
73
+ return
74
+ }
75
+ e.currentTarget.parentElement?.querySelector("input")?.focus()
76
+ }}
77
+ {...props}
78
+ />
79
+ )
80
+ }
81
+
82
+ const inputGroupButtonVariants = cva("text-sm flex gap-2 items-center", {
83
+ variants: {
84
+ size: {
85
+ xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
86
+ sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
87
+ "icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
88
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
89
+ },
90
+ },
91
+ defaultVariants: {
92
+ size: "xs",
93
+ },
94
+ })
95
+
96
+ function InputGroupButton({
97
+ className,
98
+ type = "button",
99
+ variant = "ghost",
100
+ size = "xs",
101
+ ...props
102
+ }: Omit<React.ComponentProps<typeof Button>, "size"> &
103
+ VariantProps<typeof inputGroupButtonVariants>) {
104
+ return (
105
+ <Button
106
+ type={type}
107
+ data-size={size}
108
+ variant={variant}
109
+ className={cn(inputGroupButtonVariants({ size }), className)}
110
+ {...props}
111
+ />
112
+ )
113
+ }
114
+
115
+ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
116
+ return (
117
+ <span
118
+ className={cn(
119
+ "text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
120
+ className
121
+ )}
122
+ {...props}
123
+ />
124
+ )
125
+ }
126
+
127
+ function InputGroupInput({
128
+ className,
129
+ ...props
130
+ }: React.ComponentProps<"input">) {
131
+ return (
132
+ <Input
133
+ data-slot="input-group-control"
134
+ className={cn(
135
+ "flex-1 rounded-none border-0 bg-transparent focus-visible:ring-0 dark:bg-transparent",
136
+ className
137
+ )}
138
+ {...props}
139
+ />
140
+ )
141
+ }
142
+
143
+ function InputGroupTextarea({
144
+ className,
145
+ ...props
146
+ }: React.ComponentProps<"textarea">) {
147
+ return (
148
+ <Textarea
149
+ data-slot="input-group-control"
150
+ className={cn(
151
+ "flex-1 resize-none rounded-none border-0 bg-transparent py-3 focus-visible:ring-0 dark:bg-transparent",
152
+ className
153
+ )}
154
+ {...props}
155
+ />
156
+ )
157
+ }
158
+
159
+ export {
160
+ InputGroup,
161
+ InputGroupAddon,
162
+ InputGroupButton,
163
+ InputGroupText,
164
+ InputGroupInput,
165
+ InputGroupTextarea,
166
+ }
@@ -0,0 +1,77 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { OTPInput, OTPInputContext } from "input-otp"
5
+ import { MinusIcon } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ function InputOTP({
10
+ className,
11
+ containerClassName,
12
+ ...props
13
+ }: React.ComponentProps<typeof OTPInput> & {
14
+ containerClassName?: string
15
+ }) {
16
+ return (
17
+ <OTPInput
18
+ data-slot="input-otp"
19
+ containerClassName={cn(
20
+ "flex items-center gap-2 has-disabled:opacity-50",
21
+ containerClassName
22
+ )}
23
+ className={cn("disabled:cursor-not-allowed", className)}
24
+ {...props}
25
+ />
26
+ )
27
+ }
28
+
29
+ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
30
+ return (
31
+ <div
32
+ data-slot="input-otp-group"
33
+ className={cn("flex items-center", className)}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ function InputOTPSlot({
40
+ index,
41
+ className,
42
+ ...props
43
+ }: React.ComponentProps<"div"> & {
44
+ index: number
45
+ }) {
46
+ const inputOTPContext = React.useContext(OTPInputContext)
47
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
48
+
49
+ return (
50
+ <div
51
+ data-slot="input-otp-slot"
52
+ data-active={isActive}
53
+ className={cn(
54
+ "data-[active=true]:border-ring data-[active=true]:ring-ring/20 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
55
+ className
56
+ )}
57
+ {...props}
58
+ >
59
+ {char}
60
+ {hasFakeCaret && (
61
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
62
+ <div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
63
+ </div>
64
+ )}
65
+ </div>
66
+ )
67
+ }
68
+
69
+ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
70
+ return (
71
+ <div data-slot="input-otp-separator" role="separator" {...props}>
72
+ <MinusIcon />
73
+ </div>
74
+ )
75
+ }
76
+
77
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
@@ -0,0 +1,21 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+ "enabled:hover:border-ring focus-visible:border-ring focus-visible:ring-ring/20 focus-visible:ring-[3px]",
13
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Input }