@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
@@ -0,0 +1,11 @@
1
+ import { onUnmounted } from "vue"
2
+ import { defineShortcuts } from "../utils/shortcuts"
3
+ import type { ShortcutsConfig, ShortcutsOptions } from "../utils/shortcuts"
4
+
5
+ export function useShortcuts(config: ShortcutsConfig, options?: ShortcutsOptions) {
6
+ const cleanup = defineShortcuts(config, options)
7
+ onUnmounted(() => {
8
+ cleanup()
9
+ })
10
+ return cleanup
11
+ }
@@ -1,42 +1,43 @@
1
- import { reactive } from "vue"
2
-
3
- export interface Toast {
4
- id?: string | number
5
- title?: string
6
- description?: string
7
- icon?: string
8
- color?: "primary" | "success" | "warning" | "error" | "info" | "neutral"
9
- timeout?: number
10
- callback?: () => void
11
- }
12
-
13
- const toasts = reactive<Toast[]>([])
14
-
15
- export function useToast() {
16
- const add = (toast: Toast) => {
17
- const id = toast.id || Date.now()
18
- const newToast = { ...toast, id }
19
- toasts.push(newToast)
20
-
21
- if (toast.timeout !== 0) {
22
- setTimeout(() => {
23
- remove(id)
24
- }, toast.timeout || 5000)
25
- }
26
-
27
- return newToast
28
- }
29
-
30
- const remove = (id: string | number) => {
31
- const index = toasts.findIndex((t) => t.id === id)
32
- if (index !== -1) {
33
- toasts.splice(index, 1)
34
- }
35
- }
36
-
37
- return {
38
- toasts,
39
- add,
40
- remove
41
- }
42
- }
1
+ import { reactive } from "vue"
2
+ import type { ThemeColor } from "../types"
3
+
4
+ export interface Toast {
5
+ id?: string | number
6
+ title?: string
7
+ description?: string
8
+ icon?: string
9
+ color?: ThemeColor
10
+ timeout?: number
11
+ callback?: () => void
12
+ }
13
+
14
+ const toasts = reactive<Toast[]>([])
15
+
16
+ export function useToast() {
17
+ const add = (toast: Toast) => {
18
+ const id = toast.id || Date.now()
19
+ const newToast = { ...toast, id }
20
+ toasts.push(newToast)
21
+
22
+ if (toast.timeout !== 0) {
23
+ setTimeout(() => {
24
+ remove(id)
25
+ }, toast.timeout || 5000)
26
+ }
27
+
28
+ return newToast
29
+ }
30
+
31
+ const remove = (id: string | number) => {
32
+ const index = toasts.findIndex((t) => t.id === id)
33
+ if (index !== -1) {
34
+ toasts.splice(index, 1)
35
+ }
36
+ }
37
+
38
+ return {
39
+ toasts,
40
+ add,
41
+ remove
42
+ }
43
+ }
@@ -1 +1,2 @@
1
1
  export * from "./site.config"
