@rimelight/ui 0.0.33 → 0.0.35

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 (389) hide show
  1. package/README.md +158 -157
  2. package/package.json +100 -105
  3. package/src/components/astro/RLAAccordion.astro +94 -18
  4. package/src/components/astro/RLAAspectRatio.astro +2 -2
  5. package/src/components/astro/RLAAvatar.astro +135 -68
  6. package/src/components/astro/RLABadge.astro +4 -2
  7. package/src/components/astro/RLABanner.astro +138 -23
  8. package/src/components/astro/RLABreadcrumb.astro +13 -0
  9. package/src/components/astro/RLAButton.astro +145 -139
  10. package/src/components/astro/RLACallout.astro +112 -0
  11. package/src/components/astro/RLACard.astro +6 -5
  12. package/src/components/astro/RLACarousel.astro +104 -75
  13. package/src/components/astro/RLAChart.astro +23 -35
  14. package/src/components/astro/RLAChip.astro +11 -5
  15. package/src/components/astro/RLACollapsible.astro +4 -1
  16. package/src/components/astro/RLAColorArea.astro +432 -0
  17. package/src/components/astro/RLAColorField.astro +300 -0
  18. package/src/components/astro/RLAColorSlider.astro +413 -0
  19. package/src/components/astro/RLAConfirm.astro +13 -11
  20. package/src/components/astro/RLACopyMarkdown.astro +78 -0
  21. package/src/components/astro/RLADate.astro +30 -0
  22. package/src/components/astro/RLADrawer.astro +50 -3
  23. package/src/components/astro/RLADropdownMenu.astro +78 -51
  24. package/src/components/astro/RLAFieldGroup.astro +4 -1
  25. package/src/components/astro/RLAFileUpload.astro +114 -100
  26. package/src/components/astro/RLAFooter.astro +2 -1
  27. package/src/components/astro/RLAFormField.astro +10 -6
  28. package/src/components/astro/RLAGrid.astro +31 -39
  29. package/src/components/astro/RLAHead.astro +528 -197
  30. package/src/components/astro/RLAHeader.astro +67 -59
  31. package/src/components/astro/RLAImage.astro +274 -209
  32. package/src/components/astro/RLAInput.astro +14 -9
  33. package/src/components/astro/RLAInputMenu.astro +119 -83
  34. package/src/components/astro/RLAKbd.astro +5 -5
  35. package/src/components/astro/RLALayoutGrid.astro +395 -0
  36. package/src/components/astro/RLALink.astro +44 -23
  37. package/src/components/astro/RLALinkGroup.astro +99 -37
  38. package/src/components/astro/RLALocaleSelector.astro +130 -113
  39. package/src/components/astro/RLALogo.astro +117 -90
  40. package/src/components/astro/RLAMain.astro +8 -3
  41. package/src/components/astro/RLAMarquee.astro +9 -2
  42. package/src/components/astro/RLAModal.astro +48 -18
  43. package/src/components/astro/RLANavigationMenu.astro +381 -137
  44. package/src/components/astro/{RLADocsPackageManagers.astro → RLAPackageManagers.astro} +81 -87
  45. package/src/components/astro/RLAPageSection.astro +4 -2
  46. package/src/components/astro/RLAPagination.astro +2 -4
  47. package/src/components/astro/RLAPopover.astro +4 -3
  48. package/src/components/astro/RLAPost.astro +11 -2
  49. package/src/components/astro/RLAProgress.astro +8 -2
  50. package/src/components/astro/RLAScrollArea.astro +4 -1
  51. package/src/components/astro/RLAScrollToTop.astro +200 -172
  52. package/src/components/astro/RLASearch.astro +282 -0
  53. package/src/components/astro/RLASelect.astro +101 -64
  54. package/src/components/astro/RLASeparator.astro +11 -6
  55. package/src/components/astro/RLAShare.astro +60 -0
  56. package/src/components/astro/RLAShortcuts.astro +429 -0
  57. package/src/components/astro/RLASidebar.astro +158 -212
  58. package/src/components/astro/RLASlideover.astro +99 -4
  59. package/src/components/astro/RLASlider.astro +14 -14
  60. package/src/components/astro/RLASplitter.astro +207 -142
  61. package/src/components/astro/RLASteps.astro +118 -71
  62. package/src/components/astro/RLAStickySurface.astro +9 -2
  63. package/src/components/astro/RLASurround.astro +39 -0
  64. package/src/components/astro/RLATable.astro +4 -1
  65. package/src/components/astro/RLATableOfContents.astro +109 -23
  66. package/src/components/astro/RLATabs.astro +147 -133
  67. package/src/components/astro/RLATextarea.astro +4 -1
  68. package/src/components/astro/RLAThemeSelector.astro +105 -76
  69. package/src/components/astro/RLAToast.astro +35 -21
  70. package/src/components/vue/RLVBanner.vue +230 -0
  71. package/src/components/vue/RLVButton.vue +3 -2
  72. package/src/components/vue/RLVCheckbox.vue +70 -68
  73. package/src/components/vue/RLVFooter.vue +3 -2
  74. package/src/components/vue/RLVForm.vue +44 -44
  75. package/src/components/vue/RLVFormField.vue +58 -58
  76. package/src/components/vue/RLVHeader.vue +3 -2
  77. package/src/components/vue/RLVIcon.vue +4 -2
  78. package/src/components/vue/RLVInput.vue +94 -93
  79. package/src/components/vue/RLVLogo.vue +25 -3
  80. package/src/components/vue/RLVPlaceholder.vue +3 -2
  81. package/src/components/vue/RLVPost.vue +69 -63
  82. package/src/components/vue/RLVPosts.vue +21 -21
  83. package/src/components/vue/RLVProgress.vue +60 -0
  84. package/src/components/vue/RLVScrollToTop.vue +65 -52
  85. package/src/components/vue/RLVSection.vue +14 -13
  86. package/src/components/vue/RLVToast.vue +81 -68
  87. package/src/components/vue/RLVToaster.vue +29 -29
  88. package/src/composables/index.ts +4 -3
  89. package/src/composables/useHeaderStore.ts +14 -14
  90. package/src/composables/useScrollToTop.ts +62 -62
  91. package/src/composables/useShortcuts.ts +11 -0
  92. package/src/composables/useToast.ts +43 -42
  93. package/src/config/index.ts +1 -0
  94. package/src/config/security.ts +227 -0
  95. package/src/config/site.config.ts +1 -0
  96. package/src/docs/components/ApiChangelog.astro +147 -0
  97. package/src/{plugins/starlightDocsApi → docs}/components/ApiEmits.astro +4 -4
  98. package/src/{plugins/starlightDocsApi → docs}/components/ApiProps.astro +4 -4
  99. package/src/{plugins/starlightDocsApi → docs}/components/ApiSlots.astro +4 -4
  100. package/src/docs/components/ApiTheme.astro +100 -0
  101. package/src/docs/extractAll.ts +94 -0
  102. package/src/docs/extractors/extractAstro.ts +69 -0
  103. package/src/docs/extractors/extractTheme.ts +56 -0
  104. package/src/{plugins/starlightDocsApi/extract-vue.ts → docs/extractors/extractVue.ts} +164 -15
  105. package/src/{plugins/starlightDocsApi → docs}/utils.ts +1 -2
  106. package/src/env.d.ts +0 -12
  107. package/src/integrations/ui.ts +215 -199
  108. package/src/middleware/security.ts +145 -29
  109. package/src/presets/defaults.ts +297 -297
  110. package/src/presets/index.ts +508 -637
  111. package/src/styles/index.css +158 -160
  112. package/src/themes/3d-hover.theme.ts +13 -13
  113. package/src/themes/accordion.theme.ts +39 -13
  114. package/src/themes/app.theme.ts +13 -13
  115. package/src/themes/aspect-ratio.theme.ts +1 -1
  116. package/src/themes/audio.theme.ts +13 -13
  117. package/src/themes/avatar-group.theme.ts +1 -1
  118. package/src/themes/avatar.theme.ts +84 -84
  119. package/src/themes/badge.theme.ts +168 -163
  120. package/src/themes/banner.theme.ts +49 -13
  121. package/src/themes/breadcrumb.theme.ts +1 -1
  122. package/src/themes/browser-mockup.theme.ts +13 -13
  123. package/src/themes/button.theme.ts +223 -202
  124. package/src/themes/calendar.theme.ts +13 -13
  125. package/src/themes/{alert.theme.ts → callout.theme.ts} +104 -125
  126. package/src/themes/card.theme.ts +50 -42
  127. package/src/themes/carousel.theme.ts +1 -1
  128. package/src/themes/chart.theme.ts +22 -22
  129. package/src/themes/chat-message.theme.ts +13 -13
  130. package/src/themes/chat-messages.theme.ts +13 -13
  131. package/src/themes/chat-palette.theme.ts +13 -13
  132. package/src/themes/chat-prompt-submit.theme.ts +13 -13
  133. package/src/themes/chat-prompt.theme.ts +13 -13
  134. package/src/themes/chat-reasoning.theme.ts +13 -13
  135. package/src/themes/chat-shimmer.theme.ts +13 -13
  136. package/src/themes/chat-tool.theme.ts +13 -13
  137. package/src/themes/chat.theme.ts +13 -13
  138. package/src/themes/checkbox.theme.ts +49 -50
  139. package/src/themes/chip.theme.ts +73 -74
  140. package/src/themes/color-area.theme.ts +33 -0
  141. package/src/themes/color-field.theme.ts +32 -0
  142. package/src/themes/color-picker.theme.ts +13 -13
  143. package/src/themes/color-slider.theme.ts +34 -0
  144. package/src/themes/command-palette.theme.ts +13 -13
  145. package/src/themes/compare.theme.ts +13 -13
  146. package/src/themes/confirm.theme.ts +48 -48
  147. package/src/themes/container.theme.ts +13 -13
  148. package/src/themes/context-menu.theme.ts +13 -13
  149. package/src/themes/dashboard-group.theme.ts +13 -13
  150. package/src/themes/dashboard-navbar.theme.ts +13 -13
  151. package/src/themes/dashboard-panel.theme.ts +13 -13
  152. package/src/themes/dashboard-resize-handle.theme.ts +13 -13
  153. package/src/themes/dashboard-search-button.theme.ts +13 -13
  154. package/src/themes/dashboard-search.theme.ts +13 -13
  155. package/src/themes/dashboard-sidebar-collapse.theme.ts +13 -13
  156. package/src/themes/dashboard-sidebar-toggle.theme.ts +13 -13
  157. package/src/themes/dashboard-sidebar.theme.ts +13 -13
  158. package/src/themes/dashboard-toolbar.theme.ts +13 -13
  159. package/src/themes/dock.theme.ts +13 -13
  160. package/src/themes/drawer.theme.ts +61 -61
  161. package/src/themes/dropdown-menu.theme.ts +29 -29
  162. package/src/themes/editor.theme.ts +13 -13
  163. package/src/themes/empty.theme.ts +13 -13
  164. package/src/themes/error.theme.ts +13 -13
  165. package/src/themes/field-group.theme.ts +24 -24
  166. package/src/themes/fieldset.theme.ts +13 -13
  167. package/src/themes/floating-action.theme.ts +13 -13
  168. package/src/themes/footer.theme.ts +30 -30
  169. package/src/themes/form.theme.ts +13 -13
  170. package/src/themes/gallery.theme.ts +13 -13
  171. package/src/themes/grid.theme.ts +38 -0
  172. package/src/themes/head.theme.ts +13 -13
  173. package/src/themes/header.theme.ts +46 -46
  174. package/src/themes/hover-card.theme.ts +1 -1
  175. package/src/themes/icon.theme.ts +23 -23
  176. package/src/themes/image.theme.ts +33 -19
  177. package/src/themes/input-date.theme.ts +13 -13
  178. package/src/themes/input-menu.theme.ts +35 -35
  179. package/src/themes/input-number.theme.ts +13 -13
  180. package/src/themes/input-tags.theme.ts +13 -13
  181. package/src/themes/input-time.theme.ts +13 -13
  182. package/src/themes/input.theme.ts +48 -42
  183. package/src/themes/kbd.theme.ts +94 -89
  184. package/src/themes/knob.theme.ts +13 -13
  185. package/src/themes/label.theme.ts +1 -1
  186. package/src/themes/layout-grid.theme.ts +16 -0
  187. package/src/themes/link-group.theme.ts +28 -32
  188. package/src/themes/link.theme.ts +13 -13
  189. package/src/themes/listbox.theme.ts +13 -13
  190. package/src/themes/locale-selector.theme.ts +49 -49
  191. package/src/themes/logo.theme.ts +13 -13
  192. package/src/themes/main.theme.ts +13 -13
  193. package/src/themes/marquee.theme.ts +1 -1
  194. package/src/themes/meter.theme.ts +13 -13
  195. package/src/themes/modal.theme.ts +1 -1
  196. package/src/themes/navigation-menu.theme.ts +44 -27
  197. package/src/themes/page-aside.theme.ts +13 -13
  198. package/src/themes/page-body.theme.ts +13 -13
  199. package/src/themes/page-header.theme.ts +13 -13
  200. package/src/themes/page-section.theme.ts +189 -187
  201. package/src/themes/page.theme.ts +13 -13
  202. package/src/themes/pagination.theme.ts +1 -1
  203. package/src/themes/password.theme.ts +13 -13
  204. package/src/themes/phone-mockup.theme.ts +13 -13
  205. package/src/themes/pin-input.theme.ts +1 -1
  206. package/src/themes/placeholder.theme.ts +15 -15
  207. package/src/themes/popover.theme.ts +1 -1
  208. package/src/themes/post.theme.ts +53 -33
  209. package/src/themes/pricing-plan.theme.ts +13 -13
  210. package/src/themes/pricing-table.theme.ts +13 -13
  211. package/src/themes/progress.theme.ts +37 -38
  212. package/src/themes/prose.theme.ts +13 -13
  213. package/src/themes/qr-code.theme.ts +13 -13
  214. package/src/themes/quote.theme.ts +13 -13
  215. package/src/themes/radio-group.theme.ts +13 -13
  216. package/src/themes/rating.theme.ts +13 -13
  217. package/src/themes/scroll-area.theme.ts +26 -26
  218. package/src/themes/scroll-to-top.theme.ts +51 -52
  219. package/src/themes/search.theme.ts +64 -0
  220. package/src/themes/select.theme.ts +29 -29
  221. package/src/themes/separator.theme.ts +147 -147
  222. package/src/themes/sidebar.theme.ts +38 -38
  223. package/src/themes/skeleton.theme.ts +21 -21
  224. package/src/themes/slideover.theme.ts +5 -5
  225. package/src/themes/slider.theme.ts +35 -36
  226. package/src/themes/speed-dial.theme.ts +13 -13
  227. package/src/themes/spinner.theme.ts +33 -34
  228. package/src/themes/splitter.theme.ts +23 -23
  229. package/src/themes/spoiler.theme.ts +13 -13
  230. package/src/themes/stepper.theme.ts +13 -13
  231. package/src/themes/{megamenu.theme.ts → steps.theme.ts} +13 -13
  232. package/src/themes/sticky-surface.theme.ts +1 -1
  233. package/src/themes/switch.theme.ts +66 -67
  234. package/src/themes/table-of-contents.theme.ts +67 -48
  235. package/src/themes/tabs.theme.ts +52 -52
  236. package/src/themes/textarea.theme.ts +27 -27
  237. package/src/themes/theme-selector.theme.ts +15 -15
  238. package/src/themes/timeline.theme.ts +18 -13
  239. package/src/themes/toast.theme.ts +31 -31
  240. package/src/themes/tooltip.theme.ts +28 -28
  241. package/src/themes/tour.theme.ts +13 -13
  242. package/src/themes/tree.theme.ts +13 -13
  243. package/src/themes/user.theme.ts +13 -13
  244. package/src/themes/video.theme.ts +17 -17
  245. package/src/themes/watermark.theme.ts +13 -13
  246. package/src/themes/window-mockup.theme.ts +13 -13
  247. package/src/types/components/3d-hover.ts +11 -11
  248. package/src/types/components/accordion.ts +35 -2
  249. package/src/types/components/app.ts +11 -11
  250. package/src/types/components/audio.ts +11 -11
  251. package/src/types/components/avatar-group.ts +11 -11
  252. package/src/types/components/avatar.ts +76 -60
  253. package/src/types/components/badge.ts +2 -2
  254. package/src/types/components/banner.ts +53 -11
  255. package/src/types/components/browser-mockup.ts +11 -11
  256. package/src/types/components/button.ts +73 -81
  257. package/src/types/components/calendar.ts +11 -11
  258. package/src/types/components/{alert.ts → callout.ts} +8 -8
  259. package/src/types/components/changelog.ts +11 -11
  260. package/src/types/components/chart.ts +2 -1
  261. package/src/types/components/chat-message.ts +11 -11
  262. package/src/types/components/chat-messages.ts +11 -11
  263. package/src/types/components/chat-palette.ts +11 -11
  264. package/src/types/components/chat-prompt-submit.ts +11 -11
  265. package/src/types/components/chat-prompt.ts +11 -11
  266. package/src/types/components/chat-reasoning.ts +11 -11
  267. package/src/types/components/chat-shimmer.ts +11 -11
  268. package/src/types/components/chat-tool.ts +11 -11
  269. package/src/types/components/chat.ts +11 -11
  270. package/src/types/components/checkbox.ts +2 -2
  271. package/src/types/components/chip.ts +17 -17
  272. package/src/types/components/collapsible.ts +2 -1
  273. package/src/types/components/color-area.ts +19 -0
  274. package/src/types/components/color-field.ts +21 -0
  275. package/src/types/components/color-picker.ts +11 -11
  276. package/src/types/components/color-slider.ts +20 -0
  277. package/src/types/components/command-palette.ts +11 -11
  278. package/src/types/components/compare.ts +11 -11
  279. package/src/types/components/container.ts +17 -17
  280. package/src/types/components/context-menu.ts +11 -11
  281. package/src/types/components/dashboard-group.ts +11 -11
  282. package/src/types/components/dashboard-navbar.ts +11 -11
  283. package/src/types/components/dashboard-panel.ts +11 -11
  284. package/src/types/components/dashboard-resize-handle.ts +11 -11
  285. package/src/types/components/dashboard-search-button.ts +11 -11
  286. package/src/types/components/dashboard-search.ts +11 -11
  287. package/src/types/components/dashboard-sidebar-collapse.ts +11 -11
  288. package/src/types/components/dashboard-sidebar-toggle.ts +11 -11
  289. package/src/types/components/dashboard-sidebar.ts +11 -11
  290. package/src/types/components/dashboard-toolbar.ts +11 -11
  291. package/src/types/components/dock.ts +11 -11
  292. package/src/types/components/dropdown-menu.ts +2 -1
  293. package/src/types/components/editor.ts +11 -11
  294. package/src/types/components/empty.ts +11 -11
  295. package/src/types/components/error.ts +11 -11
  296. package/src/types/components/fieldset.ts +11 -11
  297. package/src/types/components/file-upload.ts +2 -1
  298. package/src/types/components/floating-action.ts +11 -11
  299. package/src/types/components/form.ts +19 -19
  300. package/src/types/components/gallery.ts +11 -11
  301. package/src/types/components/grid.ts +23 -0
  302. package/src/types/components/icon.ts +19 -19
  303. package/src/types/components/image.ts +32 -28
  304. package/src/types/components/input-date.ts +11 -11
  305. package/src/types/components/input-menu.ts +44 -43
  306. package/src/types/components/input-number.ts +11 -11
  307. package/src/types/components/input-pin.ts +36 -35
  308. package/src/types/components/input-tags.ts +11 -11
  309. package/src/types/components/input-time.ts +11 -11
  310. package/src/types/components/input.ts +6 -2
  311. package/src/types/components/knob.ts +11 -11
  312. package/src/types/components/layout-grid.ts +145 -0
  313. package/src/types/components/link-group.ts +47 -23
  314. package/src/types/components/link.ts +19 -0
  315. package/src/types/components/listbox.ts +11 -11
  316. package/src/types/components/locale-selector.ts +33 -33
  317. package/src/types/components/logo.ts +32 -31
  318. package/src/types/components/main.ts +17 -17
  319. package/src/types/components/meter.ts +11 -11
  320. package/src/types/components/modal.ts +39 -39
  321. package/src/types/components/navigation-menu.ts +59 -54
  322. package/src/types/components/page-aside.ts +11 -11
  323. package/src/types/components/page-body.ts +11 -11
  324. package/src/types/components/page-header.ts +11 -11
  325. package/src/types/components/page.ts +11 -11
  326. package/src/types/components/password.ts +11 -11
  327. package/src/types/components/phone-mockup.ts +5 -5
  328. package/src/types/components/pin-input.ts +11 -11
  329. package/src/types/components/popover.ts +23 -23
  330. package/src/types/components/post.ts +47 -35
  331. package/src/types/components/pricing-plan.ts +11 -11
  332. package/src/types/components/pricing-table.ts +11 -11
  333. package/src/types/components/progress.ts +33 -33
  334. package/src/types/components/prose.ts +11 -11
  335. package/src/types/components/qr-code.ts +11 -11
  336. package/src/types/components/radio-group.ts +11 -11
  337. package/src/types/components/rating.ts +11 -11
  338. package/src/types/components/scroll-area.ts +23 -23
  339. package/src/types/components/scroll-to-top.ts +2 -2
  340. package/src/types/components/search.ts +29 -0
  341. package/src/types/components/select.ts +2 -1
  342. package/src/types/components/separator.ts +19 -19
  343. package/src/types/components/sidebar.ts +83 -72
  344. package/src/types/components/slideover.ts +31 -31
  345. package/src/types/components/slider.ts +2 -2
  346. package/src/types/components/speed-dial.ts +11 -11
  347. package/src/types/components/spinner.ts +25 -25
  348. package/src/types/components/splitter.ts +19 -19
  349. package/src/types/components/spoiler.ts +11 -11
  350. package/src/types/components/stepper.ts +11 -11
  351. package/src/types/components/{megamenu.ts → steps.ts} +17 -11
  352. package/src/types/components/sticky-surface.ts +19 -19
  353. package/src/types/components/switch.ts +41 -41
  354. package/src/types/components/table-of-contents.ts +39 -17
  355. package/src/types/components/tabs.ts +2 -1
  356. package/src/types/components/textarea.ts +2 -1
  357. package/src/types/components/theme-selector.ts +15 -15
  358. package/src/types/components/timeline.ts +11 -11
  359. package/src/types/components/toast.ts +6 -1
  360. package/src/types/components/tooltip.ts +23 -23
  361. package/src/types/components/tour.ts +11 -11
  362. package/src/types/components/tree.ts +11 -11
  363. package/src/types/components/user.ts +11 -11
  364. package/src/types/components/watermark.ts +11 -11
  365. package/src/types/components/window-mockup.ts +11 -11
  366. package/src/types/docs.ts +40 -0
  367. package/src/types/index.ts +151 -1
  368. package/src/types/theme.ts +11 -1
  369. package/src/utils/color.ts +165 -0
  370. package/src/utils/docs.ts +365 -189
  371. package/src/utils/headerStack.ts +115 -95
  372. package/src/utils/index.ts +7 -5
  373. package/src/utils/shortcuts.ts +322 -0
  374. package/src/components/TableOfContents.astro +0 -107
  375. package/src/components/astro/RLAAlert.astro +0 -93
  376. package/src/components/astro/RLABlogPost.astro +0 -7
  377. package/src/components/astro/RLABlogPosts.astro +0 -9
  378. package/src/components/astro/RLAChangelog.astro +0 -23
  379. package/src/components/astro/RLAMegamenu.astro +0 -23
  380. package/src/components/astro/RLAPosts.astro +0 -23
  381. package/src/plugins/index.ts +0 -2
  382. package/src/plugins/starlightDocsApi/components/ApiTheme.astro +0 -27
  383. package/src/plugins/starlightDocsApi/index.ts +0 -272
  384. package/src/styles/prism.css +0 -42
  385. package/src/themes/changelog.theme.ts +0 -13
  386. package/src/themes/posts.theme.ts +0 -13
  387. package/src/types/components/index.ts +0 -135
  388. package/src/types/components/posts.ts +0 -11
  389. /package/src/{plugins/starlightDocsApi → docs}/types.ts +0 -0
