@rimelight/ui 0.0.33 → 0.0.34

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 (282) hide show
  1. package/README.md +157 -157
  2. package/package.json +105 -105
  3. package/src/components/astro/RLAAspectRatio.astro +2 -2
  4. package/src/components/astro/RLAButton.astro +141 -139
  5. package/src/components/astro/RLAChart.astro +19 -34
  6. package/src/components/astro/RLAHead.astro +427 -196
  7. package/src/components/astro/RLAHeader.astro +66 -59
  8. package/src/components/astro/RLAImage.astro +61 -19
  9. package/src/components/astro/RLALink.astro +22 -23
  10. package/src/components/astro/RLALinkGroup.astro +66 -4
  11. package/src/components/astro/RLALocaleSelector.astro +136 -113
  12. package/src/components/astro/RLAMain.astro +8 -3
  13. package/src/components/astro/RLAMarquee.astro +9 -2
  14. package/src/components/astro/RLANavigationMenu.astro +245 -56
  15. package/src/components/astro/RLAPagination.astro +2 -4
  16. package/src/components/astro/RLAProgress.astro +8 -2
  17. package/src/components/astro/RLASelect.astro +38 -24
  18. package/src/components/astro/RLASlideover.astro +66 -1
  19. package/src/components/astro/RLASlider.astro +14 -14
  20. package/src/components/astro/RLASplitter.astro +14 -2
  21. package/src/components/astro/RLAStickySurface.astro +9 -2
  22. package/src/components/vue/RLVCheckbox.vue +68 -68
  23. package/src/components/vue/RLVForm.vue +44 -44
  24. package/src/components/vue/RLVFormField.vue +58 -58
  25. package/src/components/vue/RLVInput.vue +93 -93
  26. package/src/components/vue/RLVPost.vue +63 -63
  27. package/src/components/vue/RLVPosts.vue +21 -21
  28. package/src/components/vue/RLVToast.vue +68 -68
  29. package/src/components/vue/RLVToaster.vue +29 -29
  30. package/src/composables/index.ts +3 -3
  31. package/src/composables/useHeaderStore.ts +13 -14
  32. package/src/composables/useScrollToTop.ts +62 -62
  33. package/src/composables/useToast.ts +43 -42
  34. package/src/config/index.ts +1 -0
  35. package/src/config/security.ts +220 -0
  36. package/src/integrations/ui.ts +199 -199
  37. package/src/middleware/security.ts +75 -15
  38. package/src/plugins/index.ts +2 -2
  39. package/src/plugins/starlightDocsApi/index.ts +272 -272
  40. package/src/presets/defaults.ts +297 -297
  41. package/src/presets/index.ts +683 -637
  42. package/src/styles/index.css +160 -160
  43. package/src/themes/3d-hover.theme.ts +13 -13
  44. package/src/themes/accordion.theme.ts +13 -13
  45. package/src/themes/alert.theme.ts +131 -125
  46. package/src/themes/app.theme.ts +13 -13
  47. package/src/themes/audio.theme.ts +13 -13
  48. package/src/themes/avatar.theme.ts +84 -84
  49. package/src/themes/badge.theme.ts +169 -163
  50. package/src/themes/banner.theme.ts +13 -13
  51. package/src/themes/browser-mockup.theme.ts +13 -13
  52. package/src/themes/button.theme.ts +224 -202
  53. package/src/themes/calendar.theme.ts +13 -13
  54. package/src/themes/card.theme.ts +42 -42
  55. package/src/themes/changelog.theme.ts +13 -13
  56. package/src/themes/chart.theme.ts +22 -22
  57. package/src/themes/chat-message.theme.ts +13 -13
  58. package/src/themes/chat-messages.theme.ts +13 -13
  59. package/src/themes/chat-palette.theme.ts +13 -13
  60. package/src/themes/chat-prompt-submit.theme.ts +13 -13
  61. package/src/themes/chat-prompt.theme.ts +13 -13
  62. package/src/themes/chat-reasoning.theme.ts +13 -13
  63. package/src/themes/chat-shimmer.theme.ts +13 -13
  64. package/src/themes/chat-tool.theme.ts +13 -13
  65. package/src/themes/chat.theme.ts +13 -13
  66. package/src/themes/checkbox.theme.ts +50 -50
  67. package/src/themes/chip.theme.ts +74 -74
  68. package/src/themes/color-picker.theme.ts +13 -13
  69. package/src/themes/command-palette.theme.ts +13 -13
  70. package/src/themes/compare.theme.ts +13 -13
  71. package/src/themes/confirm.theme.ts +48 -48
  72. package/src/themes/container.theme.ts +13 -13
  73. package/src/themes/context-menu.theme.ts +13 -13
  74. package/src/themes/dashboard-group.theme.ts +13 -13
  75. package/src/themes/dashboard-navbar.theme.ts +13 -13
  76. package/src/themes/dashboard-panel.theme.ts +13 -13
  77. package/src/themes/dashboard-resize-handle.theme.ts +13 -13
  78. package/src/themes/dashboard-search-button.theme.ts +13 -13
  79. package/src/themes/dashboard-search.theme.ts +13 -13
  80. package/src/themes/dashboard-sidebar-collapse.theme.ts +13 -13
  81. package/src/themes/dashboard-sidebar-toggle.theme.ts +13 -13
  82. package/src/themes/dashboard-sidebar.theme.ts +13 -13
  83. package/src/themes/dashboard-toolbar.theme.ts +13 -13
  84. package/src/themes/dock.theme.ts +13 -13
  85. package/src/themes/drawer.theme.ts +61 -61
  86. package/src/themes/dropdown-menu.theme.ts +29 -29
  87. package/src/themes/editor.theme.ts +13 -13
  88. package/src/themes/empty.theme.ts +13 -13
  89. package/src/themes/error.theme.ts +13 -13
  90. package/src/themes/field-group.theme.ts +24 -24
  91. package/src/themes/fieldset.theme.ts +13 -13
  92. package/src/themes/floating-action.theme.ts +13 -13
  93. package/src/themes/footer.theme.ts +30 -30
  94. package/src/themes/form.theme.ts +13 -13
  95. package/src/themes/gallery.theme.ts +13 -13
  96. package/src/themes/head.theme.ts +13 -13
  97. package/src/themes/header.theme.ts +45 -46
  98. package/src/themes/icon.theme.ts +23 -23
  99. package/src/themes/image.theme.ts +23 -19
  100. package/src/themes/input-date.theme.ts +13 -13
  101. package/src/themes/input-menu.theme.ts +35 -35
  102. package/src/themes/input-number.theme.ts +13 -13
  103. package/src/themes/input-tags.theme.ts +13 -13
  104. package/src/themes/input-time.theme.ts +13 -13
  105. package/src/themes/input.theme.ts +42 -42
  106. package/src/themes/kbd.theme.ts +95 -89
  107. package/src/themes/knob.theme.ts +13 -13
  108. package/src/themes/link-group.theme.ts +32 -32
  109. package/src/themes/link.theme.ts +13 -13
  110. package/src/themes/listbox.theme.ts +13 -13
  111. package/src/themes/locale-selector.theme.ts +49 -49
  112. package/src/themes/logo.theme.ts +13 -13
  113. package/src/themes/main.theme.ts +13 -13
  114. package/src/themes/megamenu.theme.ts +13 -13
  115. package/src/themes/meter.theme.ts +13 -13
  116. package/src/themes/navigation-menu.theme.ts +44 -27
  117. package/src/themes/page-aside.theme.ts +13 -13
  118. package/src/themes/page-body.theme.ts +13 -13
  119. package/src/themes/page-header.theme.ts +13 -13
  120. package/src/themes/page-section.theme.ts +187 -187
  121. package/src/themes/page.theme.ts +13 -13
  122. package/src/themes/password.theme.ts +13 -13
  123. package/src/themes/phone-mockup.theme.ts +13 -13
  124. package/src/themes/placeholder.theme.ts +15 -15
  125. package/src/themes/post.theme.ts +33 -33
  126. package/src/themes/pricing-plan.theme.ts +13 -13
  127. package/src/themes/pricing-table.theme.ts +13 -13
  128. package/src/themes/progress.theme.ts +38 -38
  129. package/src/themes/prose.theme.ts +13 -13
  130. package/src/themes/qr-code.theme.ts +13 -13
  131. package/src/themes/quote.theme.ts +13 -13
  132. package/src/themes/radio-group.theme.ts +13 -13
  133. package/src/themes/rating.theme.ts +13 -13
  134. package/src/themes/scroll-area.theme.ts +26 -26
  135. package/src/themes/scroll-to-top.theme.ts +52 -52
  136. package/src/themes/select.theme.ts +29 -29
  137. package/src/themes/separator.theme.ts +147 -147
  138. package/src/themes/sidebar.theme.ts +38 -38
  139. package/src/themes/skeleton.theme.ts +21 -21
  140. package/src/themes/slideover.theme.ts +4 -4
  141. package/src/themes/slider.theme.ts +36 -36
  142. package/src/themes/speed-dial.theme.ts +13 -13
  143. package/src/themes/spinner.theme.ts +34 -34
  144. package/src/themes/splitter.theme.ts +23 -23
  145. package/src/themes/spoiler.theme.ts +13 -13
  146. package/src/themes/stepper.theme.ts +13 -13
  147. package/src/themes/switch.theme.ts +67 -67
  148. package/src/themes/table-of-contents.theme.ts +48 -48
  149. package/src/themes/tabs.theme.ts +52 -52
  150. package/src/themes/textarea.theme.ts +27 -27
  151. package/src/themes/theme-selector.theme.ts +15 -15
  152. package/src/themes/timeline.theme.ts +13 -13
  153. package/src/themes/toast.theme.ts +31 -31
  154. package/src/themes/tooltip.theme.ts +28 -28
  155. package/src/themes/tour.theme.ts +13 -13
  156. package/src/themes/tree.theme.ts +13 -13
  157. package/src/themes/user.theme.ts +13 -13
  158. package/src/themes/video.theme.ts +17 -17
  159. package/src/themes/watermark.theme.ts +13 -13
  160. package/src/themes/window-mockup.theme.ts +13 -13
  161. package/src/types/components/3d-hover.ts +11 -11
  162. package/src/types/components/alert.ts +2 -2
  163. package/src/types/components/app.ts +11 -11
  164. package/src/types/components/audio.ts +11 -11
  165. package/src/types/components/avatar-group.ts +11 -11
  166. package/src/types/components/avatar.ts +60 -60
  167. package/src/types/components/badge.ts +2 -2
  168. package/src/types/components/banner.ts +11 -11
  169. package/src/types/components/browser-mockup.ts +11 -11
  170. package/src/types/components/button.ts +74 -81
  171. package/src/types/components/calendar.ts +11 -11
  172. package/src/types/components/changelog.ts +11 -11
  173. package/src/types/components/chart.ts +2 -1
  174. package/src/types/components/chat-message.ts +11 -11
  175. package/src/types/components/chat-messages.ts +11 -11
  176. package/src/types/components/chat-palette.ts +11 -11
  177. package/src/types/components/chat-prompt-submit.ts +11 -11
  178. package/src/types/components/chat-prompt.ts +11 -11
  179. package/src/types/components/chat-reasoning.ts +11 -11
  180. package/src/types/components/chat-shimmer.ts +11 -11
  181. package/src/types/components/chat-tool.ts +11 -11
  182. package/src/types/components/chat.ts +11 -11
  183. package/src/types/components/checkbox.ts +2 -2
  184. package/src/types/components/chip.ts +17 -17
  185. package/src/types/components/collapsible.ts +2 -1
  186. package/src/types/components/color-picker.ts +11 -11
  187. package/src/types/components/command-palette.ts +11 -11
  188. package/src/types/components/compare.ts +11 -11
  189. package/src/types/components/container.ts +17 -17
  190. package/src/types/components/context-menu.ts +11 -11
  191. package/src/types/components/dashboard-group.ts +11 -11
  192. package/src/types/components/dashboard-navbar.ts +11 -11
  193. package/src/types/components/dashboard-panel.ts +11 -11
  194. package/src/types/components/dashboard-resize-handle.ts +11 -11
  195. package/src/types/components/dashboard-search-button.ts +11 -11
  196. package/src/types/components/dashboard-search.ts +11 -11
  197. package/src/types/components/dashboard-sidebar-collapse.ts +11 -11
  198. package/src/types/components/dashboard-sidebar-toggle.ts +11 -11
  199. package/src/types/components/dashboard-sidebar.ts +11 -11
  200. package/src/types/components/dashboard-toolbar.ts +11 -11
  201. package/src/types/components/dock.ts +11 -11
  202. package/src/types/components/dropdown-menu.ts +2 -1
  203. package/src/types/components/editor.ts +11 -11
  204. package/src/types/components/empty.ts +11 -11
  205. package/src/types/components/error.ts +11 -11
  206. package/src/types/components/fieldset.ts +11 -11
  207. package/src/types/components/file-upload.ts +2 -1
  208. package/src/types/components/floating-action.ts +11 -11
  209. package/src/types/components/form.ts +19 -19
  210. package/src/types/components/gallery.ts +11 -11
  211. package/src/types/components/icon.ts +19 -19
  212. package/src/types/components/image.ts +32 -28
  213. package/src/types/components/index.ts +134 -135
  214. package/src/types/components/input-date.ts +11 -11
  215. package/src/types/components/input-menu.ts +44 -43
  216. package/src/types/components/input-number.ts +11 -11
  217. package/src/types/components/input-pin.ts +36 -35
  218. package/src/types/components/input-tags.ts +11 -11
  219. package/src/types/components/input-time.ts +11 -11
  220. package/src/types/components/input.ts +2 -2
  221. package/src/types/components/knob.ts +11 -11
  222. package/src/types/components/link-group.ts +45 -23
  223. package/src/types/components/link.ts +4 -0
  224. package/src/types/components/listbox.ts +11 -11
  225. package/src/types/components/locale-selector.ts +33 -33
  226. package/src/types/components/logo.ts +32 -31
  227. package/src/types/components/main.ts +17 -17
  228. package/src/types/components/megamenu.ts +11 -11
  229. package/src/types/components/meter.ts +11 -11
  230. package/src/types/components/modal.ts +39 -39
  231. package/src/types/components/navigation-menu.ts +59 -54
  232. package/src/types/components/page-aside.ts +11 -11
  233. package/src/types/components/page-body.ts +11 -11
  234. package/src/types/components/page-header.ts +11 -11
  235. package/src/types/components/page.ts +11 -11
  236. package/src/types/components/password.ts +11 -11
  237. package/src/types/components/phone-mockup.ts +5 -5
  238. package/src/types/components/pin-input.ts +11 -11
  239. package/src/types/components/popover.ts +23 -23
  240. package/src/types/components/post.ts +35 -35
  241. package/src/types/components/pricing-plan.ts +11 -11
  242. package/src/types/components/pricing-table.ts +11 -11
  243. package/src/types/components/progress.ts +33 -33
  244. package/src/types/components/prose.ts +11 -11
  245. package/src/types/components/qr-code.ts +11 -11
  246. package/src/types/components/radio-group.ts +11 -11
  247. package/src/types/components/rating.ts +11 -11
  248. package/src/types/components/scroll-area.ts +23 -23
  249. package/src/types/components/scroll-to-top.ts +2 -2
  250. package/src/types/components/select.ts +2 -1
  251. package/src/types/components/separator.ts +19 -19
  252. package/src/types/components/sidebar.ts +87 -72
  253. package/src/types/components/slideover.ts +31 -31
  254. package/src/types/components/slider.ts +2 -2
  255. package/src/types/components/speed-dial.ts +11 -11
  256. package/src/types/components/spinner.ts +25 -25
  257. package/src/types/components/splitter.ts +19 -19
  258. package/src/types/components/spoiler.ts +11 -11
  259. package/src/types/components/stepper.ts +11 -11
  260. package/src/types/components/sticky-surface.ts +19 -19
  261. package/src/types/components/switch.ts +41 -41
  262. package/src/types/components/table-of-contents.ts +17 -17
  263. package/src/types/components/tabs.ts +2 -1
  264. package/src/types/components/textarea.ts +2 -1
  265. package/src/types/components/theme-selector.ts +15 -15
  266. package/src/types/components/timeline.ts +11 -11
  267. package/src/types/components/toast.ts +2 -1
  268. package/src/types/components/tooltip.ts +23 -23
  269. package/src/types/components/tour.ts +11 -11
  270. package/src/types/components/tree.ts +11 -11
  271. package/src/types/components/user.ts +11 -11
  272. package/src/types/components/watermark.ts +11 -11
  273. package/src/types/components/window-mockup.ts +11 -11
  274. package/src/types/theme.ts +10 -0
  275. package/src/utils/docs.ts +215 -189
  276. package/src/utils/headerStack.ts +95 -95
  277. package/src/utils/index.ts +5 -5
  278. package/src/components/astro/RLABlogPost.astro +0 -7
  279. package/src/components/astro/RLABlogPosts.astro +0 -9
  280. package/src/components/astro/RLAPosts.astro +0 -23
  281. package/src/themes/posts.theme.ts +0 -13
  282. package/src/types/components/posts.ts +0 -11
