@sakoa/ui 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 (345) hide show
  1. package/README.md +171 -0
  2. package/dist/App.d.ts +2 -0
  3. package/dist/cli/index.js +9243 -0
  4. package/dist/components/DemoSection.d.ts +30 -0
  5. package/dist/components/SApiKeyboard.d.ts +22 -0
  6. package/dist/components/SApiSection.d.ts +21 -0
  7. package/dist/components/SApiTable.d.ts +46 -0
  8. package/dist/components/STableOfContents.d.ts +2 -0
  9. package/dist/components/ui/SAlert.d.ts +76 -0
  10. package/dist/components/ui/SBadge.d.ts +56 -0
  11. package/dist/components/ui/SButton.d.ts +67 -0
  12. package/dist/components/ui/SCheckbox.d.ts +64 -0
  13. package/dist/components/ui/SChip.d.ts +43 -0
  14. package/dist/components/ui/SDatePicker.d.ts +77 -0
  15. package/dist/components/ui/SGlassButton.d.ts +70 -0
  16. package/dist/components/ui/SIcon.d.ts +29 -0
  17. package/dist/components/ui/SInput.d.ts +129 -0
  18. package/dist/components/ui/SKbd.d.ts +24 -0
  19. package/dist/components/ui/SKbdShortcut.d.ts +14 -0
  20. package/dist/components/ui/SSelect.d.ts +148 -0
  21. package/dist/components/ui/SSkeleton.d.ts +37 -0
  22. package/dist/components/ui/SSwitch.d.ts +61 -0
  23. package/dist/components/ui/STooltip.d.ts +82 -0
  24. package/dist/components/ui/accordion/SAccordionContent.d.ts +23 -0
  25. package/dist/components/ui/accordion/SAccordionItem.d.ts +70 -0
  26. package/dist/components/ui/accordion/SAccordionTrigger.d.ts +37 -0
  27. package/dist/components/ui/accordion/index.d.ts +4 -0
  28. package/dist/components/ui/avatar/SAvatar.d.ts +36 -0
  29. package/dist/components/ui/avatar/SAvatarFallback.d.ts +26 -0
  30. package/dist/components/ui/avatar/SAvatarGroup.d.ts +30 -0
  31. package/dist/components/ui/avatar/SAvatarImage.d.ts +23 -0
  32. package/dist/components/ui/avatar/index.d.ts +4 -0
  33. package/dist/components/ui/breadcrumb/SBreadcrumb.d.ts +22 -0
  34. package/dist/components/ui/breadcrumb/SBreadcrumbEllipsis.d.ts +17 -0
  35. package/dist/components/ui/breadcrumb/SBreadcrumbItem.d.ts +17 -0
  36. package/dist/components/ui/breadcrumb/SBreadcrumbLink.d.ts +26 -0
  37. package/dist/components/ui/breadcrumb/SBreadcrumbList.d.ts +17 -0
  38. package/dist/components/ui/breadcrumb/SBreadcrumbPage.d.ts +17 -0
  39. package/dist/components/ui/breadcrumb/SBreadcrumbSeparator.d.ts +17 -0
  40. package/dist/components/ui/breadcrumb/index.d.ts +7 -0
  41. package/dist/components/ui/card/SCard.d.ts +103 -0
  42. package/dist/components/ui/card/SCardActions.d.ts +44 -0
  43. package/dist/components/ui/card/SCardContent.d.ts +35 -0
  44. package/dist/components/ui/card/SCardFooter.d.ts +38 -0
  45. package/dist/components/ui/card/SCardHeader.d.ts +53 -0
  46. package/dist/components/ui/card/SCardMedia.d.ts +83 -0
  47. package/dist/components/ui/card/SGlassCard.d.ts +103 -0
  48. package/dist/components/ui/card/SMorphingCardContent.d.ts +18 -0
  49. package/dist/components/ui/card/index.d.ts +24 -0
  50. package/dist/components/ui/carousel/SCarousel.d.ts +166 -0
  51. package/dist/components/ui/carousel/index.d.ts +2 -0
  52. package/dist/components/ui/color-picker/SColorPickerAlphaSlider.d.ts +4 -0
  53. package/dist/components/ui/color-picker/SColorPickerCopy.d.ts +19 -0
  54. package/dist/components/ui/color-picker/SColorPickerEyeDropper.d.ts +17 -0
  55. package/dist/components/ui/color-picker/SColorPickerHueSlider.d.ts +4 -0
  56. package/dist/components/ui/color-picker/SColorPickerInputs.d.ts +2 -0
  57. package/dist/components/ui/color-picker/SColorPickerPresets.d.ts +9 -0
  58. package/dist/components/ui/color-picker/SColorPickerPreview.d.ts +2 -0
  59. package/dist/components/ui/color-picker/SColorPickerRecent.d.ts +7 -0
  60. package/dist/components/ui/color-picker/SColorPickerSpectrum.d.ts +4 -0
  61. package/dist/components/ui/color-picker/index.d.ts +11 -0
  62. package/dist/components/ui/drawer/index.d.ts +11 -0
  63. package/dist/components/ui/dropdown/SDropdownDivider.d.ts +8 -0
  64. package/dist/components/ui/dropdown/SDropdownGroup.d.ts +25 -0
  65. package/dist/components/ui/dropdown/SDropdownItem.d.ts +56 -0
  66. package/dist/components/ui/dropdown/index.d.ts +4 -0
  67. package/dist/components/ui/form/SForm.d.ts +38 -0
  68. package/dist/components/ui/form/SFormField.d.ts +31 -0
  69. package/dist/components/ui/form/index.d.ts +5 -0
  70. package/dist/components/ui/modal/index.d.ts +19 -0
  71. package/dist/components/ui/option/SOption.d.ts +32 -0
  72. package/dist/components/ui/option/SOptionGroup.d.ts +28 -0
  73. package/dist/components/ui/option/index.d.ts +2 -0
  74. package/dist/components/ui/otp/SOTP.d.ts +122 -0
  75. package/dist/components/ui/otp/SOTPGroup.d.ts +23 -0
  76. package/dist/components/ui/otp/SOTPSeparator.d.ts +17 -0
  77. package/dist/components/ui/otp/SOTPSlot.d.ts +49 -0
  78. package/dist/components/ui/otp/index.d.ts +7 -0
  79. package/dist/components/ui/otp/types.d.ts +26 -0
  80. package/dist/components/ui/otp/useOTPContext.d.ts +42 -0
  81. package/dist/components/ui/pagination/SPagination.d.ts +151 -0
  82. package/dist/components/ui/pagination/index.d.ts +2 -0
  83. package/dist/components/ui/progress/SProgress.d.ts +62 -0
  84. package/dist/components/ui/progress/SProgressRange.d.ts +91 -0
  85. package/dist/components/ui/progress/index.d.ts +4 -0
  86. package/dist/components/ui/radio/SRadio.d.ts +58 -0
  87. package/dist/components/ui/radio/SRadioGroup.d.ts +52 -0
  88. package/dist/components/ui/radio/index.d.ts +2 -0
  89. package/dist/components/ui/stepper/SStepper.d.ts +83 -0
  90. package/dist/components/ui/stepper/SStepperContent.d.ts +24 -0
  91. package/dist/components/ui/stepper/SStepperDescription.d.ts +20 -0
  92. package/dist/components/ui/stepper/SStepperIndicator.d.ts +37 -0
  93. package/dist/components/ui/stepper/SStepperItem.d.ts +37 -0
  94. package/dist/components/ui/stepper/SStepperSeparator.d.ts +5 -0
  95. package/dist/components/ui/stepper/SStepperTitle.d.ts +20 -0
  96. package/dist/components/ui/stepper/SStepperTrigger.d.ts +22 -0
  97. package/dist/components/ui/stepper/index.d.ts +11 -0
  98. package/dist/components/ui/table/STableBody.d.ts +27 -0
  99. package/dist/components/ui/table/STableCell.d.ts +55 -0
  100. package/dist/components/ui/table/STableColumn.d.ts +87 -0
  101. package/dist/components/ui/table/STableEmpty.d.ts +54 -0
  102. package/dist/components/ui/table/STableHeader.d.ts +25 -0
  103. package/dist/components/ui/table/STableRow.d.ts +38 -0
  104. package/dist/components/ui/table/STableSkeleton.d.ts +29 -0
  105. package/dist/components/ui/table/index.d.ts +98 -0
  106. package/dist/components/ui/table/useDataTable.d.ts +80 -0
  107. package/dist/components/ui/tabs/STabPane.d.ts +31 -0
  108. package/dist/components/ui/tabs/STabsContent.d.ts +21 -0
  109. package/dist/components/ui/tabs/STabsIndicator.d.ts +9 -0
  110. package/dist/components/ui/tabs/STabsTrigger.d.ts +28 -0
  111. package/dist/components/ui/tabs/index.d.ts +6 -0
  112. package/dist/components/ui/toast/SToast.d.ts +49 -0
  113. package/dist/components/ui/toast/SToastContainer.d.ts +21 -0
  114. package/dist/components/ui/toast/index.d.ts +2 -0
  115. package/dist/composables/useAsync.d.ts +134 -0
  116. package/dist/composables/useClickOutside.d.ts +69 -0
  117. package/dist/composables/useClipboard.d.ts +46 -0
  118. package/dist/composables/useDebounce.d.ts +150 -0
  119. package/dist/composables/useDialog.d.ts +118 -0
  120. package/dist/composables/useForm.d.ts +204 -0
  121. package/dist/composables/useHotkey.d.ts +128 -0
  122. package/dist/composables/useIntersectionObserver.d.ts +156 -0
  123. package/dist/composables/useLocalStorage.d.ts +120 -0
  124. package/dist/composables/useMediaQuery.d.ts +115 -0
  125. package/dist/composables/useTheme.d.ts +8 -0
  126. package/dist/composables/useToast.d.ts +1619 -0
  127. package/dist/index.d.ts +71 -0
  128. package/dist/layouts/UILayout.d.ts +2 -0
  129. package/dist/lib/utils.d.ts +2 -0
  130. package/dist/main.d.ts +0 -0
  131. package/dist/router.d.ts +2 -0
  132. package/dist/saka-ui.css +1 -0
  133. package/dist/saka-ui.js +18513 -0
  134. package/dist/saka-ui.umd.cjs +38 -0
  135. package/dist/views/docs/CustomizationView.d.ts +2 -0
  136. package/dist/views/docs/FormValidationView.d.ts +2 -0
  137. package/dist/views/docs/StylingGuideView.d.ts +2 -0
  138. package/dist/views/docs/UseAsyncView.d.ts +2 -0
  139. package/dist/views/docs/UseClickOutsideView.d.ts +124 -0
  140. package/dist/views/docs/UseClipboardView.d.ts +4 -0
  141. package/dist/views/docs/UseDebounceView.d.ts +2 -0
  142. package/dist/views/docs/UseHotkeyView.d.ts +205 -0
  143. package/dist/views/docs/UseIntersectionObserverView.d.ts +5 -0
  144. package/dist/views/docs/UseLocalStorageView.d.ts +2 -0
  145. package/dist/views/docs/UseMediaQueryView.d.ts +2 -0
  146. package/dist/views/docs/UseThemeView.d.ts +2 -0
  147. package/dist/views/examples/AuthFormView.d.ts +2 -0
  148. package/dist/views/examples/CreditCardFormView.d.ts +6 -0
  149. package/dist/views/examples/FormFieldExampleView.d.ts +2 -0
  150. package/dist/views/examples/ProjectFormView.d.ts +2 -0
  151. package/dist/views/ui/AccordionView.d.ts +2 -0
  152. package/dist/views/ui/AlertView.d.ts +2 -0
  153. package/dist/views/ui/AvatarView.d.ts +2 -0
  154. package/dist/views/ui/BadgeView.d.ts +2 -0
  155. package/dist/views/ui/BreadcrumbView.d.ts +2 -0
  156. package/dist/views/ui/ButtonView.d.ts +2 -0
  157. package/dist/views/ui/CardView.d.ts +2 -0
  158. package/dist/views/ui/CarouselView.d.ts +274 -0
  159. package/dist/views/ui/CheckboxView.d.ts +2 -0
  160. package/dist/views/ui/ChipView.d.ts +2 -0
  161. package/dist/views/ui/ColorPickerView.d.ts +2 -0
  162. package/dist/views/ui/DatePickerView.d.ts +2 -0
  163. package/dist/views/ui/DialogView.d.ts +2 -0
  164. package/dist/views/ui/DrawerView.d.ts +2 -0
  165. package/dist/views/ui/DropdownView.d.ts +2 -0
  166. package/dist/views/ui/GlassButtonView.d.ts +2 -0
  167. package/dist/views/ui/GlassCardView.d.ts +2 -0
  168. package/dist/views/ui/HomeView.d.ts +2 -0
  169. package/dist/views/ui/IconsView.d.ts +2 -0
  170. package/dist/views/ui/InputView.d.ts +2 -0
  171. package/dist/views/ui/KbdView.d.ts +2 -0
  172. package/dist/views/ui/ModalView.d.ts +2 -0
  173. package/dist/views/ui/MorphingCardView.d.ts +2 -0
  174. package/dist/views/ui/MorphingModalView.d.ts +2 -0
  175. package/dist/views/ui/OTPView.d.ts +206 -0
  176. package/dist/views/ui/PaginationView.d.ts +2 -0
  177. package/dist/views/ui/ProgressView.d.ts +2 -0
  178. package/dist/views/ui/RadioView.d.ts +2 -0
  179. package/dist/views/ui/SelectView.d.ts +2 -0
  180. package/dist/views/ui/SkeletonView.d.ts +2 -0
  181. package/dist/views/ui/StepperView.d.ts +2 -0
  182. package/dist/views/ui/SwitchView.d.ts +2 -0
  183. package/dist/views/ui/TableView.d.ts +2 -0
  184. package/dist/views/ui/TabsView.d.ts +2 -0
  185. package/dist/views/ui/ToastView.d.ts +2 -0
  186. package/dist/views/ui/TooltipView.d.ts +2 -0
  187. package/dist/vite.svg +1 -0
  188. package/package.json +64 -0
  189. package/registry/components/accordion.json +19 -0
  190. package/registry/components/alert.json +17 -0
  191. package/registry/components/avatar.json +18 -0
  192. package/registry/components/badge.json +14 -0
  193. package/registry/components/breadcrumb.json +24 -0
  194. package/registry/components/button.json +17 -0
  195. package/registry/components/card.json +23 -0
  196. package/registry/components/carousel.json +19 -0
  197. package/registry/components/checkbox.json +17 -0
  198. package/registry/components/chip.json +17 -0
  199. package/registry/components/color-picker.json +24 -0
  200. package/registry/components/date-picker.json +17 -0
  201. package/registry/components/drawer.json +26 -0
  202. package/registry/components/dropdown.json +21 -0
  203. package/registry/components/form.json +16 -0
  204. package/registry/components/glass-button.json +17 -0
  205. package/registry/components/icon.json +17 -0
  206. package/registry/components/input.json +17 -0
  207. package/registry/components/kbd.json +16 -0
  208. package/registry/components/modal.json +32 -0
  209. package/registry/components/option.json +16 -0
  210. package/registry/components/otp.json +23 -0
  211. package/registry/components/pagination.json +18 -0
  212. package/registry/components/progress.json +16 -0
  213. package/registry/components/radio.json +19 -0
  214. package/registry/components/select.json +17 -0
  215. package/registry/components/skeleton.json +14 -0
  216. package/registry/components/switch.json +17 -0
  217. package/registry/components/table.json +26 -0
  218. package/registry/components/tabs.json +19 -0
  219. package/registry/components/toast.json +19 -0
  220. package/registry/components/tooltip.json +14 -0
  221. package/registry/index.json +4 -0
  222. package/registry/source/components/ui/SAlert.vue +388 -0
  223. package/registry/source/components/ui/SBadge.vue +243 -0
  224. package/registry/source/components/ui/SButton.vue +387 -0
  225. package/registry/source/components/ui/SCheckbox.vue +310 -0
  226. package/registry/source/components/ui/SChip.vue +130 -0
  227. package/registry/source/components/ui/SDatePicker.vue +1290 -0
  228. package/registry/source/components/ui/SGlassButton.vue +547 -0
  229. package/registry/source/components/ui/SIcon.vue +78 -0
  230. package/registry/source/components/ui/SInput.vue +1054 -0
  231. package/registry/source/components/ui/SKbd.vue +96 -0
  232. package/registry/source/components/ui/SKbdShortcut.vue +36 -0
  233. package/registry/source/components/ui/SSelect.vue +1290 -0
  234. package/registry/source/components/ui/SSkeleton.vue +185 -0
  235. package/registry/source/components/ui/SSwitch.vue +275 -0
  236. package/registry/source/components/ui/STooltip.vue +491 -0
  237. package/registry/source/components/ui/accordion/SAccordion.vue +248 -0
  238. package/registry/source/components/ui/accordion/SAccordionItem.vue +353 -0
  239. package/registry/source/components/ui/accordion/index.ts +5 -0
  240. package/registry/source/components/ui/avatar/SAvatar.vue +169 -0
  241. package/registry/source/components/ui/avatar/SAvatarFallback.vue +66 -0
  242. package/registry/source/components/ui/avatar/SAvatarGroup.vue +69 -0
  243. package/registry/source/components/ui/avatar/SAvatarImage.vue +92 -0
  244. package/registry/source/components/ui/avatar/index.ts +5 -0
  245. package/registry/source/components/ui/breadcrumb/SBreadcrumb.vue +23 -0
  246. package/registry/source/components/ui/breadcrumb/SBreadcrumbEllipsis.vue +17 -0
  247. package/registry/source/components/ui/breadcrumb/SBreadcrumbItem.vue +14 -0
  248. package/registry/source/components/ui/breadcrumb/SBreadcrumbLink.vue +46 -0
  249. package/registry/source/components/ui/breadcrumb/SBreadcrumbList.vue +17 -0
  250. package/registry/source/components/ui/breadcrumb/SBreadcrumbPage.vue +15 -0
  251. package/registry/source/components/ui/breadcrumb/SBreadcrumbSeparator.vue +18 -0
  252. package/registry/source/components/ui/breadcrumb/index.ts +7 -0
  253. package/registry/source/components/ui/card/SCard.vue +517 -0
  254. package/registry/source/components/ui/card/SCardActions.vue +129 -0
  255. package/registry/source/components/ui/card/SCardContent.vue +117 -0
  256. package/registry/source/components/ui/card/SCardFooter.vue +103 -0
  257. package/registry/source/components/ui/card/SCardHeader.vue +163 -0
  258. package/registry/source/components/ui/card/SCardMedia.vue +312 -0
  259. package/registry/source/components/ui/card/index.ts +34 -0
  260. package/registry/source/components/ui/carousel/SCarousel.vue +1069 -0
  261. package/registry/source/components/ui/carousel/SCarouselSlide.vue +107 -0
  262. package/registry/source/components/ui/carousel/index.ts +3 -0
  263. package/registry/source/components/ui/color-picker/SColorPicker.vue +772 -0
  264. package/registry/source/components/ui/color-picker/SColorPickerAlphaSlider.vue +158 -0
  265. package/registry/source/components/ui/color-picker/SColorPickerCopy.vue +76 -0
  266. package/registry/source/components/ui/color-picker/SColorPickerEyeDropper.vue +68 -0
  267. package/registry/source/components/ui/color-picker/SColorPickerHueSlider.vue +138 -0
  268. package/registry/source/components/ui/color-picker/SColorPickerInputs.vue +227 -0
  269. package/registry/source/components/ui/color-picker/SColorPickerPresets.vue +87 -0
  270. package/registry/source/components/ui/color-picker/SColorPickerPreview.vue +46 -0
  271. package/registry/source/components/ui/color-picker/SColorPickerRecent.vue +74 -0
  272. package/registry/source/components/ui/color-picker/SColorPickerSpectrum.vue +149 -0
  273. package/registry/source/components/ui/color-picker/index.ts +11 -0
  274. package/registry/source/components/ui/drawer/SDrawer.vue +797 -0
  275. package/registry/source/components/ui/drawer/SDrawerClose.vue +64 -0
  276. package/registry/source/components/ui/drawer/SDrawerContent.vue +81 -0
  277. package/registry/source/components/ui/drawer/SDrawerDescription.vue +40 -0
  278. package/registry/source/components/ui/drawer/SDrawerFooter.vue +97 -0
  279. package/registry/source/components/ui/drawer/SDrawerHandle.vue +79 -0
  280. package/registry/source/components/ui/drawer/SDrawerHeader.vue +117 -0
  281. package/registry/source/components/ui/drawer/SDrawerTitle.vue +40 -0
  282. package/registry/source/components/ui/drawer/SDrawerTrigger.vue +51 -0
  283. package/registry/source/components/ui/drawer/index.ts +20 -0
  284. package/registry/source/components/ui/dropdown/SDropdown.vue +843 -0
  285. package/registry/source/components/ui/dropdown/SDropdownDivider.vue +23 -0
  286. package/registry/source/components/ui/dropdown/SDropdownGroup.vue +53 -0
  287. package/registry/source/components/ui/dropdown/SDropdownItem.vue +179 -0
  288. package/registry/source/components/ui/dropdown/index.ts +5 -0
  289. package/registry/source/components/ui/form/SForm.vue +84 -0
  290. package/registry/source/components/ui/form/SFormField.vue +78 -0
  291. package/registry/source/components/ui/form/index.ts +8 -0
  292. package/registry/source/components/ui/modal/SModal.vue +648 -0
  293. package/registry/source/components/ui/modal/SModalClose.vue +49 -0
  294. package/registry/source/components/ui/modal/SModalContent.vue +74 -0
  295. package/registry/source/components/ui/modal/SModalDescription.vue +39 -0
  296. package/registry/source/components/ui/modal/SModalFooter.vue +84 -0
  297. package/registry/source/components/ui/modal/SModalHeader.vue +107 -0
  298. package/registry/source/components/ui/modal/SModalTitle.vue +39 -0
  299. package/registry/source/components/ui/modal/SModalTrigger.vue +61 -0
  300. package/registry/source/components/ui/modal/SMorphingModal.vue +429 -0
  301. package/registry/source/components/ui/modal/SMorphingModalClose.vue +42 -0
  302. package/registry/source/components/ui/modal/SMorphingModalDescription.vue +49 -0
  303. package/registry/source/components/ui/modal/SMorphingModalImage.vue +44 -0
  304. package/registry/source/components/ui/modal/SMorphingModalSubtitle.vue +29 -0
  305. package/registry/source/components/ui/modal/SMorphingModalTitle.vue +34 -0
  306. package/registry/source/components/ui/modal/SMorphingModalTrigger.vue +95 -0
  307. package/registry/source/components/ui/modal/index.ts +32 -0
  308. package/registry/source/components/ui/option/SOption.vue +180 -0
  309. package/registry/source/components/ui/option/SOptionGroup.vue +77 -0
  310. package/registry/source/components/ui/option/index.ts +3 -0
  311. package/registry/source/components/ui/otp/SOTP.vue +843 -0
  312. package/registry/source/components/ui/otp/SOTPGroup.vue +29 -0
  313. package/registry/source/components/ui/otp/SOTPSeparator.vue +15 -0
  314. package/registry/source/components/ui/otp/SOTPSlot.vue +462 -0
  315. package/registry/source/components/ui/otp/index.ts +7 -0
  316. package/registry/source/components/ui/otp/types.ts +27 -0
  317. package/registry/source/components/ui/otp/useOTPContext.ts +62 -0
  318. package/registry/source/components/ui/pagination/SPagination.vue +923 -0
  319. package/registry/source/components/ui/pagination/index.ts +8 -0
  320. package/registry/source/components/ui/progress/SProgress.vue +635 -0
  321. package/registry/source/components/ui/progress/SProgressRange.vue +715 -0
  322. package/registry/source/components/ui/progress/index.ts +4 -0
  323. package/registry/source/components/ui/radio/SRadio.vue +407 -0
  324. package/registry/source/components/ui/radio/SRadioGroup.vue +200 -0
  325. package/registry/source/components/ui/radio/index.ts +3 -0
  326. package/registry/source/components/ui/table/SDataTable.vue +828 -0
  327. package/registry/source/components/ui/table/STableBody.vue +70 -0
  328. package/registry/source/components/ui/table/STableCell.vue +147 -0
  329. package/registry/source/components/ui/table/STableColumn.vue +120 -0
  330. package/registry/source/components/ui/table/STableEmpty.vue +159 -0
  331. package/registry/source/components/ui/table/STableHeader.vue +132 -0
  332. package/registry/source/components/ui/table/STableRow.vue +106 -0
  333. package/registry/source/components/ui/table/STableSkeleton.vue +208 -0
  334. package/registry/source/components/ui/table/index.ts +126 -0
  335. package/registry/source/components/ui/table/useDataTable.ts +519 -0
  336. package/registry/source/components/ui/tabs/STabPane.vue +130 -0
  337. package/registry/source/components/ui/tabs/STabs.vue +467 -0
  338. package/registry/source/components/ui/tabs/index.ts +7 -0
  339. package/registry/source/components/ui/toast/SToast.vue +261 -0
  340. package/registry/source/components/ui/toast/SToastContainer.vue +209 -0
  341. package/registry/source/components/ui/toast/index.ts +2 -0
  342. package/registry/source/composables/useForm.ts +960 -0
  343. package/registry/source/composables/useTheme.ts +86 -0
  344. package/registry/source/composables/useToast.ts +440 -0
  345. package/registry/source/lib/utils.ts +6 -0
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "tabs",
3
+ "displayName": "STabs",
4
+ "description": "Tabs with tab panes, dynamic tab management, and customizable styling",
5
+ "version": "0.1.0",
6
+ "files": [
7
+ "components/ui/tabs/index.ts",
8
+ "components/ui/tabs/STabs.vue",
9
+ "components/ui/tabs/STabPane.vue"
10
+ ],
11
+ "dependencies": [],
12
+ "composables": [],
13
+ "peerDependencies": {
14
+ "vue": "^3.2.0"
15
+ },
16
+ "devDependencies": {
17
+ "@mdi/font": "^7.0.0"
18
+ }
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "toast",
3
+ "displayName": "SToast",
4
+ "description": "Toast notifications with container, auto-dismiss, stacking, and position variants",
5
+ "version": "0.1.0",
6
+ "files": [
7
+ "components/ui/toast/index.ts",
8
+ "components/ui/toast/SToast.vue",
9
+ "components/ui/toast/SToastContainer.vue"
10
+ ],
11
+ "dependencies": [],
12
+ "composables": ["useToast"],
13
+ "peerDependencies": {
14
+ "vue": "^3.2.0"
15
+ },
16
+ "devDependencies": {
17
+ "@mdi/font": "^7.0.0"
18
+ }
19
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "tooltip",
3
+ "displayName": "STooltip",
4
+ "description": "Tooltip with positioning, triggers, delays, and arrow indicator",
5
+ "version": "0.1.0",
6
+ "files": [
7
+ "components/ui/STooltip.vue"
8
+ ],
9
+ "dependencies": [],
10
+ "composables": [],
11
+ "peerDependencies": {
12
+ "vue": "^3.2.0"
13
+ }
14
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "version": "0.1.0",
3
+ "components": ["accordion", "alert", "avatar", "badge", "button", "breadcrumb", "card", "carousel", "checkbox", "chip", "color-picker", "date-picker", "drawer", "dropdown", "form", "glass-button", "icon", "input", "kbd", "modal", "option", "otp", "pagination", "progress", "radio", "select", "skeleton", "switch", "table", "tabs", "toast", "tooltip"]
4
+ }
@@ -0,0 +1,388 @@
1
+ <script setup lang="ts">
2
+ import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
3
+ import { cva, type VariantProps } from 'class-variance-authority'
4
+ import { cn } from '../../lib/utils'
5
+
6
+ defineOptions({ inheritAttrs: false })
7
+
8
+ const alertVariants = cva(
9
+ 'relative overflow-hidden transition-all duration-300 max-w-[600px] min-w-[300px]',
10
+ {
11
+ variants: {
12
+ variant: {
13
+ success: 'bg-emerald-50 dark:bg-emerald-950/50 text-emerald-800 dark:text-emerald-200',
14
+ warning: 'bg-amber-50 dark:bg-amber-950/50 text-amber-800 dark:text-amber-200',
15
+ error: 'bg-red-50 dark:bg-red-950/50 text-red-800 dark:text-red-200',
16
+ info: 'bg-blue-50 dark:bg-blue-950/50 text-blue-800 dark:text-blue-200',
17
+ custom: 'bg-muted text-foreground',
18
+ },
19
+ size: {
20
+ small: 'p-3',
21
+ medium: 'p-4',
22
+ large: 'p-5',
23
+ },
24
+ },
25
+ defaultVariants: {
26
+ variant: 'info',
27
+ size: 'medium',
28
+ },
29
+ }
30
+ )
31
+
32
+ export type AlertVariants = VariantProps<typeof alertVariants>
33
+
34
+ const variantIconColors: Record<string, string> = {
35
+ success: 'text-emerald-600 dark:text-emerald-400',
36
+ warning: 'text-amber-600 dark:text-amber-400',
37
+ error: 'text-red-600 dark:text-red-400',
38
+ info: 'text-blue-600 dark:text-blue-400',
39
+ custom: 'text-current',
40
+ }
41
+
42
+ const variantBorderColors: Record<string, string> = {
43
+ success: 'border-emerald-500',
44
+ warning: 'border-amber-500',
45
+ error: 'border-red-500',
46
+ info: 'border-blue-500',
47
+ custom: 'border-current',
48
+ }
49
+
50
+ const variantProgressColors: Record<string, string> = {
51
+ success: 'bg-emerald-500',
52
+ warning: 'bg-amber-500',
53
+ error: 'bg-red-500',
54
+ info: 'bg-blue-500',
55
+ custom: 'bg-current',
56
+ }
57
+
58
+ const sizeConfig: Record<string, { gap: string; iconSize: string; titleSize: string; textSize: string }> = {
59
+ small: { gap: 'gap-2', iconSize: 'text-lg', titleSize: 'text-sm font-semibold', textSize: 'text-xs' },
60
+ medium: { gap: 'gap-3', iconSize: 'text-xl', titleSize: 'text-base font-semibold', textSize: 'text-sm' },
61
+ large: { gap: 'gap-4', iconSize: 'text-2xl', titleSize: 'text-lg font-semibold', textSize: 'text-base' },
62
+ }
63
+
64
+ export interface Props {
65
+ variant?: 'success' | 'warning' | 'error' | 'info' | 'custom'
66
+ size?: 'small' | 'medium' | 'large'
67
+ title?: string
68
+ description?: string
69
+ icon?: string | boolean
70
+ closable?: boolean
71
+ autoDismiss?: boolean
72
+ duration?: number
73
+ showProgress?: boolean
74
+ color?: string
75
+ position?: 'static' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
76
+ elevation?: boolean
77
+ border?: 'none' | 'left' | 'top' | 'all'
78
+ rounded?: boolean
79
+ dismissible?: boolean
80
+ contentClass?: string
81
+ iconClass?: string
82
+ }
83
+
84
+ const props = withDefaults(defineProps<Props>(), {
85
+ variant: 'info',
86
+ size: 'medium',
87
+ title: undefined,
88
+ description: undefined,
89
+ icon: true,
90
+ closable: true,
91
+ autoDismiss: false,
92
+ duration: 5000,
93
+ showProgress: true,
94
+ color: undefined,
95
+ position: 'static',
96
+ elevation: true,
97
+ border: 'left',
98
+ rounded: true,
99
+ dismissible: false,
100
+ contentClass: undefined,
101
+ iconClass: undefined,
102
+ })
103
+
104
+ const emit = defineEmits<{
105
+ close: []
106
+ dismiss: []
107
+ }>()
108
+
109
+ // Refs
110
+ const isVisible = ref(true)
111
+ const isPaused = ref(false)
112
+ const progress = ref(100)
113
+ const dismissTimer = ref<ReturnType<typeof setTimeout> | null>(null)
114
+ const progressInterval = ref<ReturnType<typeof setInterval> | null>(null)
115
+ const startTime = ref<number>(0)
116
+ const remainingTime = ref<number>(props.duration)
117
+
118
+ // Computed
119
+ const defaultIcons = computed(() => ({
120
+ success: 'check-circle',
121
+ warning: 'alert',
122
+ error: 'alert-circle',
123
+ info: 'information',
124
+ }))
125
+
126
+ const displayIcon = computed(() => {
127
+ if (props.icon === false) return null
128
+ if (typeof props.icon === 'string') return props.icon
129
+ return defaultIcons.value[props.variant as keyof typeof defaultIcons.value] || 'information'
130
+ })
131
+
132
+ const sizes = computed(() => sizeConfig[props.size])
133
+
134
+ const borderClasses = computed(() => {
135
+ if (props.border === 'none') return ''
136
+ const borderColor = variantBorderColors[props.variant]
137
+ if (props.border === 'left') return `border-l-4 ${borderColor}`
138
+ if (props.border === 'top') return `border-t-4 ${borderColor}`
139
+ if (props.border === 'all') return `border-2 ${borderColor}`
140
+ return ''
141
+ })
142
+
143
+ const positionClasses = computed(() => {
144
+ if (props.position === 'static') return ''
145
+ const positions: Record<string, string> = {
146
+ top: 'fixed top-4 left-1/2 -translate-x-1/2 z-50',
147
+ bottom: 'fixed bottom-4 left-1/2 -translate-x-1/2 z-50',
148
+ 'top-left': 'fixed top-4 left-4 z-50',
149
+ 'top-right': 'fixed top-4 right-4 z-50',
150
+ 'bottom-left': 'fixed bottom-4 left-4 z-50',
151
+ 'bottom-right': 'fixed bottom-4 right-4 z-50',
152
+ }
153
+ return positions[props.position] || ''
154
+ })
155
+
156
+ const customStyle = computed(() => {
157
+ if (props.variant !== 'custom' || !props.color) return undefined
158
+ return { '--alert-color': props.color }
159
+ })
160
+
161
+ const alertClasses = computed(() => {
162
+ return cn(
163
+ alertVariants({ variant: props.variant, size: props.size }),
164
+ borderClasses.value,
165
+ positionClasses.value,
166
+ {
167
+ 'rounded-lg': props.rounded,
168
+ 'shadow-lg': props.elevation && props.position !== 'static',
169
+ 'shadow-md': props.elevation && props.position === 'static',
170
+ 'cursor-pointer': props.dismissible,
171
+ },
172
+ )
173
+ })
174
+
175
+ // Methods
176
+ function close() {
177
+ isVisible.value = false
178
+ clearTimers()
179
+ emit('close')
180
+ }
181
+
182
+ function handleDismiss() {
183
+ isVisible.value = false
184
+ clearTimers()
185
+ emit('dismiss')
186
+ }
187
+
188
+ function pause() {
189
+ if (!props.autoDismiss || isPaused.value) return
190
+
191
+ isPaused.value = true
192
+ clearTimers()
193
+
194
+ const elapsed = Date.now() - startTime.value
195
+ remainingTime.value = Math.max(0, remainingTime.value - elapsed)
196
+ }
197
+
198
+ function resume() {
199
+ if (!props.autoDismiss || !isPaused.value) return
200
+
201
+ isPaused.value = false
202
+ startDismissTimer()
203
+ }
204
+
205
+ function startDismissTimer() {
206
+ if (!props.autoDismiss) return
207
+
208
+ startTime.value = Date.now()
209
+
210
+ dismissTimer.value = setTimeout(() => {
211
+ handleDismiss()
212
+ }, remainingTime.value)
213
+
214
+ if (props.showProgress) {
215
+ startProgressAnimation()
216
+ }
217
+ }
218
+
219
+ function startProgressAnimation() {
220
+ const interval = 50
221
+ const totalSteps = remainingTime.value / interval
222
+ let currentStep = 0
223
+
224
+ progressInterval.value = setInterval(() => {
225
+ currentStep++
226
+ progress.value = Math.max(0, 100 - (currentStep / totalSteps) * 100)
227
+
228
+ if (currentStep >= totalSteps) {
229
+ clearInterval(progressInterval.value!)
230
+ progressInterval.value = null
231
+ }
232
+ }, interval)
233
+ }
234
+
235
+ function clearTimers() {
236
+ if (dismissTimer.value) {
237
+ clearTimeout(dismissTimer.value)
238
+ dismissTimer.value = null
239
+ }
240
+ if (progressInterval.value) {
241
+ clearInterval(progressInterval.value)
242
+ progressInterval.value = null
243
+ }
244
+ }
245
+
246
+ function handleKeydown(event: KeyboardEvent) {
247
+ if (event.key === 'Escape' && props.closable) {
248
+ close()
249
+ }
250
+ }
251
+
252
+ function handleAlertClick() {
253
+ if (props.dismissible) {
254
+ close()
255
+ }
256
+ }
257
+
258
+ // Lifecycle
259
+ onMounted(() => {
260
+ if (props.autoDismiss) {
261
+ startDismissTimer()
262
+ }
263
+ document.addEventListener('keydown', handleKeydown)
264
+ })
265
+
266
+ onBeforeUnmount(() => {
267
+ clearTimers()
268
+ document.removeEventListener('keydown', handleKeydown)
269
+ })
270
+
271
+ watch(() => props.autoDismiss, (newVal) => {
272
+ if (newVal) {
273
+ remainingTime.value = props.duration
274
+ startDismissTimer()
275
+ } else {
276
+ clearTimers()
277
+ }
278
+ })
279
+
280
+ defineExpose({
281
+ close,
282
+ pause,
283
+ resume,
284
+ })
285
+ </script>
286
+
287
+ <template>
288
+ <Transition
289
+ name="alert"
290
+ @after-leave="() => emit('close')"
291
+ >
292
+ <div
293
+ v-show="isVisible"
294
+ v-bind="$attrs"
295
+ :class="cn(alertClasses, ($attrs.class as string))"
296
+ :style="customStyle"
297
+ role="alert"
298
+ aria-live="polite"
299
+ @mouseenter="pause"
300
+ @mouseleave="resume"
301
+ @click="handleAlertClick"
302
+ >
303
+ <div class="flex items-start" :class="sizes.gap">
304
+ <!-- Icon -->
305
+ <div v-if="displayIcon" class="shrink-0" :class="[variantIconColors[variant], iconClass]">
306
+ <slot name="icon">
307
+ <span class="mdi" :class="[`mdi-${displayIcon}`, sizes.iconSize]" />
308
+ </slot>
309
+ </div>
310
+
311
+ <!-- Content -->
312
+ <div class="flex-1 min-w-0" :class="contentClass">
313
+ <div v-if="title || $slots.title" :class="sizes.titleSize">
314
+ <slot name="title">
315
+ {{ title }}
316
+ </slot>
317
+ </div>
318
+
319
+ <div
320
+ v-if="description || $slots.default"
321
+ :class="[sizes.textSize, { 'mt-1': title || $slots.title }]"
322
+ >
323
+ <slot>
324
+ {{ description }}
325
+ </slot>
326
+ </div>
327
+
328
+ <div v-if="$slots.actions" class="mt-3 flex items-center gap-2">
329
+ <slot name="actions" />
330
+ </div>
331
+ </div>
332
+
333
+ <!-- Close Button -->
334
+ <button
335
+ v-if="closable"
336
+ type="button"
337
+ :class="cn(
338
+ 'shrink-0 inline-flex items-center justify-center rounded-md px-1 transition-colors hover:bg-black/5 dark:hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-offset-2',
339
+ variantIconColors[variant]
340
+ )"
341
+ aria-label="Close alert"
342
+ @click.stop="close"
343
+ >
344
+ <span class="mdi mdi-close text-lg" />
345
+ </button>
346
+ </div>
347
+
348
+ <!-- Progress Bar -->
349
+ <div
350
+ v-if="autoDismiss && showProgress"
351
+ class="absolute bottom-0 left-0 h-1 transition-all duration-100 ease-linear"
352
+ :class="variantProgressColors[variant]"
353
+ :style="{ width: `${progress}%` }"
354
+ />
355
+ </div>
356
+ </Transition>
357
+ </template>
358
+
359
+ <style scoped>
360
+ /* Alert transitions */
361
+ .alert-enter-active,
362
+ .alert-leave-active {
363
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
364
+ }
365
+
366
+ .alert-enter-from {
367
+ opacity: 0;
368
+ transform: translateY(-12px) scale(0.95);
369
+ }
370
+
371
+ .alert-leave-to {
372
+ opacity: 0;
373
+ transform: translateY(12px) scale(0.95);
374
+ }
375
+
376
+ /* Custom variant with color prop */
377
+ [style*="--alert-color"] .text-current {
378
+ color: var(--alert-color);
379
+ }
380
+
381
+ [style*="--alert-color"] .bg-current {
382
+ background-color: var(--alert-color);
383
+ }
384
+
385
+ [style*="--alert-color"] .border-current {
386
+ border-color: var(--alert-color);
387
+ }
388
+ </style>
@@ -0,0 +1,243 @@
1
+ <script setup lang="ts">
2
+ import { computed, type CSSProperties } from 'vue'
3
+ import { cva, type VariantProps } from 'class-variance-authority'
4
+ import { cn } from '../../lib/utils'
5
+
6
+ defineOptions({ inheritAttrs: false })
7
+
8
+ const badgeVariants = cva(
9
+ 'inline-flex items-center justify-center rounded-full font-medium transition-all duration-200 select-none whitespace-nowrap z-10',
10
+ {
11
+ variants: {
12
+ variant: {
13
+ filled: 'bg-primary text-primary-foreground',
14
+ outlined: 'border-[1.5px] border-primary text-primary bg-background',
15
+ light: 'bg-primary/15 text-primary',
16
+ },
17
+ size: {
18
+ small: 'text-[10px] min-w-4 h-4 px-1',
19
+ medium: 'text-xs min-w-5 h-5 px-1.5',
20
+ large: 'text-sm min-w-6 h-6 px-2',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: 'filled',
25
+ size: 'medium',
26
+ },
27
+ }
28
+ )
29
+
30
+ const dotSizeClasses = {
31
+ small: 'w-1.5 h-1.5',
32
+ medium: 'w-2 h-2',
33
+ large: 'w-2.5 h-2.5',
34
+ }
35
+
36
+ export type BadgeVariants = VariantProps<typeof badgeVariants>
37
+
38
+ export interface Props {
39
+ variant?: 'filled' | 'outlined' | 'light'
40
+ size?: 'small' | 'medium' | 'large'
41
+ color?: string
42
+ content?: string | number
43
+ max?: number
44
+ showZero?: boolean
45
+ dot?: boolean
46
+ bordered?: boolean
47
+ position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
48
+ offset?: [number, number]
49
+ standalone?: boolean
50
+ pulse?: boolean
51
+ badgeClass?: string
52
+ }
53
+
54
+ const props = withDefaults(defineProps<Props>(), {
55
+ variant: 'filled',
56
+ size: 'medium',
57
+ color: undefined,
58
+ max: 99,
59
+ showZero: false,
60
+ dot: false,
61
+ bordered: false,
62
+ position: 'top-right',
63
+ offset: () => [0, 0],
64
+ standalone: false,
65
+ pulse: false,
66
+ })
67
+
68
+ const emit = defineEmits<{
69
+ click: [event: MouseEvent]
70
+ }>()
71
+
72
+ const displayContent = computed(() => {
73
+ if (props.dot) return ''
74
+ if (props.content === undefined || props.content === null) return ''
75
+
76
+ const numContent = typeof props.content === 'string'
77
+ ? parseInt(props.content, 10)
78
+ : props.content
79
+
80
+ if (isNaN(numContent)) return props.content
81
+ if (numContent === 0 && !props.showZero) return ''
82
+ if (numContent > props.max) return `${props.max}+`
83
+
84
+ return String(numContent)
85
+ })
86
+
87
+ const isVisible = computed(() => {
88
+ if (props.dot) return true
89
+ if (props.content === undefined || props.content === null) return false
90
+
91
+ const numContent = typeof props.content === 'string'
92
+ ? parseInt(props.content, 10)
93
+ : props.content
94
+
95
+ if (isNaN(numContent)) return true
96
+ if (numContent === 0 && !props.showZero) return false
97
+
98
+ return true
99
+ })
100
+
101
+ // Custom color override: when color prop is explicitly set, inject as CSS variable
102
+ const colorStyle = computed<CSSProperties | undefined>(() => {
103
+ if (!props.color) return undefined
104
+
105
+ const style: CSSProperties = {}
106
+ const c = props.color
107
+
108
+ if (props.variant === 'filled') {
109
+ style.backgroundColor = c
110
+ style.color = '#fff'
111
+ } else if (props.variant === 'outlined') {
112
+ style.borderColor = c
113
+ style.color = c
114
+ } else if (props.variant === 'light') {
115
+ style.backgroundColor = c.startsWith('var(') ? `color-mix(in srgb, ${c} 15%, transparent)` : `${c}20`
116
+ style.color = c
117
+ }
118
+
119
+ if (props.bordered) {
120
+ style.boxShadow = '0 0 0 2px var(--s-background)'
121
+ }
122
+
123
+ return style
124
+ })
125
+
126
+ const borderedStyle = computed<CSSProperties | undefined>(() => {
127
+ if (!props.bordered || props.color) return undefined
128
+ return { boxShadow: '0 0 0 2px var(--s-background)' }
129
+ })
130
+
131
+ const sizeClasses = computed(() => {
132
+ if (props.dot) return dotSizeClasses[props.size]
133
+ return undefined
134
+ })
135
+
136
+ const badgeClasses = computed(() => {
137
+ if (props.dot) {
138
+ return cn(
139
+ 'inline-flex rounded-full transition-all duration-200 select-none z-10',
140
+ props.variant === 'filled' && !props.color && 'bg-primary',
141
+ props.variant === 'outlined' && !props.color && 'border-[1.5px] border-primary bg-background',
142
+ props.variant === 'light' && !props.color && 'bg-primary/15',
143
+ dotSizeClasses[props.size],
144
+ { 'cursor-pointer hover:brightness-110': !!emit },
145
+ props.badgeClass,
146
+ )
147
+ }
148
+
149
+ return cn(
150
+ badgeVariants({ variant: props.color ? undefined : props.variant, size: props.size }),
151
+ // When color is set, skip variant styling (handled by inline style)
152
+ props.color && 'inline-flex items-center justify-center rounded-full font-medium transition-all duration-200 select-none whitespace-nowrap z-10',
153
+ { 'cursor-pointer hover:brightness-110': !!emit },
154
+ props.badgeClass,
155
+ )
156
+ })
157
+
158
+ const positionStyle = computed<CSSProperties>(() => {
159
+ if (props.standalone) return {}
160
+
161
+ const [offsetX, offsetY] = props.offset
162
+ const positions: Record<string, CSSProperties> = {
163
+ 'top-right': {
164
+ top: `${offsetY}px`,
165
+ right: `${offsetX}px`,
166
+ transform: 'translate(50%, -50%)',
167
+ },
168
+ 'top-left': {
169
+ top: `${offsetY}px`,
170
+ left: `${offsetX}px`,
171
+ transform: 'translate(-50%, -50%)',
172
+ },
173
+ 'bottom-right': {
174
+ bottom: `${offsetY}px`,
175
+ right: `${offsetX}px`,
176
+ transform: 'translate(50%, 50%)',
177
+ },
178
+ 'bottom-left': {
179
+ bottom: `${offsetY}px`,
180
+ left: `${offsetX}px`,
181
+ transform: 'translate(-50%, 50%)',
182
+ },
183
+ }
184
+
185
+ return positions[props.position]
186
+ })
187
+
188
+ const handleClick = (e: MouseEvent) => {
189
+ emit('click', e)
190
+ }
191
+ </script>
192
+
193
+ <template>
194
+ <div v-if="standalone" v-bind="$attrs" class="inline-flex align-middle">
195
+ <span
196
+ v-if="isVisible"
197
+ :class="badgeClasses"
198
+ :style="colorStyle ?? borderedStyle"
199
+ @click="handleClick"
200
+ >
201
+ <slot name="content">{{ displayContent }}</slot>
202
+ </span>
203
+ </div>
204
+
205
+ <div v-else v-bind="$attrs" class="relative inline-flex align-middle">
206
+ <slot />
207
+
208
+ <span
209
+ v-if="isVisible"
210
+ :class="cn(badgeClasses, 'absolute', { 's-badge-pulse': pulse })"
211
+ :style="{ ...(colorStyle ?? borderedStyle), ...positionStyle }"
212
+ @click="handleClick"
213
+ >
214
+ <slot name="content">{{ displayContent }}</slot>
215
+ </span>
216
+ </div>
217
+ </template>
218
+
219
+ <style scoped>
220
+ .s-badge-pulse::after {
221
+ content: '';
222
+ position: absolute;
223
+ inset: 0;
224
+ border-radius: inherit;
225
+ background: inherit;
226
+ animation: pulse-ring 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
227
+ }
228
+
229
+ @keyframes pulse-ring {
230
+ 0% {
231
+ transform: scale(1);
232
+ opacity: 0.8;
233
+ }
234
+ 50% {
235
+ transform: scale(1.5);
236
+ opacity: 0;
237
+ }
238
+ 100% {
239
+ transform: scale(1.5);
240
+ opacity: 0;
241
+ }
242
+ }
243
+ </style>