@@ -1,172 +1,200 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { ScrollToTopProps } from "../../types"
5
- import scrollToTopThemeDefault, { createScrollToTopTheme } from "../../themes/scroll-to-top.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
7
-
8
- const uiConfig = getUIConfig()
9
- const scrollToTopTheme = uiConfig.colors ? createScrollToTopTheme(uiConfig.colors) : scrollToTopThemeDefault
10
-
11
- const scrollToTop = scv(scrollToTopTheme)
12
-
13
- const {
14
- color = "primary",
15
- progressWidth = 6,
16
- duration = 0.1,
17
- threshold = 200,
18
- showProgress = false,
19
- theme,
20
- ui: uiProp,
21
- class: className,
22
- ...rest
23
- } = Astro.props as ScrollToTopProps
24
-
25
- const classes = resolveClasses(scrollToTop, { color, theme }, useUi("scrollToTop", uiProp), className)
26
-
27
- const circumference = 2 * Math.PI * 45
28
- const percentPx = circumference / 100
29
-
30
-
31
- ---
32
-
33
- <div
34
- class:list={["rla-scroll-to-top", "fixed bottom-6 right-6 z-50", classes.root]}
35
- data-threshold={threshold}
36
- data-duration={duration}
37
- data-circle-stroke-width={progressWidth}
38
- {...rest}
39
- >
40
- <button
41
- type="button"
42
- class={classes.button}
43
- aria-label="Scroll to top"
44
- data-scroll-to-top-button
45
- >
46
- <div class={classes.progressBase}>
47
- <svg class={classes.svg} viewBox="0 0 100 100" shape-rendering="geometricPrecision">
48
- <circle
49
- cx="50"
50
- cy="50"
51
- r="45"
52
- stroke={`var(--color-${color}-900)`}
53
- fill={`var(--color-${color}-950)`}
54
- stroke-width={progressWidth}
55
- stroke-dashoffset="0"
56
- stroke-linecap="round"
57
- class="gauge-secondary-stroke opacity-100"
58
- />
59
- {showProgress && (
60
- <circle
61
- cx="50"
62
- cy="50"
63
- r="45"
64
- fill="transparent"
65
- stroke={`var(--color-${color}-500)`}
66
- stroke-width={progressWidth}
67
- stroke-dashoffset="0"
68
- stroke-linecap="round"
69
- class="gauge-primary-stroke opacity-100"
70
- data-progress-circle
71
- />
72
- )}
73
- </svg>
74
- <div class={classes.iconContainer}>
75
- <svg
76
- xmlns="http://www.w3.org/2000/svg"
77
- width="24"
78
- height="24"
79
- viewBox="0 0 24 24"
80
- fill="none"
81
- stroke="currentColor"
82
- stroke-width="2"
83
- stroke-linecap="round"
84
- stroke-linejoin="round"
85
- class={classes.icon}
86
- >
87
- <path d="m5 12 7-7 7 7" />
88
- <path d="M12 19V5" />
89
- </svg>
90
- </div>
91
- </div>
92
- </button>
93
- </div>
94
-
95
- <script>
96
- document.querySelectorAll('.rla-scroll-to-top').forEach((el) => {
97
- const element = el as HTMLElement
98
- const button = element.querySelector('[data-scroll-to-top-button]') as HTMLButtonElement | null
99
- const progressCircle = element.querySelector('[data-progress-circle]') as SVGCircleElement | null
100
-
101
- if (!button) return
102
-
103
- const threshold = Number(element.dataset.threshold) || 200
104
-
105
- function updateScrollState() {
106
- const scrollTop = window.scrollY || document.documentElement.scrollTop
107
- const scrollHeight = document.documentElement.scrollHeight - window.innerHeight
108
- const scrollPercentage = scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0
109
-
110
- if (scrollTop > threshold) {
111
- element.classList.add('visible')
112
- } else {
113
- element.classList.remove('visible')
114
- }
115
-
116
- if (progressCircle) {
117
- const circumference = 2 * Math.PI * 45
118
- const percentPx = circumference / 100
119
- const duration = element.dataset.duration || '0.1'
120
- progressCircle.style.setProperty('--stroke-percent', scrollPercentage.toString())
121
- progressCircle.style.setProperty('--percent-to-px', `${percentPx}px`)
122
- progressCircle.style.setProperty('--circumference', circumference.toString())
123
- progressCircle.style.setProperty('--duration', `${duration}s`)
124
- }
125
- }
126
-
127
- button.addEventListener('click', () => {
128
- window.scrollTo({ top: 0, behavior: 'smooth' })
129
- })
130
-
131
- window.addEventListener('scroll', updateScrollState, { passive: true })
132
- updateScrollState()
133
- })
134
- </script>
135
-
136
- <style>
137
- .rla-scroll-to-top {
138
- opacity: 0;
139
- pointer-events: none;
140
- transition: opacity 0.3s ease-in-out;
141
- }
142
-
143
- .rla-scroll-to-top.visible {
144
- opacity: 1;
145
- pointer-events: auto;
146
- }
147
-
148
- .progress-circle-base {
149
- transform: translateZ(0);
150
- }
151
-
152
- .gauge-primary-stroke {
153
- stroke-dasharray: calc(var(--stroke-percent, 0) * var(--percent-to-px, 2.826px)) var(--circumference, 282.6);
154
- transition: stroke-dasharray var(--duration, 0.1s) ease, stroke var(--duration, 0.1s) ease;
155
- transform: rotate(-90deg);
156
- transform-origin: center;
157
- shape-rendering: geometricPrecision;
158
- }
159
-
160
- .gauge-secondary-stroke {
161
- stroke-dasharray: 282.6;
162
- transform: rotate(-90deg);
163
- transform-origin: center;
164
- }
165
-
166
- [data-progress-circle] {
167
- --stroke-percent: 0;
168
- --percent-to-px: 2.826px;
169
- --circumference: 282.6;
170
- --duration: 0.1s;
171
- }
172
- </style>
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ScrollToTopProps } from "../../types"
5
+ import scrollToTopThemeDefault, { createScrollToTopTheme } from "../../themes/scroll-to-top.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+
8
+ const uiConfig = getUIConfig()
9
+ const scrollToTopTheme = uiConfig.colors ? createScrollToTopTheme(uiConfig.colors) : scrollToTopThemeDefault
10
+
11
+ const scrollToTop = scv(scrollToTopTheme)
12
+
13
+ const {
14
+ color = "primary",
15
+ progressWidth = 6,
16
+ duration = 0.1,
17
+ threshold = 200,
18
+ showProgress = false,
19
+ theme,
20
+ ui: uiProp,
21
+ class: className,
22
+ ...rest
23
+ } = Astro.props as ScrollToTopProps
24
+
25
+ const classes = resolveClasses(scrollToTop, { color, theme }, useUi("scrollToTop", uiProp), className)
26
+
27
+ ---
28
+
29
+ <rla-scroll-to-top data-threshold={threshold} data-duration={duration} data-color={color} data-progress-width={progressWidth} {...rest}>
30
+ <div
31
+ class:list={["rla-scroll-to-top-inner", "fixed bottom-6 right-6 z-50", classes.root]}
32
+ >
33
+ <button
34
+ type="button"
35
+ class={classes.button}
36
+ aria-label="Scroll to top"
37
+ data-scroll-to-top-button
38
+ >
39
+ <div class={classes.progressBase}>
40
+ <div class="gauge-track"></div>
41
+ {showProgress && (
42
+ <div class="gauge-progress" data-gauge-progress></div>
43
+ )}
44
+ <div class={classes.iconContainer}>
45
+ <svg
46
+ xmlns="http://www.w3.org/2000/svg"
47
+ width="24"
48
+ height="24"
49
+ viewBox="0 0 24 24"
50
+ fill="none"
51
+ stroke="currentColor"
52
+ stroke-width="2"
53
+ stroke-linecap="round"
54
+ stroke-linejoin="round"
55
+ class={classes.icon}
56
+ >
57
+ <path d="m5 12 7-7 7 7" />
58
+ <path d="M12 19V5" />
59
+ </svg>
60
+ </div>
61
+ </div>
62
+ </button>
63
+ </div>
64
+ </rla-scroll-to-top>
65
+
66
+ <script>
67
+ function onClick() {
68
+ window.scrollTo({ top: 0, behavior: 'smooth' });
69
+ }
70
+
71
+ class RLAScrollToTop extends HTMLElement {
72
+ private cleanupScroll: (() => void) | null = null;
73
+ private styleEl: HTMLStyleElement | null = null;
74
+
75
+ connectedCallback() {
76
+ this.style.display = 'contents';
77
+ const button = this.querySelector('[data-scroll-to-top-button]');
78
+ const innerElement = this.querySelector('.rla-scroll-to-top-inner') as HTMLElement | null;
79
+
80
+ if (!button || !innerElement) return;
81
+
82
+ const id = ++RLAScrollToTop.instanceCounter;
83
+ const threshold = Number(this.dataset.threshold) || 200;
84
+ const color = this.dataset.color || 'primary';
85
+ const progressWidth = Number(this.dataset.progressWidth) || 6;
86
+ const gaugeBorderWidth = progressWidth * 0.5;
87
+ const nonce = (document.querySelector('meta[name="csp-nonce"]')?.getAttribute('content') ?? '');
88
+
89
+ const getStyleEl = () => {
90
+ if (!this.styleEl) {
91
+ this.styleEl = document.createElement('style');
92
+ if (nonce) this.styleEl.setAttribute('nonce', nonce);
93
+ document.head.appendChild(this.styleEl);
94
+ }
95
+ return this.styleEl;
96
+ };
97
+
98
+ const updateStyles = () => {
99
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
100
+ const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
101
+ const scrollPercentage = scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0;
102
+
103
+ if (scrollTop > threshold) {
104
+ innerElement.classList.add('visible');
105
+ } else {
106
+ innerElement.classList.remove('visible');
107
+ }
108
+
109
+ getStyleEl().textContent = `
110
+ .rla-scroll-to-top-inner[data-rla-instance="${id}"] .gauge-track {
111
+ border-width: ${gaugeBorderWidth}px;
112
+ border-color: var(--color-${color}-900);
113
+ background-color: #000;
114
+ }
115
+ .rla-scroll-to-top-inner[data-rla-instance="${id}"] .gauge-progress {
116
+ --gauge-progress: ${scrollPercentage};
117
+ --gauge-stroke-width: ${gaugeBorderWidth}px;
118
+ --gauge-color: var(--color-${color}-500);
119
+ }
120
+ `;
121
+ };
122
+
123
+ innerElement.dataset.rlaInstance = String(id);
124
+
125
+ button.addEventListener('click', onClick);
126
+
127
+ window.addEventListener('scroll', updateStyles, { passive: true });
128
+ updateStyles();
129
+
130
+ this.cleanupScroll = () => {
131
+ button.removeEventListener('click', onClick);
132
+ window.removeEventListener('scroll', updateStyles);
133
+ if (this.styleEl) {
134
+ this.styleEl.remove();
135
+ this.styleEl = null;
136
+ }
137
+ };
138
+ }
139
+
140
+ disconnectedCallback() {
141
+ if (this.cleanupScroll) {
142
+ this.cleanupScroll();
143
+ this.cleanupScroll = null;
144
+ }
145
+ }
146
+
147
+ static instanceCounter = 0;
148
+ }
149
+
150
+ if (!customElements.get('rla-scroll-to-top')) {
151
+ customElements.define('rla-scroll-to-top', RLAScrollToTop);
152
+ }
153
+ </script>
154
+
155
+ <style>
156
+ .rla-scroll-to-top-inner {
157
+ opacity: 0;
158
+ pointer-events: none;
159
+ transition: opacity 0.3s ease-in-out;
160
+ }
161
+
162
+ .rla-scroll-to-top-inner.visible {
163
+ opacity: 1;
164
+ pointer-events: auto;
165
+ }
166
+
167
+ .progress-circle-base {
168
+ position: relative;
169
+ transform: translateZ(0);
170
+ }
171
+
172
+ .gauge-track {
173
+ position: absolute;
174
+ inset: 0;
175
+ border-radius: 50%;
176
+ border-style: solid;
177
+ }
178
+
179
+ .gauge-progress {
180
+ position: absolute;
181
+ inset: 0;
182
+ border-radius: 50%;
183
+ background: conic-gradient(
184
+ from 0deg,
185
+ var(--gauge-color, var(--color-primary-500)) 0deg,
186
+ var(--gauge-color, var(--color-primary-500)) calc(var(--gauge-progress, 0) * 3.6deg),
187
+ transparent calc(var(--gauge-progress, 0) * 3.6deg)
188
+ );
189
+ -webkit-mask: radial-gradient(
190
+ circle closest-side,
191
+ transparent calc(100% - var(--gauge-stroke-width, 6px)),
192
+ #000 calc(100% - var(--gauge-stroke-width, 6px))
193
+ );
194
+ mask: radial-gradient(
195
+ circle closest-side,
196
+ transparent calc(100% - var(--gauge-stroke-width, 6px)),
197
+ #000 calc(100% - var(--gauge-stroke-width, 6px))
198
+ );
199
+ }
200
+ </style>
@@ -0,0 +1,282 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { SearchProps } from "../../types"
5
+ import searchThemeDefault, { createSearchTheme } from "../../themes/search.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+ import RLAInput from "./RLAInput.astro"
8
+ import RLAKbd from "./RLAKbd.astro"
9
+ import RLAButton from "./RLAButton.astro"
10
+
11
+ const uiConfig = getUIConfig()
12
+ const searchTheme = uiConfig.colors ? createSearchTheme() : searchThemeDefault
13
+
14
+ const search = scv(searchTheme)
15
+
16
+ const {
17
+ endpoint = "/api/search",
18
+ placeholder = "Search...",
19
+ messages = {},
20
+ ui: uiProp,
21
+ class: className,
22
+ ...rest
23
+ } = Astro.props as SearchProps
24
+
25
+ const classes = resolveClasses(search, {}, useUi("search", uiProp), className)
26
+
27
+ // Default messages
28
+ const searchPlaceholder = messages.searchPlaceholder || placeholder
29
+ const noResultsLabel = messages.noResultsLabel || "No results found"
30
+ const footerCloseHint = messages.footerCloseHint || "Escape to close"
31
+ const footerBackendHint = messages.footerBackendHint || "Postgres Full-Text Search"
32
+
33
+ // Generate unique IDs for this instance to avoid collisions if multiple search bars exist
34
+ const uniqueId = Math.random().toString(36).slice(2, 8)
35
+ const triggerId = `search-trigger-${uniqueId}`
36
+ const modalId = `search-modal-${uniqueId}`
37
+ const inputId = `search-input-${uniqueId}`
38
+ const resultsId = `search-results-${uniqueId}`
39
+ const emptyId = `search-empty-${uniqueId}`
40
+ ---
41
+
42
+ <rla-search
43
+ class:list={[classes.root, "rla-search-wrapper"]}
44
+ data-slot="root"
45
+ data-trigger-id={triggerId}
46
+ data-modal-id={modalId}
47
+ data-input-id={inputId}
48
+ data-results-id={resultsId}
49
+ data-empty-id={emptyId}
50
+ data-endpoint={endpoint}
51
+ {...rest}
52
+ >
53
+ {Astro.slots.has("trigger") ? (
54
+ <div id={triggerId} class="cursor-pointer">
55
+ <slot name="trigger" />
56
+ </div>
57
+ ) : (
58
+ <RLAButton
59
+ id={triggerId}
60
+ variant="ghost"
61
+ color="neutral"
62
+ square
63
+ aria-label="Open Search"
64
+ >
65
+ <span class="i-lucide-search w-5 h-5" />
66
+ </RLAButton>
67
+ )}
68
+
69
+ <!-- Search modal -->
70
+ <div id={modalId} class={classes.modal} data-slot="modal">
71
+ <div class={classes.dialog} data-slot="dialog">
72
+ <!-- Search header -->
73
+ <div class={classes.header} data-slot="header">
74
+ <RLAInput
75
+ variant="ghost"
76
+ type="text"
77
+ id={inputId}
78
+ placeholder={searchPlaceholder}
79
+ autocomplete="off"
80
+ ui={{
81
+ root: "relative flex items-center w-full",
82
+ input: "pl-8 pr-20 py-1.5 text-base outline-none text-white placeholder-neutral-500",
83
+ leading: "absolute left-0 text-neutral-400 flex items-center",
84
+ trailing: "absolute right-0 flex items-center gap-2"
85
+ }}
86
+ >
87
+ <span slot="leading" class={classes.headerIcon} />
88
+ <div slot="trailing" class="flex items-center gap-2">
89
+ <RLAKbd size="sm">Esc</RLAKbd>
90
+ <button id={`${modalId}-close`} class={classes.close} aria-label="Close search">
91
+ <span class={classes.closeIcon}></span>
92
+ </button>
93
+ </div>
94
+ </RLAInput>
95
+ </div>
96
+
97
+ <!-- Results list -->
98
+ <div id={resultsId} class={classes.results} data-slot="results"></div>
99
+
100
+ <!-- Empty state -->
101
+ <div id={emptyId} class={classes.empty} data-slot="empty">
102
+ {noResultsLabel}
103
+ </div>
104
+
105
+ <!-- Footer -->
106
+ <div class={classes.footer} data-slot="footer">
107
+ <span>{footerCloseHint}</span>
108
+ <span>{footerBackendHint}</span>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ </rla-search>
113
+
114
+ <script>
115
+ import { defineShortcuts } from "../../utils/shortcuts"
116
+
117
+ class RLASearch extends HTMLElement {
118
+ private searchCleanup: (() => void) | null = null;
119
+
120
+ connectedCallback() {
121
+ this.style.display = 'contents';
122
+ const triggerId = this.dataset.triggerId;
123
+ const modalId = this.dataset.modalId;
124
+ const inputId = this.dataset.inputId;
125
+ const resultsId = this.dataset.resultsId;
126
+ const emptyId = this.dataset.emptyId;
127
+ const endpoint = this.dataset.endpoint;
128
+
129
+ const trigger = this.querySelector(`#${triggerId}`);
130
+ const modal = this.querySelector(`#${modalId}`) as HTMLElement | null;
131
+ const closeBtn = this.querySelector(`#${modalId}-close`);
132
+ const input = this.querySelector(`#${inputId}`) as HTMLInputElement | null;
133
+ const resultsContainer = this.querySelector(`#${resultsId}`) as HTMLElement | null;
134
+ const emptyState = this.querySelector(`#${emptyId}`) as HTMLElement | null;
135
+
136
+ // Teleport modal to body to avoid containing block/transform clipping from header containers
137
+ if (modal && modal.parentNode !== document.body) {
138
+ document.body.appendChild(modal);
139
+ }
140
+
141
+ let escapeCleanup: (() => void) | null = null;
142
+
143
+ const openModal = () => {
144
+ modal?.classList.remove("hidden");
145
+ modal?.classList.add("flex");
146
+ input?.focus();
147
+ document.body.style.overflow = "hidden";
148
+
149
+ escapeCleanup = defineShortcuts({
150
+ escape: {
151
+ handler: () => closeModal(),
152
+ usingInput: true
153
+ }
154
+ });
155
+ };
156
+
157
+ const closeModal = () => {
158
+ modal?.classList.add("hidden");
159
+ modal?.classList.remove("flex");
160
+ document.body.style.overflow = "";
161
+ if (input) input.value = "";
162
+ if (resultsContainer) resultsContainer.innerHTML = "";
163
+ emptyState?.classList.add("hidden");
164
+
165
+ if (escapeCleanup) {
166
+ escapeCleanup();
167
+ escapeCleanup = null;
168
+ }
169
+ };
170
+
171
+ const onTriggerClick = () => openModal();
172
+ const onCloseClick = () => closeModal();
173
+ const onModalClick = (e: MouseEvent) => {
174
+ const target = e.target as HTMLElement | null;
175
+ if (target && (target === modal || !target.closest('[data-slot="dialog"]'))) {
176
+ closeModal();
177
+ }
178
+ };
179
+
180
+ trigger?.addEventListener("click", onTriggerClick);
181
+ closeBtn?.addEventListener("click", onCloseClick);
182
+ modal?.addEventListener("click", onModalClick);
183
+
184
+ // Register global shortcut key Cmd+K / Ctrl+K
185
+ const metaKCleanup = defineShortcuts({
186
+ meta_k: {
187
+ handler: () => openModal(),
188
+ label: "Open Search",
189
+ description: "Open the global site search modal",
190
+ category: "navigation"
191
+ }
192
+ });
193
+
194
+ let debounceTimer: any;
195
+ const onInput = () => {
196
+ clearTimeout(debounceTimer);
197
+ const query = input?.value.trim();
198
+ if (!query) {
199
+ if (resultsContainer) resultsContainer.innerHTML = "";
200
+ emptyState?.classList.add("hidden");
201
+ return;
202
+ }
203
+
204
+ debounceTimer = setTimeout(async () => {
205
+ try {
206
+ console.log("[Search UI] Fetching search results for:", query);
207
+ const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`);
208
+
209
+ if (!res.ok) {
210
+ throw new Error(`HTTP status: ${res.status}`);
211
+ }
212
+
213
+ const results = await res.json();
214
+ console.log("[Search UI] Received results:", results);
215
+
216
+ if (resultsContainer) resultsContainer.innerHTML = "";
217
+
218
+ if (!Array.isArray(results) || results.length === 0) {
219
+ emptyState?.classList.remove("hidden");
220
+ return;
221
+ }
222
+
223
+ emptyState?.classList.add("hidden");
224
+ results.forEach((item) => {
225
+ const div = document.createElement("a");
226
+ div.href = item.url || "#";
227
+ div.className = "flex flex-col gap-1 p-3 hover:bg-neutral-800 rounded-lg transition-colors border border-transparent hover:border-neutral-700 text-left decoration-none";
228
+
229
+ div.innerHTML = `
230
+ <div class="flex items-center justify-between">
231
+ <span class="text-sm font-semibold text-white">${item.title || "Untitled"}</span>
232
+ ${item.sourceType ? `<span class="text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded bg-neutral-800 text-neutral-400 font-mono">${item.sourceType}</span>` : ""}
233
+ </div>
234
+ ${item.snippet ? `<p class="text-xs text-neutral-400 line-clamp-2 m-0">${item.snippet}</p>` : ""}
235
+ `;
236
+ resultsContainer?.appendChild(div);
237
+ });
238
+ } catch (err) {
239
+ console.error("[Search UI] Search failed:", err);
240
+ if (resultsContainer) resultsContainer.innerHTML = "";
241
+ emptyState?.classList.remove("hidden");
242
+ }
243
+ }, 200);
244
+ };
245
+ input?.addEventListener("input", onInput);
246
+
247
+ this.searchCleanup = () => {
248
+ clearTimeout(debounceTimer);
249
+ trigger?.removeEventListener("click", onTriggerClick);
250
+ closeBtn?.removeEventListener("click", onCloseClick);
251
+ modal?.removeEventListener("click", onModalClick);
252
+ input?.removeEventListener("input", onInput);
253
+ if (escapeCleanup) escapeCleanup();
254
+ metaKCleanup();
255
+ if (modal && modal.parentNode === document.body) {
256
+ modal.remove();
257
+ }
258
+ };
259
+ }
260
+
261
+ disconnectedCallback() {
262
+ if (this.searchCleanup) {
263
+ this.searchCleanup();
264
+ this.searchCleanup = null;
265
+ }
266
+ }
267
+ }
268
+
269
+ if (!customElements.get('rla-search')) {
270
+ customElements.define('rla-search', RLASearch);
271
+ }
272
+ </script>
273
+
274
+ <style is:global>
275
+ #search-results mark {
276
+ background-color: rgba(168, 85, 247, 0.3) !important;
277
+ color: rgb(233, 213, 255) !important;
278
+ padding-left: 2px;
279
+ padding-right: 2px;
280
+ border-radius: 4px;
281
+ }
282
+ </style>