@@ -1,59 +1,66 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { HeaderProps } from "../../types"
5
- import headerThemeDefault, { createHeaderTheme } from "../../themes/header.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
7
-
8
- const uiConfig = getUIConfig()
9
- const headerTheme = uiConfig.colors ? createHeaderTheme() : headerThemeDefault
10
-
11
- const header = scv(headerTheme)
12
-
13
- const {
14
- contain = true,
15
- sticky = true,
16
- fixed = false,
17
- stackIndex = 0,
18
- hideOnScroll = false,
19
- ui: uiProp,
20
- class: className,
21
- ...rest
22
- } = Astro.props as HeaderProps;
23
-
24
- const classes = resolveClasses(header, {
25
- contain,
26
- sticky: fixed ? false : sticky,
27
- fixed,
28
- }, useUi("header", uiProp), className);
29
-
30
- const headerId = `rla-header-${Math.random().toString(36).slice(2, 8)}`;
31
- const zIndex = 100 - stackIndex;
32
- ---
33
-
34
- <header
35
- id={headerId}
36
- data-slot="root"
37
- class:list={[classes.root]}
38
- data-rla-header={fixed ? "true" : undefined}
39
- data-stack-index={stackIndex}
40
- data-hide-on-scroll={String(hideOnScroll)}
41
- data-header-layer-id={headerId}
42
- style={fixed ? `z-index: ${zIndex};` : undefined}
43
- {...rest}
44
- >
45
- <div class:list={[classes.content]} data-header-content>
46
- <div class:list={[classes.container]}>
47
- <div class:list={[classes.left]} data-slot="left">
48
- <slot name="left" />
49
- </div>
50
- <div class:list={[classes.center]} data-slot="center">
51
- <slot name="center" />
52
- </div>
53
- <div class:list={[classes.right]} data-slot="right">
54
- <slot name="right" />
55
- </div>
56
- </div>
57
- </div>
58
- </header>
59
-
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { HeaderProps } from "../../types"
5
+ import headerThemeDefault, { createHeaderTheme } from "../../themes/header.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+
8
+ const uiConfig = getUIConfig()
9
+ const headerTheme = uiConfig.colors ? createHeaderTheme() : headerThemeDefault
10
+
11
+ const header = scv(headerTheme)
12
+
13
+ const {
14
+ contain = true,
15
+ sticky = true,
16
+ fixed = false,
17
+ stackIndex = 0,
18
+ hideOnScroll = false,
19
+ ui: uiProp,
20
+ class: className,
21
+ ...rest
22
+ } = Astro.props as HeaderProps;
23
+
24
+ const classes = resolveClasses(header, {
25
+ contain,
26
+ sticky: fixed ? false : sticky,
27
+ fixed,
28
+ }, useUi("header", uiProp), className);
29
+
30
+ const headerId = `rla-header-${Math.random().toString(36).slice(2, 8)}`;
31
+ const zIndex = 100 - stackIndex;
32
+ ---
33
+
34
+ <header
35
+ id={headerId}
36
+ data-slot="root"
37
+ class:list={[classes.root]}
38
+ data-rla-header={fixed ? "true" : undefined}
39
+ data-stack-index={stackIndex}
40
+ data-hide-on-scroll={String(hideOnScroll)}
41
+ data-header-layer-id={headerId}
42
+ {...rest}
43
+ >
44
+ <div class:list={[classes.content]} data-header-content>
45
+ <div class:list={[classes.container]}>
46
+ <div class:list={[classes.left]} data-slot="left">
47
+ <slot name="left" />
48
+ </div>
49
+ <div class:list={[classes.center]} data-slot="center">
50
+ <slot name="center" />
51
+ </div>
52
+ <div class:list={[classes.right]} data-slot="right">
53
+ <slot name="right" />
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </header>
58
+
59
+ {fixed && (
60
+ <style is:inline set:html={`
61
+ #${headerId} {
62
+ z-index: ${zIndex} !important;
63
+ }
64
+ `} />
65
+ )}
66
+
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { Image } from "astro:assets"
2
+ import { Image, Picture, getImage } from "astro:assets"
3
3
  import { scv } from "css-variants"