2
+ export * from "./security"
@@ -0,0 +1,227 @@
1
+ import type { AstroUserConfig } from "astro"
2
+
3
+ export type AstroSecurityConfig = NonNullable<AstroUserConfig["security"]>
4
+ export type AstroCspConfig = Exclude<NonNullable<AstroSecurityConfig["csp"]>, boolean>
5
+
6
+ export interface SecurityConfigOptions {
7
+ /**
8
+ * The base domain name for this project (e.g., "starter.rimelight.com") used to autoconfigure
9
+ * standard allowedDomains and img-src CDN targets.
10
+ */
11
+ domain: string
12
+ /**
13
+ * Additional Allowed Domains (appended to the default wildcard subdomains of `domain`)
14
+ */
15
+ allowedDomains?: AstroSecurityConfig["allowedDomains"]
16
+ /**
17
+ * Additional sources to allow for img-src directive
18
+ */
19
+ imgSrc?: string[]
20
+ /**
21
+ * Additional sources to allow for connect-src directive
22
+ */
23
+ connectSrc?: string[]
24
+ /**
25
+ * Additional sources to allow for frame-src directive
26
+ */
27
+ frameSrc?: string[]
28
+ /**
29
+ * Additional script resources
30
+ */
31
+ scriptResources?: string[]
32
+ /**
33
+ * Additional style resources
34
+ */
35
+ styleResources?: string[]
36
+ /**
37
+ * Enables the 'require-trusted-types-for' directive
38
+ */
39
+ trustedTypes?: boolean
40
+ /**
41
+ * Direct overrides for any security config fields
42
+ */
43
+ overrides?: Partial<Omit<AstroSecurityConfig, "csp">> & {
44
+ csp?: Partial<AstroCspConfig>
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Generates a standard, strictly configured Security/CSP object for Astro configurations with
50
+ * support for easy customization and additions per project.
51
+ *
52
+ * @example
53
+ * ;```ts
54
+ * // Default returned shape:
55
+ * {
56
+ * checkOrigin: true,
57
+ * allowedDomains: [
58
+ * {
59
+ * hostname: "**.domain.com",
60
+ * protocol: "https"
61
+ * }
62
+ * ],
63
+ * csp: {
64
+ * algorithm: "SHA-384",
65
+ * directives: [
66
+ * "default-src 'none'",
67
+ * "img-src 'self' data: https://cdn.domain.com https://i3.ytimg.com https://www.youtube.com https://www.youtube-nocookie.com",
68
+ * "font-src 'self'",
69
+ * "connect-src 'self' https://cloudflareinsights.com",
70
+ * "frame-ancestors 'none'",
71
+ * "frame-src https://www.youtube.com https://www.youtube-nocookie.com",
72
+ * "upgrade-insecure-requests",
73
+ * "base-uri 'self'",
74
+ * "form-action 'self'"
75
+ * ],
76
+ * scriptDirective: {
77
+ * resources: [
78
+ * "'self'",
79
+ * "https://static.cloudflareinsights.com",
80
+ * "https://betterlytics.io/analytics.js",
81
+ * "'inline-speculation-rules'"
82
+ * ]
83
+ * },
84
+ * styleDirective: {
85
+ * resources: [
86
+ * "'self'",
87
+ * "'sha256-SKuaOGnks7NAUq37nvw1PfGEE0lOAs5ERbiYRbGFIbw='"
88
+ * ]
89
+ * }
90
+ * }
91
+ * }
92
+ * ```
93
+ */
94
+ export function defineSecurity(options: SecurityConfigOptions): AstroSecurityConfig {
95
+ const { domain, overrides } = options
96
+ const domainWithWildcard = `**.${domain}`
97
+
98
+ // 1. Build default allowed domains
99
+ const allowedDomains = [
100
+ {
101
+ hostname: domainWithWildcard,
102
+ protocol: "https" as const
103
+ },
104
+ ...(options.allowedDomains || [])
105
+ ]
106
+
107
+ // 2. Build CSP directives
108
+ const imgSources = Array.from(
109
+ new Set([
110
+ "'self'",
111
+ "data:",
112
+ `https://cdn.${domain}`,
113
+ "https://i3.ytimg.com",
114
+ "https://www.youtube.com",
115
+ "https://www.youtube-nocookie.com",
116
+ ...(options.imgSrc || [])
117
+ ])
118
+ )
119
+
120
+ const connectSources = Array.from(
121
+ new Set(["'self'", "https://cloudflareinsights.com", ...(options.connectSrc || [])])
122
+ )
123
+
124
+ const frameSources = Array.from(
125
+ new Set([
126
+ "https://www.youtube.com",
127
+ "https://www.youtube-nocookie.com",
128
+ ...(options.frameSrc || [])
129
+ ])
130
+ )
131
+
132
+ const baseDirectives: AstroCspConfig["directives"] = [
133
+ "default-src 'none'",
134
+ `img-src ${imgSources.join(" ")}`,
135
+ "font-src 'self'",
136
+ `connect-src ${connectSources.join(" ")}`,
137
+ "frame-ancestors 'none'",
138
+ `frame-src ${frameSources.join(" ")}`,
139
+ "upgrade-insecure-requests",
140
+ "base-uri 'self'",
141
+ "form-action 'self'",
142
+ "object-src 'none'",
143
+ "manifest-src 'self'",
144
+ ...(options.trustedTypes ? ["require-trusted-types-for 'script'" as const] : [])
145
+ ]
146
+
147
+ // 3. Build script & style directives
148
+ const scriptResources = Array.from(
149
+ new Set([
150
+ "'self'",
151
+ "https://static.cloudflareinsights.com",
152
+ "https://betterlytics.io/analytics.js",
153
+ "'inline-speculation-rules'",
154
+ // Astro ClientRouter (View Transitions)
155
+ "'sha256-ZuMSxilKU+4KIM8LWna4lqBEKzd6WaiAjz6gamhm7zM='",
156
+ ...(options.scriptResources || [])
157
+ ])
158
+ )
159
+
160
+ const styleResources = Array.from(
161
+ new Set([
162
+ "'self'",
163
+ // Astro ClientRouter (View Transitions)
164
+ "'sha256-SKuaOGnks7NAUq37nvw1PfGEE0lOAs5ERbiYRbGFIbw='",
165
+ ...(options.styleResources || [])
166
+ ])
167
+ )
168
+
169
+ // 4. Build base SecurityConfig
170
+ const securityConfig: AstroSecurityConfig = {
171
+ checkOrigin: true,
172
+ allowedDomains,
173
+ csp: {
174
+ algorithm: "SHA-384",
175
+ directives: baseDirectives,
176
+ scriptDirective: {
177
+ resources: scriptResources
178
+ },
179
+ styleDirective: {
180
+ resources: styleResources
181
+ }
182
+ }
183
+ }
184
+
185
+ // 5. Merge overrides
186
+ if (overrides) {
187
+ const { csp, ...restOverrides } = overrides
188
+ Object.assign(securityConfig, restOverrides)
189
+ if (csp && typeof securityConfig.csp === "object" && securityConfig.csp !== null) {
190
+ const currentCsp = securityConfig.csp
191
+ const mergedCsp: AstroCspConfig = {
192
+ ...currentCsp,
193
+ ...csp
194
+ }
195
+
196
+ if (csp.scriptDirective || currentCsp.scriptDirective) {
197
+ mergedCsp.scriptDirective = {
198
+ ...currentCsp.scriptDirective,
199
+ ...csp.scriptDirective,
200
+ resources: Array.from(
201
+ new Set([
202
+ ...(currentCsp.scriptDirective?.resources || []),
203
+ ...(csp.scriptDirective?.resources || [])
204
+ ])
205
+ )
206
+ }
207
+ }
208
+
209
+ if (csp.styleDirective || currentCsp.styleDirective) {
210
+ mergedCsp.styleDirective = {
211
+ ...currentCsp.styleDirective,
212
+ ...csp.styleDirective,
213
+ resources: Array.from(
214
+ new Set([
215
+ ...(currentCsp.styleDirective?.resources || []),
216
+ ...(csp.styleDirective?.resources || [])
217
+ ])
218
+ )
219
+ }
220
+ }
221
+
222
+ securityConfig.csp = mergedCsp
223
+ }
224
+ }
225
+
226
+ return securityConfig
227
+ }
@@ -24,4 +24,5 @@ export interface SiteConfig {
24
24
  maxDescriptionLength: number
25
25
  authorHandle?: string
26
26
  }
27
+ ui?: Record<string, any>
27
28
  }
@@ -0,0 +1,147 @@
1
+ ---
2
+ import RLATimeline from "../../components/astro/RLATimeline.astro"
3
+ import { scv } from "css-variants"
4
+ import { useUi, resolveClasses } from "../../utils"
5
+ import timelineThemeDefault, { createTimelineTheme } from "../../themes/timeline.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+
8
+ interface Props {
9
+ component: string
10
+ ui?: any
11
+ class?: any
12
+ }
13
+
14
+ const { component, ui: uiProp, class: className } = Astro.props
15
+
16
+ const uiConfig = getUIConfig()
17
+ const timelineTheme = uiConfig.colors ? createTimelineTheme() : timelineThemeDefault
18
+ const timeline = scv(timelineTheme)
19
+ const classes = resolveClasses(timeline, {}, useUi("timeline", uiProp), className);
20
+ ---
21
+
22
+ <div class="api-changelog-container group" data-component={component} data-theme-classes={JSON.stringify(classes)}>
23
+ <!-- Loading skeleton -->
24
+ <div class="api-changelog-loading py-6 flex flex-col gap-4">
25
+ <div class="animate-pulse h-4 bg-gray-800 rounded w-1/4"></div>
26
+ <div class="animate-pulse h-3 bg-gray-850 rounded w-full"></div>
27
+ <div class="animate-pulse h-3 bg-gray-850 rounded w-5/6"></div>
28
+ </div>
29
+
30
+ <!-- Timeline Content -->
31
+ <div class="api-changelog-content hidden">
32
+ <RLATimeline ui={uiProp} class={className}>
33
+ <!-- Dynamic timeline items insert here -->
34
+ <div class="api-changelog-list flex flex-col space-y-8"></div>
35
+ </RLATimeline>
36
+ </div>
37
+
38
+ <div class="api-changelog-empty hidden text-sm italic text-gray-500 py-2">
39
+ No recent changes found.
40
+ </div>
41
+ </div>
42
+
43
+ <script>
44
+ function escapeHtml(str: string): string {
45
+ return str
46
+ .replace(/&/g, "&amp;")
47
+ .replace(/</g, "&lt;")
48
+ .replace(/>/g, "&gt;")
49
+ .replace(/"/g, "&quot;")
50
+ .replace(/'/g, "&#039;");
51
+ }
52
+
53
+ async function loadChangelog() {
54
+ if (typeof document === "undefined") return;
55
+ const containers = document.querySelectorAll('.api-changelog-container');
56
+
57
+ await Promise.all(
58
+ Array.from(containers).map(async (container) => {
59
+ if (container.getAttribute('data-changelog-ready') === 'true') return;
60
+ container.setAttribute('data-changelog-ready', 'true');
61
+
62
+ const component = container.getAttribute('data-component');
63
+ const themeClassesJson = container.getAttribute('data-theme-classes');
64
+ const themeClasses = themeClassesJson ? JSON.parse(themeClassesJson) : {};
65
+
66
+ const loadingEl = container.querySelector('.api-changelog-loading') as HTMLElement;
67
+ const contentEl = container.querySelector('.api-changelog-content') as HTMLElement;
68
+ const listEl = container.querySelector('.api-changelog-list') as HTMLElement;
69
+ const emptyEl = container.querySelector('.api-changelog-empty') as HTMLElement;
70
+
71
+ if (!component || !loadingEl || !contentEl || !listEl || !emptyEl) return;
72
+
73
+ try {
74
+ const res = await fetch(`/api/github/changelog?component=${component}`);
75
+ if (!res.ok) throw new Error();
76
+ const data = await res.json();
77
+
78
+ loadingEl.classList.add('hidden');
79
+
80
+ if (!data || data.length === 0) {
81
+ emptyEl.classList.remove('hidden');
82
+ return;
83
+ }
84
+
85
+ let html = '';
86
+ for (const item of data) {
87
+ const dateStr = item.published_at
88
+ ? new Date(item.published_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
89
+ : 'Unreleased';
90
+
91
+ html += `
92
+ <div class="${themeClasses.node || 'relative timeline-node'}">
93
+ <!-- Dot Indicator -->
94
+ <span class="${themeClasses.dot || 'absolute -left-[33px] top-[2px] flex h-4 w-4 items-center justify-center rounded-full bg-gray-950 ring-2 ring-gray-800'}">
95
+ <span class="${themeClasses.dotInner || 'h-2 w-2 rounded-full bg-primary-500'}"></span>
96
+ </span>
97
+
98
+ <div class="${themeClasses.header || 'flex items-center justify-between gap-4 mb-3'}">
99
+ <div class="flex items-center gap-2">
100
+ <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold bg-primary-500/10 text-primary-400 border border-primary-500/20">
101
+ ${escapeHtml(item.tag === 'unreleased' ? 'Soon' : item.tag)}
102
+ </span>
103
+ </div>
104
+
105
+ <time class="text-xs text-gray-500 font-normal">
106
+ ${escapeHtml(dateStr)}
107
+ </time>
108
+ </div>
109
+
110
+ <ul class="${themeClasses.content || 'space-y-2 text-sm text-gray-400'}">
111
+ ${item.commits.map((commit: any) => {
112
+ const cleanedMessage = commit.message
113
+ .replace(/#(\d+)/g, '<a href="https://github.com/Rimelight-Entertainment/rimelight/issues/$1" target="_blank" class="text-primary-400 hover:underline">#$1</a>')
114
+ .replace(/`(.*?)`/g, '<code class="text-xs px-1 bg-gray-900 border border-gray-800 rounded font-mono text-gray-300">$1</code>');
115
+
116
+ return `
117
+ <li class="flex items-start gap-2">
118
+ <a href="https://github.com/Rimelight-Entertainment/rimelight/commit/${commit.sha}" target="_blank" class="font-mono text-xs text-gray-500 hover:text-gray-300 hover:underline shrink-0 pt-0.5">
119
+ ${commit.sha.slice(0, 7)}
120
+ </a>
121
+ <span class="text-gray-300">
122
+ ${cleanedMessage}
123
+ </span>
124
+ </li>
125
+ `;
126
+ }).join('')}
127
+ </ul>
128
+ </div>
129
+ `;
130
+ }
131
+
132
+ listEl.innerHTML = html;
133
+ contentEl.classList.remove('hidden');
134
+ } catch (err) {
135
+ loadingEl.classList.add('hidden');
136
+ emptyEl.textContent = 'Failed to load changelog.';
137
+ emptyEl.classList.remove('hidden');
138
+ }
139
+ })
140
+ );
141
+ }
142
+
143
+ if (typeof document !== 'undefined') {
144
+ loadChangelog();
145
+ document.addEventListener('astro:after-swap', loadChangelog);
146
+ }
147
+ </script>
@@ -29,14 +29,14 @@ const emits = compMeta?.emits ?? []
29
29
  {emits.map((emit: EmitMeta) => (
30
30
  <tr class="border-b border-gray-100 dark:border-gray-800">
31
31
  <td class="py-2 px-3">
32
- <code class="text-sm bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded">
32
+ <span class="font-mono text-sm">
33
33
  {emit.name}
34
- </code>
34
+ </span>
35
35
  </td>
36
36
  <td class="py-2 px-3">
37
- <code class="text-xs bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded font-mono">
37
+ <span class="font-mono text-xs text-gray-600 dark:text-gray-400">
38
38
  {emit.type}
39
- </code>
39
+ </span>
40
40
  </td>
41
41
  </tr>
42
42
  ))}
@@ -33,15 +33,15 @@ const props = filterProps(compMeta?.props ?? [], filterOpts)
33
33
  <tbody>
34
34
  {props.map((prop: PropMeta) => (
35
35
  <tr>
36
- <td><code>{prop.name}</code></td>
37
- <td><code>{prop.type}</code></td>
36
+ <td><span class="font-mono text-sm">{prop.name}</span></td>
37
+ <td><span class="font-mono text-xs text-gray-600 dark:text-gray-400">{prop.type}</span></td>
38
38
  <td>{prop.required ? "Yes" : "No"}</td>
39
- <td>{prop.default !== undefined ? <code>{prop.default}</code> : "—"}</td>
39
+ <td>{prop.default !== undefined ? <span class="font-mono text-xs text-gray-600 dark:text-gray-400">{prop.default}</span> : "—"}</td>
40
40
  <td>{prop.description || "—"}</td>
41
41
  </tr>
42
42
  ))}
43
43
  </tbody>
44
44
  </table>
45
45
  ) : (
46
- <p>No props to display.</p>
46
+ <p class="text-sm italic text-gray-500">No props to display.</p>
47
47
  )}
@@ -29,15 +29,15 @@ const slots = compMeta?.slots ?? []
29
29
  {slots.map((slot: SlotMeta) => (
30
30
  <tr class="border-b border-gray-100 dark:border-gray-800">
31
31
  <td class="py-2 px-3">
32
- <code class="text-sm bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded">
32
+ <span class="font-mono text-sm">
33
33
  {slot.name}
34
- </code>
34
+ </span>
35
35
  </td>
36
36
  <td class="py-2 px-3">
37
37
  {Object.keys(slot.bindings).length > 0 ? (
38
- <code class="text-xs bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded font-mono">
38
+ <span class="font-mono text-xs text-gray-600 dark:text-gray-400">
39
39
  {Object.values(slot.bindings)[0]}
40
- </code>
40
+ </span>
41
41
  ) : (
42
42
  <span class="text-gray-400">-</span>
43
43
  )}
@@ -0,0 +1,100 @@
1
+ ---
2
+ import type { ComponentMetaMap } from "../types"
3
+ import { generateThemeCode } from "../utils"
4
+ import meta from "virtual:rimelight-ui-docs-meta"
5
+
6
+ interface Props {
7
+ component: string
8
+ }
9
+
10
+ const { component } = Astro.props
11
+
12
+ const allMeta = meta as unknown as ComponentMetaMap
13
+ const compMeta = allMeta[component]
14
+
15
+ const theme = compMeta?.theme ?? null
16
+ const themeCode = theme ? generateThemeCode(component, theme) : null
17
+ ---
18
+
19
+ {themeCode ? (
20
+ <div class="api-theme-container relative border border-gray-800 rounded-lg overflow-hidden group mb-6" data-component={component}>
21
+ <div class="api-theme-collapse overflow-hidden max-h-[240px] relative transition-[max-height] duration-300 ease-in-out">
22
+ <div class="expressive-code m-0 border-0 rounded-none">
23
+ <figure class="frame m-0 border-0">
24
+ <pre class="language-ts overflow-x-auto m-0 border-0 rounded-none bg-gray-900"><code class="language-ts m-0">{themeCode}</code></pre>
25
+ </figure>
26
+ </div>
27
+
28
+ {/* Gradient Fade Overlay */}
29
+ <div class="api-theme-fade absolute bottom-0 left-0 right-0 h-20 bg-gradient-to-t from-gray-950 to-transparent pointer-events-none transition-opacity duration-300"></div>
30
+ </div>
31
+
32
+ {/* Toggle Button Container */}
33
+ <div class="api-theme-trigger-bar absolute bottom-0 left-0 right-0 flex justify-center pb-3 bg-gradient-to-t from-gray-950/90 via-gray-950/70 to-transparent pt-12">
34
+ <button class="api-theme-btn px-4 py-1.5 text-xs font-semibold text-white bg-gray-800 hover:bg-gray-700 border border-gray-700 hover:border-gray-650 rounded-md shadow-md transition-all duration-200 cursor-pointer">
35
+ Show theme config
36
+ </button>
37
+ </div>
38
+ </div>
39
+ ) : (
40
+ <p class="text-sm italic text-gray-500">No theme data available.</p>
41
+ )}
42
+
43
+ <script>
44
+ function setupThemeCollapser() {
45
+ if (typeof document === 'undefined') return;
46
+ const containers = document.querySelectorAll('.api-theme-container');
47
+ containers.forEach(container => {
48
+ if (container.getAttribute('data-collapser-ready') === 'true') return;
49
+ container.setAttribute('data-collapser-ready', 'true');
50
+
51
+ const collapseWrapper = container.querySelector('.api-theme-collapse') as HTMLElement;
52
+ const fadeOverlay = container.querySelector('.api-theme-fade') as HTMLElement;
53
+ const btn = container.querySelector('.api-theme-btn') as HTMLButtonElement;
54
+ const triggerBar = container.querySelector('.api-theme-trigger-bar') as HTMLElement;
55
+
56
+ if (!collapseWrapper || !btn || !triggerBar || !fadeOverlay) return;
57
+
58
+ // Let code blocks load and measure scrollHeight
59
+ const checkAndSetup = () => {
60
+ const scrollHeight = collapseWrapper.scrollHeight;
61
+ if (scrollHeight <= 240) {
62
+ collapseWrapper.style.maxHeight = 'none';
63
+ fadeOverlay.style.display = 'none';
64
+ triggerBar.style.display = 'none';
65
+ return;
66
+ }
67
+
68
+ let isExpanded = false;
69
+
70
+ btn.addEventListener('click', () => {
71
+ isExpanded = !isExpanded;
72
+ if (isExpanded) {
73
+ collapseWrapper.style.maxHeight = `${collapseWrapper.scrollHeight}px`;
74
+ btn.textContent = 'Hide theme config';
75
+ fadeOverlay.style.opacity = '0';
76
+ triggerBar.classList.remove('absolute', 'bottom-0');
77
+ triggerBar.classList.add('relative', 'bg-gray-950', 'py-3', 'border-t', 'border-gray-800');
78
+ triggerBar.style.paddingTop = '12px';
79
+ } else {
80
+ collapseWrapper.style.maxHeight = '240px';
81
+ btn.textContent = 'Show theme config';
82
+ fadeOverlay.style.opacity = '1';
83
+ triggerBar.classList.add('absolute', 'bottom-0');
84
+ triggerBar.classList.remove('relative', 'bg-gray-950', 'py-3', 'border-t', 'border-gray-800');
85
+ triggerBar.style.paddingTop = '48px';
86
+ container.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
87
+ }
88
+ });
89
+ };
90
+
91
+ // Delay slightly to ensure fonts/expressive code are rendered
92
+ setTimeout(checkAndSetup, 150);
93
+ });
94
+ }
95
+
96
+ if (typeof document !== 'undefined') {
97
+ setupThemeCollapser();
98
+ document.addEventListener('astro:after-swap', setupThemeCollapser);
99
+ }
100
+ </script>