4
4
  import { useUi, resolveClasses } from "../../utils"
5
5
  import type { ImageProps, ImageMetadataInfo } from "../../types"
@@ -9,10 +9,14 @@ import { getUIConfig } from "virtual:rimelight-ui"
9
9
  const uiConfig = getUIConfig()
10
10
  const imageTheme = uiConfig.colors ? createImageTheme() : imageThemeDefault
11
11
 
12
- const imgc = scv(imageTheme)
12
+ const img = scv(imageTheme)
13
13
 
14
14
  const {
15
15
  src,
16
+ mobileSrc,
17
+ desktopSrc,
18
+ breakpoint,
19
+ formats,
16
20
  alt = "",
17
21
  height,
18
22
  width,
@@ -31,13 +35,34 @@ const {
31
35
  ...rest
32
36
  } = Astro.props as ImageProps
33
37
 
34
- const classes = resolveClasses(imgc, {}, useUi("image", uiProp), className)
35
-
36
- const isMetadata = typeof src !== "string"
37
- const imgWidth = width ?? (isMetadata ? src.width : undefined)
38
- const imgHeight = height ?? (isMetadata ? src.height : undefined)
39
- const imgFormat = isMetadata ? src.format : (preMetadata?.format ?? undefined)
40
- const rawName = typeof src === "string" ? src.split("/").pop() || "image" : src.src.split("/").pop() || "image"
38
+ const classes = resolveClasses(img, {}, useUi("image", uiProp), className)
39
+
40
+ const isResponsive = !!(mobileSrc && desktopSrc)
41
+ const isFormatFallback = !isResponsive && !!(formats && formats.length > 0)
42
+ const breakpointVal = breakpoint ?? 768
43
+
44
+ let mobileImg = null
45
+ let desktopImg = null
46
+
47
+ if (isResponsive) {
48
+ mobileImg = await getImage({
49
+ src: mobileSrc!,
50
+ format: "webp",
51
+ })
52
+ desktopImg = await getImage({
53
+ src: desktopSrc!,
54
+ format: "webp",
55
+ })
56
+ }
57
+
58
+ const activeSrc = isResponsive ? desktopSrc : src
59
+ const isMetadata = typeof activeSrc !== "string" && activeSrc !== undefined
60
+ const imgWidth = width ?? (isMetadata ? (activeSrc as any).width : undefined)
61
+ const imgHeight = height ?? (isMetadata ? (activeSrc as any).height : undefined)
62
+ const imgFormat = isMetadata ? (activeSrc as any).format : (preMetadata?.format ?? undefined)
63
+ const rawName = activeSrc
64
+ ? (typeof activeSrc === "string" ? activeSrc.split("/").pop() || "image" : (activeSrc as any).src.split("/").pop() || "image")
65
+ : "image"
41
66
  const fileName = rawName.split("?")[0]
42
67
  const fileExtension = imgFormat?.toUpperCase() || (fileName.includes(".") ? fileName.split(".").pop()?.toUpperCase() : "IMG")
43
68
  const initialSize = preMetadata?.size ?? undefined
@@ -50,7 +75,17 @@ const initialSize = preMetadata?.size ?? undefined
50
75
  class={classes.trigger}
51
76
  data-image-trigger
52
77
  >
53
- <Image src={src} alt={alt} width={imgWidth ?? 800} height={imgHeight ?? 400} loading={loading} fit={fit} />
78
+ {isResponsive && mobileImg && desktopImg ? (
79
+ <picture>
80
+ <source media={`(max-width: ${breakpointVal - 1}px)`} srcset={mobileImg.src} />
81
+ <source media={`(min-width: ${breakpointVal}px)`} srcset={desktopImg.src} />
82
+ <img src={desktopImg.src} alt={alt} loading={loading} class="w-full h-full object-cover rounded-lg" />
83
+ </picture>
84
+ ) : isFormatFallback ? (
85
+ <Picture src={src!} formats={formats!} alt={alt} width={imgWidth ?? 800} height={imgHeight ?? 400} loading={loading} class="w-full h-full object-cover rounded-lg" />
86
+ ) : (
87
+ <Image src={src!} alt={alt} width={imgWidth ?? 800} height={imgHeight ?? 400} loading={loading} fit={fit} />
88
+ )}
54
89
  </button>
55
90
  </slot>
56
91
 
@@ -60,12 +95,20 @@ const initialSize = preMetadata?.size ?? undefined
60
95
  >
61
96
  <div class="flex flex-col bg-background text-foreground max-h-[90vh]">
62
97
  <div class="flex-1 min-h-0 flex items-center justify-center p-4 overflow-hidden">
63
- <img
64
- src={typeof src === "string" ? src : src.src}
65
- alt={alt}
66
- class={classes.image}
67
- data-modal-img
68
- />
98
+ {isResponsive && mobileImg && desktopImg ? (
99
+ <picture class="max-w-full max-h-[65vh] flex items-center justify-center overflow-hidden">
100
+ <source media={`(max-width: ${breakpointVal - 1}px)`} srcset={mobileImg.src} />
101
+ <source media={`(min-width: ${breakpointVal}px)`} srcset={desktopImg.src} />
102
+ <img src={desktopImg.src} alt={alt} class={classes.image} data-modal-img />
103
+ </picture>
104
+ ) : (
105
+ <img
106
+ src={typeof src === "string" ? src : src!.src}
107
+ alt={alt}
108
+ class={classes.image}
109
+ data-modal-img
110
+ />
111
+ )}
69
112
  </div>
70
113
 
71
114
  <hr class="border-border mx-4 mb-3 shrink-0" />
@@ -194,8 +237,7 @@ const initialSize = preMetadata?.size ?? undefined
194
237
  const link = document.createElement("a")
195
238
  link.href = url
196
239
  const srcAttr = (trigger.querySelector("img") || {}).getAttribute("src") || ""
197
- const name = (srcAttr.split("/").pop() || "").split("?")[0] || `image-${Date.now()}`
198
- link.download = name
240
+ link.download = (srcAttr.split("/").pop() || "").split("?")[0] || `image-${Date.now()}`
199
241
  document.body.appendChild(link)
200
242
  link.click()
201
243
  document.body.removeChild(link)
@@ -206,4 +248,4 @@ const initialSize = preMetadata?.size ?? undefined
206
248
  })
207
249
  }
208
250
  }
209
- </script>
251
+ </script>
@@ -1,23 +1,22 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { LinkProps } from "../../types"
5
- import linkThemeDefault, { createLinkTheme } from "../../themes/link.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
7
-
8
- const uiConfig = getUIConfig()
9
- const linkTheme = uiConfig.colors ? createLinkTheme() : linkThemeDefault
10
-
11
- const link = scv(linkTheme)
12
-
13
- const {
14
- ui: uiProp,
15
- class: className,
16
- ...rest
17
- } = Astro.props as LinkProps
18
-
19
- const classes = resolveClasses(link, {}, useUi("link", uiProp), className);
20
- ---
21
- <div class={classes.root} data-slot="root" {...rest}>
22
- <slot />
23
- </div>
1
+ ---
2
+ import RLAButton from "./RLAButton.astro"
3
+ import type { LinkProps } from "../../types"
4
+
5
+ const {
6
+ to,
7
+ href,
8
+ variant = "link",
9
+ color = "neutral",
10
+ ...rest
11
+ } = Astro.props as LinkProps
12
+
13
+ const linkHref = href || (typeof to === 'string' ? to : undefined);
14
+ ---
15
+ <RLAButton
16
+ variant={variant as any}
17
+ color={color as any}
18
+ href={linkHref}
19
+ {...rest}
20
+ >
21
+ <slot />
22
+ </RLAButton>
@@ -5,6 +5,8 @@ import type { LinkGroupProps } from "../../types"
5
5
  import linkGroupThemeDefault, { createLinkGroupTheme } from "../../themes/link-group.theme"
6
6
  import { getUIConfig } from "virtual:rimelight-ui"
7
7
 
8
+ import RLALink from "./RLALink.astro"
9
+
8
10
  const uiConfig = getUIConfig()
9
11
  const linkGroupTheme = uiConfig.colors ? createLinkGroupTheme() : linkGroupThemeDefault
10
12
 
@@ -12,6 +14,11 @@ const linkGroup = scv(linkGroupTheme)
12
14
 
13
15
  const {
14
16
  title,
17
+ label,
18
+ leadingIcon,
19
+ trailingIcon,
20
+ href,
21
+ to,
15
22
  links = [],
16
23
  theme,
17
24
  ui: uiProp,
@@ -20,17 +27,72 @@ const {
20
27
  } = Astro.props as LinkGroupProps
21
28
 
22
29
  const classes = resolveClasses(linkGroup, { theme }, useUi("linkGroup", uiProp), className);
30
+
31
+ const headingLabel = label || (typeof title === "object" ? title.label : (typeof title === "string" ? title : undefined));
32
+ const headingLeadingIcon = leadingIcon || (typeof title === "object" ? title.leadingIcon : undefined);
33
+ const headingTrailingIcon = trailingIcon || (typeof title === "object" ? title.trailingIcon : undefined);
34
+ const headingHref = href || (typeof title === "object" ? title.href : undefined);
35
+ const headingTo = to || (typeof title === "object" ? (title as any).to : undefined);
36
+
37
+ const linksProp = links ?? [];
38
+ const normalizedLinks = Array.isArray(linksProp) ? linksProp : [linksProp];
39
+
40
+ // Prefix utility classes in classes.link with `!` to cleanly override conflicting text colors in RLAButton's base classes.
41
+ // For default or light themes, do not force base text classes so RLAButton's own light/dark mode styles can adapt naturally.
42
+ const isPinnedDark = theme === "flat" || theme === "dark";
43
+ const overrideLinkClass = classes.link
44
+ ? classes.link
45
+ .split(" ")
46
+ .map(cls => {
47
+ if (!cls) return "";
48
+ if (cls.includes(":")) {
49
+ const parts = cls.split(":");
50
+ const state = parts.slice(0, -1).join(":");
51
+ const baseCls = parts[parts.length - 1];
52
+ return `${state}:!${baseCls}`;
53
+ }
54
+ if (cls.startsWith("text-") && !isPinnedDark) {
55
+ return cls;
56
+ }
57
+ return `!${cls}`;
58
+ })
59
+ .filter(Boolean)
60
+ .join(" ")
61
+ : "";
23
62
  ---
24
63
  <div class={classes.root} data-slot="root" {...rest}>
25
- {title && <h4 class={classes.title} data-slot="title">{title}</h4>}
64
+ {headingLabel && (
65
+ <h4 class={classes.title} data-slot="title">
66
+ {headingHref || headingTo ? (
67
+ <a href={headingHref || (typeof headingTo === 'string' ? headingTo : undefined)} class="hover:underline flex items-center gap-1.5">
68
+ {headingLeadingIcon && <span class={headingLeadingIcon} />}
69
+ <span>{headingLabel}</span>
70
+ {headingTrailingIcon && <span class={headingTrailingIcon} />}
71
+ </a>
72
+ ) : (
73
+ <span class="flex items-center gap-1.5">
74
+ {headingLeadingIcon && <span class={headingLeadingIcon} />}
75
+ <span>{headingLabel}</span>
76
+ {headingTrailingIcon && <span class={headingTrailingIcon} />}
77
+ </span>
78
+ )}
79
+ </h4>
80
+ )}
26
81
 
27
82
  <ul class={classes.list} data-slot="list">
28
83
  <slot>
29
- {links.map((link) => (
84
+ {normalizedLinks.map((link) => (
30
85
  <li class={classes.item} data-slot="item">
31
- <a href={link.href} class={classes.link} data-slot="link" {...link}>
86
+ <RLALink
87
+ variant={link.variant ?? "ghost"}
88
+ color={link.color ?? "neutral"}
89
+ theme={link.theme ?? theme}
90
+ class:list={[overrideLinkClass, "w-full !justify-start"]}
91
+ data-slot="link"
92
+ {...link}
93
+ >
32
94
  {link.label}
33
- </a>
95
+ </RLALink>
34
96
  </li>
35
97
  ))}
36
98
  </slot>
@@ -1,114 +1,137 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { LocaleSelectorProps } from "../../types"
5
- import localeSelectorThemeDefault, { createLocaleSelectorTheme } from "../../themes/locale-selector.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
7
- import { getRelativeLocaleUrlList, getRelativeLocaleUrl } from "astro:i18n";
8
-
9
- const uiConfig = getUIConfig()
10
- const localeSelectorTheme = uiConfig.colors ? createLocaleSelectorTheme() : localeSelectorThemeDefault
11
-
12
- const localeSelector = scv(localeSelectorTheme)
13
-
14
- const {
15
- locales,
16
- variant = "default",
17
- size = "md",
18
- ui: uiProp,
19
- class: className,
20
- ...rest
21
- } = Astro.props as LocaleSelectorProps;
22
-
23
- const classes = resolveClasses(localeSelector, {
24
- variant,
25
- size
26
- }, useUi("localeSelector", uiProp), className);
27
-
28
- const currentLocale = Astro.currentLocale ?? 'en';
29
- const localeUrls = [...new Map(getRelativeLocaleUrlList().map(url => {
30
- const locale = url.split('/')[1] || 'en';
31
- return [locale, url];
32
- })).values()];
33
-
34
- const processedLocales = locales && locales.length > 0
35
- ? locales.map(item => typeof item === 'string' ? { code: item, label: item } : item)
36
- : [...new Map(getRelativeLocaleUrlList().map(url => {
37
- const locale = url.split('/')[1] || 'en';
38
- return [locale, { code: locale, label: locale }];
39
- })).values()];
40
-
41
- function getLocaleDisplayName(localeCode: string): string {
42
- try {
43
- const formatter = new Intl.DisplayNames([localeCode], { type: 'language' });
44
- const nativeName = formatter.of(localeCode);
45
-
46
- return nativeName
47
- ? nativeName.charAt(0).toUpperCase() + nativeName.slice(1)
48
- : localeCode.toUpperCase();
49
- } catch (e) {
50
- return localeCode.toUpperCase();
51
- }
52
- }
53
- ---
54
-
55
- <div class:list={[classes.root]} {...rest}>
56
- {Astro.slots.has("label") && (
57
- <label for="language-picker" class:list={[classes.label]}>
58
- <slot name="label" />
59
- </label>
60
- )}
61
-
62
- <div class:list={[classes.wrapper]}>
63
- <select
64
- id="language-picker"
65
- class:list={[classes.select]}
66
- aria-label="Select language"
67
- data-variant={variant}
68
- data-size={size}
69
- >
70
- {processedLocales.map((item) => {
71
- const targetUrl = getRelativeLocaleUrl(item.code, Astro.url.pathname.replace(/^\/[^/]+/, ''));
72
- return (
73
- <option
74
- value={targetUrl}
75
- selected={currentLocale === item.code}
76
- class:list={[classes.option]}
77
- >
78
- {item.label !== item.code ? item.label : getLocaleDisplayName(item.code)}
79
- </option>
80
- );
81
- })}
82
- </select>
83
-
84
- <div class:list={[classes.iconWrapper]}>
85
- <slot name="icon">
86
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-4 h-4 opacity-70">
87
- <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
88
- </svg>
89
- </slot>
90
- </div>
91
- </div>
92
- </div>
93
-
94
- <script>
95
- const initializeLanguagePicker = () => {
96
- const languagePickers = document.querySelectorAll('#language-picker');
97
-
98
- languagePickers.forEach(picker => {
99
- if (picker.hasAttribute('data-initialized')) return;
100
- picker.setAttribute('data-initialized', 'true');
101
-
102
- picker.addEventListener('change', (event) => {
103
- const target = event.target as HTMLSelectElement;
104
- const targetUrl = target.value;
105
- if (targetUrl) {
106
- window.location.href = targetUrl;
107
- }
108
- });
109
- });
110
- };
111
-
112
- document.addEventListener('DOMContentLoaded', initializeLanguagePicker);
113
- document.addEventListener('astro:page-load', initializeLanguagePicker);
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { LocaleSelectorProps } from "../../types"
5
+ import localeSelectorThemeDefault, { createLocaleSelectorTheme } from "../../themes/locale-selector.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+ import { getRelativeLocaleUrlList, getRelativeLocaleUrl } from "astro:i18n"
8
+ import RLASelect from "./RLASelect.astro"
9
+
10
+ const uiConfig = getUIConfig()
11
+ const localeSelectorTheme = uiConfig.colors ? createLocaleSelectorTheme() : localeSelectorThemeDefault
12
+
13
+ const localeSelector = scv(localeSelectorTheme)
14
+
15
+ const {
16
+ locales,
17
+ variant = "default",
18
+ size = "md",
19
+ ui: uiProp,
20
+ class: className,
21
+ ...rest
22
+ } = Astro.props as LocaleSelectorProps;
23
+
24
+ const classes = resolveClasses(localeSelector, {
25
+ variant,
26
+ size
27
+ }, useUi("localeSelector", uiProp), className);
28
+
29
+ const currentLocale = Astro.currentLocale ?? 'en';
30
+
31
+ const processedLocales = locales && locales.length > 0
32
+ ? locales.map(item => typeof item === 'string' ? { code: item, label: item } : item)
33
+ : [...new Map(getRelativeLocaleUrlList().map(url => {
34
+ const locale = url.split('/')[1] || 'en';
35
+ return [locale, { code: locale, label: locale }];
36
+ })).values()];
37
+
38
+ function getLocaleDisplayName(localeCode: string): string {
39
+ try {
40
+ const formatter = new Intl.DisplayNames([localeCode], { type: 'language' });
41
+ const nativeName = formatter.of(localeCode);
42
+
43
+ return nativeName
44
+ ? nativeName.charAt(0).toUpperCase() + nativeName.slice(1)
45
+ : localeCode.toUpperCase();
46
+ } catch (e) {
47
+ return localeCode.toUpperCase();
48
+ }
49
+ }
50
+
51
+ const items = processedLocales.map((item) => {
52
+ const targetUrl = getRelativeLocaleUrl(item.code, Astro.url.pathname.replace(/^\/[^/]+/, ''));
53
+ return {
54
+ label: item.label !== item.code ? item.label : getLocaleDisplayName(item.code),
55
+ value: targetUrl,
56
+ code: item.code
57
+ };
58
+ });
59
+
60
+ const currentLocaleUrl = items.find(item => item.code === currentLocale)?.value || "";
61
+
62
+ // Prefix utility classes in classes.select with `!` to cleanly override conflicting styles in RLASelect's base trigger
63
+ // Also remove `pr-` classes which were meant for absolute positioned native select icons
64
+ const overrideTriggerClass = classes.select
65
+ ? classes.select
66
+ .split(" ")
67
+ .map(cls => {
68
+ if (!cls) return "";
69
+ if (cls.startsWith("pr-") || cls.startsWith("!pr-")) return ""; // Strip padding-right
70
+ if (cls.includes(":")) {
71
+ const parts = cls.split(":");
72
+ const state = parts.slice(0, -1).join(":");
73
+ const baseCls = parts[parts.length - 1];
74
+ return `${state}:!${baseCls}`;
75
+ }
76
+ return `!${cls}`;
77
+ })
78
+ .filter(Boolean)
79
+ .join(" ")
80
+ : "";
81
+
82
+ const gapClass = size === "sm" ? "gap-1.5" : size === "lg" ? "gap-3" : "gap-2";
83
+
84
+ const isDefault = variant === "default";
85
+ const triggerDarkModeOverrides = isDefault
86
+ ? "dark:!bg-neutral-800 dark:!text-white dark:hover:!bg-neutral-700"
87
+ : "";
88
+
89
+ const selectUi = {
90
+ root: "!w-fit !inline-flex",
91
+ trigger: `flex items-center justify-between !w-fit ${gapClass} ${overrideTriggerClass} ${triggerDarkModeOverrides}`,
92
+ content: "!min-w-0 !w-full !bg-white !border-gray-200 !text-gray-800 dark:!bg-neutral-900 dark:!border-neutral-800 dark:!text-white",
93
+ item: "!text-gray-700 hover:!bg-gray-100 hover:!text-gray-900 dark:!text-neutral-300 dark:hover:!bg-neutral-800 dark:hover:!text-white"
94
+ };
95
+ ---
96
+
97
+ <div class:list={[classes.root]} data-locale-selector {...rest}>
98
+ {Astro.slots.has("label") && (
99
+ <label class:list={[classes.label]}>
100
+ <slot name="label" />
101
+ </label>
102
+ )}
103
+
104
+ <div class:list={[classes.wrapper]}>
105
+ <RLASelect
106
+ items={items}
107
+ value={currentLocaleUrl}
108
+ size={size}
109
+ ui={selectUi}
110
+ />
111
+ </div>
112
+ </div>
113
+
114
+ <script>
115
+ const initializeLocaleSelector = () => {
116
+ const selectors = document.querySelectorAll('[data-locale-selector]');
117
+
118
+ selectors.forEach(selector => {
119
+ if (selector.hasAttribute('data-initialized')) return;
120
+ selector.setAttribute('data-initialized', 'true');
121
+
122
+ const hiddenInput = selector.querySelector('[data-select-hidden-input]') as HTMLInputElement;
123
+ if (!hiddenInput) return;
124
+
125
+ hiddenInput.addEventListener('change', (event) => {
126
+ const target = event.target as HTMLInputElement;
127
+ const targetUrl = target.value;
128
+ if (targetUrl) {
129
+ window.location.href = targetUrl;
130
+ }
131
+ });
132
+ });
133
+ };
134
+
135
+ document.addEventListener('DOMContentLoaded', initializeLocaleSelector);
136
+ document.addEventListener('astro:page-load', initializeLocaleSelector);
114
137
  </script>