@rimelight/ui 0.0.47 → 0.0.49

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 (197) hide show
  1. package/dist/index.d.mts +4 -5
  2. package/dist/preset.mjs +73 -1
  3. package/dist/resolver.d.mts +3 -4
  4. package/dist/resolver.mjs +2 -4
  5. package/dist/shortcuts.d.mts +10 -11
  6. package/dist/stores.d.mts +3 -4
  7. package/package.json +8 -6
  8. package/src/components/3d-hover/RLS3dHover.tsx +21 -0
  9. package/src/components/accordion/RLSAccordion.tsx +112 -0
  10. package/src/components/app/RLSApp.tsx +21 -0
  11. package/src/components/aspect-ratio/RLSAspectRatio.tsx +30 -0
  12. package/src/components/audio/RLSAudio.tsx +27 -0
  13. package/src/components/avatar/RLSAvatar.tsx +142 -0
  14. package/src/components/avatar/avatar.ts +22 -21
  15. package/src/components/avatar-group/RLSAvatarGroup.tsx +163 -0
  16. package/src/components/badge/RLSBadge.tsx +1 -1
  17. package/src/components/badge/RLVBadge.vue +5 -3
  18. package/src/components/banner/RLSBanner.tsx +151 -0
  19. package/src/components/breadcrumb/RLSBreadcrumb.tsx +194 -0
  20. package/src/components/browser-mockup/RLSBrowserMockup.tsx +21 -0
  21. package/src/components/button/RLSButton.tsx +49 -40
  22. package/src/components/button/RLVButton.vue +44 -32
  23. package/src/components/calendar/RLSCalendar.tsx +26 -0
  24. package/src/components/callout/RLSCallout.tsx +151 -0
  25. package/src/components/card/RLSCard.tsx +4 -0
  26. package/src/components/card/RLVCard.vue +4 -0
  27. package/src/components/card/card.ts +10 -0
  28. package/src/components/carousel/RLACarousel.astro +14 -1
  29. package/src/components/carousel/RLSCarousel.tsx +260 -0
  30. package/src/components/chart/RLSChart.tsx +299 -0
  31. package/src/components/chat/RLSChat.tsx +27 -0
  32. package/src/components/chat-message/RLSChatMessage.tsx +27 -0
  33. package/src/components/chat-messages/RLSChatMessages.tsx +27 -0
  34. package/src/components/chat-palette/RLSChatPalette.tsx +27 -0
  35. package/src/components/chat-prompt/RLSChatPrompt.tsx +27 -0
  36. package/src/components/chat-prompt-submit/RLSChatPromptSubmit.tsx +27 -0
  37. package/src/components/chat-reasoning/RLSChatReasoning.tsx +27 -0
  38. package/src/components/chat-shimmer/RLSChatShimmer.tsx +27 -0
  39. package/src/components/chat-tool/RLSChatTool.tsx +27 -0
  40. package/src/components/checkbox/RLACheckbox.astro +1 -0
  41. package/src/components/checkbox/RLSCheckbox.tsx +1 -1
  42. package/src/components/checkbox/checkbox.theme.ts +2 -2
  43. package/src/components/chip/RLSChip.tsx +65 -0
  44. package/src/components/collapsible/RLSCollapsible.tsx +89 -0
  45. package/src/components/color-area/RLSColorArea.tsx +554 -0
  46. package/src/components/color-field/RLSColorField.tsx +236 -0
  47. package/src/components/color-picker/RLSColorPicker.tsx +26 -0
  48. package/src/components/color-slider/RLSColorSlider.tsx +373 -0
  49. package/src/components/command-palette/RLSCommandPalette.tsx +26 -0
  50. package/src/components/compare/RLSCompare.tsx +26 -0
  51. package/src/components/confirm/RLSConfirm.tsx +173 -0
  52. package/src/components/container/RLSContainer.tsx +24 -0
  53. package/src/components/context-menu/RLSContextMenu.tsx +26 -0
  54. package/src/components/copy-markdown/RLSCopyMarkdown.tsx +57 -0
  55. package/src/components/dashboard-group/RLSDashboardGroup.tsx +29 -0
  56. package/src/components/dashboard-navbar/RLSDashboardNavbar.tsx +116 -0
  57. package/src/components/dashboard-panel/RLSDashboardPanel.tsx +84 -0
  58. package/src/components/dashboard-resize-handle/RLSDashboardResizeHandle.tsx +35 -0
  59. package/src/components/dashboard-search/RLADashboardSearch.astro +1 -1
  60. package/src/components/dashboard-search/RLSDashboardSearch.tsx +125 -0
  61. package/src/components/dashboard-search-button/RLSDashboardSearchButton.tsx +82 -0
  62. package/src/components/dashboard-sidebar/RLSDashboardSidebar.tsx +184 -0
  63. package/src/components/dashboard-sidebar-collapse/RLSDashboardSidebarCollapse.tsx +46 -0
  64. package/src/components/dashboard-sidebar-toggle/RLSDashboardSidebarToggle.tsx +35 -0
  65. package/src/components/dashboard-toolbar/RLSDashboardToolbar.tsx +49 -0
  66. package/src/components/date/RLSDate.tsx +34 -0
  67. package/src/components/dock/RLSDock.tsx +26 -0
  68. package/src/components/drawer/RLSDrawer.tsx +177 -0
  69. package/src/components/dropdown-menu/RLADropdownMenu.astro +250 -241
  70. package/src/components/dropdown-menu/RLSDropdownMenu.tsx +183 -86
  71. package/src/components/editor/RLSEditor.tsx +26 -0
  72. package/src/components/empty/RLSEmpty.tsx +132 -0
  73. package/src/components/error/RLSError.tsx +26 -0
  74. package/src/components/field-group/RLSFieldGroup.tsx +46 -0
  75. package/src/components/fieldset/RLSFieldset.tsx +26 -0
  76. package/src/components/file-upload/RLSFileUpload.tsx +163 -0
  77. package/src/components/floating-action/RLSFloatingAction.tsx +26 -0
  78. package/src/components/footer/RLSFooter.tsx +56 -0
  79. package/src/components/form/RLSForm.tsx +34 -0
  80. package/src/components/gallery/RLSGallery.tsx +21 -0
  81. package/src/components/gamepad/RLSGamepad.tsx +269 -0
  82. package/src/components/grid/RLSGrid.tsx +29 -0
  83. package/src/components/head/RLAHead.astro +9 -0
  84. package/src/components/head/RLSHead.tsx +42 -0
  85. package/src/components/head/UIHead.astro +3 -0
  86. package/src/components/header/RLSHeader.tsx +87 -0
  87. package/src/components/hover-card/RLSHoverCard.tsx +72 -0
  88. package/src/components/icon/RLSIcon.tsx +3 -1
  89. package/src/components/image/RLAImage.astro +447 -138
  90. package/src/components/image/RLSImage.tsx +545 -0
  91. package/src/components/image/image.theme.ts +19 -3
  92. package/src/components/image/image.ts +31 -1
  93. package/src/components/input/RLAInput.astro +62 -51
  94. package/src/components/input/RLSInput.tsx +1 -1
  95. package/src/components/input-date/RLSInputDate.tsx +92 -0
  96. package/src/components/input-menu/RLSInputMenu.tsx +199 -0
  97. package/src/components/input-number/RLSInputNumber.tsx +184 -0
  98. package/src/components/input-pin/RLSInputPin.tsx +185 -0
  99. package/src/components/input-rating/RLSInputRating.tsx +198 -0
  100. package/src/components/input-rating/input-rating.ts +4 -0
  101. package/src/components/input-tags/RLSInputTags.tsx +94 -0
  102. package/src/components/input-time/RLSInputTime.tsx +92 -0
  103. package/src/components/kbd/RLSKbd.tsx +37 -0
  104. package/src/components/keyboard/RLSKeyboard.tsx +476 -0
  105. package/src/components/knob/RLSKnob.tsx +27 -0
  106. package/src/components/label/RLSLabel.tsx +27 -0
  107. package/src/components/layout-grid/RLSLayoutGrid.tsx +402 -0
  108. package/src/components/layout-grid/layout-grid.ts +25 -1
  109. package/src/components/link/RLSLink.tsx +2 -1
  110. package/src/components/link/link.ts +21 -12
  111. package/src/components/link-group/RLSLinkGroup.tsx +76 -0
  112. package/src/components/listbox/RLSListbox.tsx +27 -0
  113. package/src/components/locale-selector/RLALocaleSelector.astro +2 -1
  114. package/src/components/locale-selector/RLSLocaleSelector.tsx +178 -0
  115. package/src/components/logo/RLALogo.astro +69 -4
  116. package/src/components/logo/RLSLogo.tsx +129 -0
  117. package/src/components/main/RLSMain.tsx +40 -0
  118. package/src/components/marquee/RLSMarquee.tsx +80 -0
  119. package/src/components/meter/RLSMeter.tsx +27 -0
  120. package/src/components/modal/RLAModal.astro +1 -1
  121. package/src/components/modal/RLSModal.tsx +109 -72
  122. package/src/components/navigation-menu/RLSNavigationMenu.tsx +228 -0
  123. package/src/components/navigation-menu/navigation-menu.ts +2 -2
  124. package/src/components/package-managers/RLSPackageManagers.tsx +204 -0
  125. package/src/components/page/RLSPage.tsx +21 -0
  126. package/src/components/page-aside/RLSPageAside.tsx +21 -0
  127. package/src/components/page-body/RLSPageBody.tsx +21 -0
  128. package/src/components/page-header/RLSPageHeader.tsx +21 -0
  129. package/src/components/page-section/RLSPageSection.tsx +201 -0
  130. package/src/components/pagination/RLSPagination.tsx +114 -0
  131. package/src/components/password/RLSPassword.tsx +27 -0
  132. package/src/components/phone-mockup/RLSPhoneMockup.tsx +27 -0
  133. package/src/components/placeholder/RLSPlaceholder.tsx +47 -0
  134. package/src/components/popover/RLSPopover.tsx +124 -0
  135. package/src/components/post/RLSPost.tsx +134 -0
  136. package/src/components/pricing-plan/RLSPricingPlan.tsx +26 -0
  137. package/src/components/pricing-table/RLSPricingTable.tsx +26 -0
  138. package/src/components/progress/RLSProgress.tsx +53 -0
  139. package/src/components/prose/RLSProse.tsx +26 -0
  140. package/src/components/qr-code/RLSQrCode.tsx +26 -0
  141. package/src/components/quote/RLAQuote.astro +10 -6
  142. package/src/components/quote/RLSQuote.tsx +37 -0
  143. package/src/components/quote/quote.theme.ts +5 -2
  144. package/src/components/radio-group/RLSRadioGroup.tsx +37 -0
  145. package/src/components/rating/RLSRating.tsx +27 -0
  146. package/src/components/scroll-area/RLSScrollArea.tsx +210 -0
  147. package/src/components/scroll-to-top/RLAScrollToTop.astro +1 -0
  148. package/src/components/scroll-to-top/RLSScrollToTop.tsx +145 -0
  149. package/src/components/search/RLSSearch.tsx +237 -0
  150. package/src/components/select/RLASelect.astro +67 -4
  151. package/src/components/select/RLSSelect.tsx +107 -39
  152. package/src/components/select/RLVSelect.vue +50 -1
  153. package/src/components/select/select.theme.ts +30 -10
  154. package/src/components/select/select.ts +20 -1
  155. package/src/components/separator/RLSSeparator.tsx +92 -0
  156. package/src/components/share/RLSShare.tsx +66 -0
  157. package/src/components/shortcuts/RLSShortcuts.tsx +393 -0
  158. package/src/components/sidebar/RLSSidebar.tsx +271 -0
  159. package/src/components/skeleton/RLSSkeleton.tsx +21 -0
  160. package/src/components/slideover/RLASlideover.astro +1 -1
  161. package/src/components/slideover/RLSSlideover.tsx +159 -0
  162. package/src/components/slider/RLSSlider.tsx +112 -0
  163. package/src/components/speed-dial/RLSSpeedDial.tsx +27 -0
  164. package/src/components/spinner/RLSSpinner.tsx +22 -0
  165. package/src/components/splitter/RLSSplitter.tsx +178 -0
  166. package/src/components/spoiler/RLSSpoiler.tsx +26 -0
  167. package/src/components/stepper/RLSStepper.tsx +205 -0
  168. package/src/components/steps/RLSSteps.tsx +108 -0
  169. package/src/components/sticky-surface/RLSStickySurface.tsx +63 -0
  170. package/src/components/surround/RLSSurround.tsx +57 -0
  171. package/src/components/switch/RLSSwitch.tsx +56 -0
  172. package/src/components/table/RLATable.astro +1044 -579
  173. package/src/components/table/RLSTable.tsx +893 -0
  174. package/src/components/table/table.theme.ts +47 -16
  175. package/src/components/table/table.ts +104 -66
  176. package/src/components/table-of-contents/RLSTableOfContents.tsx +196 -0
  177. package/src/components/tabs/RLSTabs.tsx +298 -0
  178. package/src/components/textarea/RLATextarea.astro +1 -0
  179. package/src/components/textarea/RLSTextarea.tsx +3 -1
  180. package/src/components/theme-selector/RLAThemeSelector.astro +85 -56
  181. package/src/components/theme-selector/RLSThemeSelector.tsx +131 -0
  182. package/src/components/theme-selector/theme-selector.theme.ts +5 -7
  183. package/src/components/theme-selector/theme-selector.ts +11 -1
  184. package/src/components/timeline/RLSTimeline.tsx +171 -0
  185. package/src/components/toast/RLSToast.tsx +179 -0
  186. package/src/components/toaster/RLSToaster.tsx +82 -0
  187. package/src/components/tooltip/RLSTooltip.tsx +48 -0
  188. package/src/components/tour/RLSTour.tsx +26 -0
  189. package/src/components/tree/RLSTree.tsx +26 -0
  190. package/src/components/user/RLSUser.tsx +26 -0
  191. package/src/components/video/RLAVideo.astro +4 -1
  192. package/src/components/video/RLSVideo.tsx +158 -0
  193. package/src/components/watermark/RLSWatermark.tsx +27 -0
  194. package/src/components/window-mockup/RLSWindowMockup.tsx +27 -0
  195. package/src/preset.ts +73 -1
  196. package/src/resolver.ts +6 -1
  197. package/src/virtual.d.ts +6 -0
@@ -0,0 +1,178 @@
1
+ import {
2
+ createMemo,
3
+ createSignal,
4
+ splitProps,
5
+ onMount,
6
+ onCleanup,
7
+ For,
8
+ Show,
9
+ type Component,
10
+ type JSX
11
+ } from "solid-js"
12
+ import type { LocaleSelectorProps, LocaleItem } from "./locale-selector"
13
+ import { localeSelectorTheme } from "./locale-selector.theme"
14
+ import RLSIcon from "../icon/RLSIcon"
15
+
16
+ export interface RLSLocaleSelectorProps extends LocaleSelectorProps {
17
+ children?: JSX.Element
18
+ labelSlot?: JSX.Element
19
+ onSelect?: (item: LocaleItem) => void
20
+ }
21
+
22
+ const getLocaleDisplayName = (localeCode: string): string => {
23
+ try {
24
+ const formatter = new Intl.DisplayNames([localeCode], { type: "language" })
25
+ const nativeName = formatter.of(localeCode)
26
+ return nativeName
27
+ ? nativeName.charAt(0).toUpperCase() + nativeName.slice(1)
28
+ : localeCode.toUpperCase()
29
+ } catch {
30
+ return localeCode.toUpperCase()
31
+ }
32
+ }
33
+
34
+ const RLSLocaleSelector: Component<RLSLocaleSelectorProps> = (allProps) => {
35
+ const [props, rest] = splitProps(allProps, [
36
+ "locales",
37
+ "currentLocale",
38
+ "variant",
39
+ "size",
40
+ "theme",
41
+ "ui",
42
+ "class",
43
+ "children",
44
+ "labelSlot",
45
+ "onSelect"
46
+ ])
47
+
48
+ const [isOpen, setIsOpen] = createSignal(false)
49
+ let containerRef: HTMLDivElement | undefined
50
+
51
+ onMount(() => {
52
+ const handleOutsideClick = (e: MouseEvent) => {
53
+ if (isOpen() && containerRef && !containerRef.contains(e.target as Node)) {
54
+ setIsOpen(false)
55
+ }
56
+ }
57
+ document.addEventListener("click", handleOutsideClick)
58
+ onCleanup(() => document.removeEventListener("click", handleOutsideClick))
59
+ })
60
+
61
+ const currentCode = (): string => props.currentLocale ?? "en"
62
+
63
+ const processedLocales = createMemo<LocaleItem[]>(() =>
64
+ (props.locales ?? []).map((item) =>
65
+ typeof item === "string"
66
+ ? { code: item, label: getLocaleDisplayName(item) }
67
+ : { ...item, label: item.label || getLocaleDisplayName(item.code) }
68
+ )
69
+ )
70
+
71
+ const items = createMemo(() =>
72
+ processedLocales().map((item) => {
73
+ let targetUrl: string
74
+ const search = typeof window !== "undefined" ? window.location.search : ""
75
+ const pathname = typeof window !== "undefined" ? window.location.pathname : "/"
76
+ if (item.href !== undefined && item.href !== null) {
77
+ targetUrl = item.href + (item.href.includes("?") ? "" : search)
78
+ } else {
79
+ const knownCodes = new Set(processedLocales().map((l) => l.code))
80
+ const segments = pathname.split("/").filter(Boolean)
81
+ const firstIsLocale = segments.length > 0 && knownCodes.has(segments[0]!)
82
+
83
+ if (firstIsLocale) {
84
+ segments[0] = item.code
85
+ targetUrl = `/${segments.join("/")}${pathname.endsWith("/") ? "/" : ""}${search}`
86
+ } else if (segments.length > 0) {
87
+ targetUrl = `/${item.code}/${segments.join("/")}${pathname.endsWith("/") ? "/" : ""}${search}`
88
+ } else {
89
+ targetUrl = `/${item.code}/${search}`
90
+ }
91
+ }
92
+ return { label: item.label, value: targetUrl, code: item.code }
93
+ })
94
+ )
95
+
96
+ const currentItem = createMemo(() => items().find((item) => item.code === currentCode()))
97
+
98
+ const resolvedClasses = createMemo(() =>
99
+ localeSelectorTheme({
100
+ variant: props.variant ?? "default",
101
+ size: props.size ?? "md",
102
+ theme: props.theme,
103
+ ui: props.ui,
104
+ class: props.class
105
+ })
106
+ )
107
+
108
+ const selectLocale = (item: { label: string; value: string; code: string }) => {
109
+ setIsOpen(false)
110
+ props.onSelect?.({ label: item.label, code: item.code, href: item.value })
111
+ if (item.value) {
112
+ window.location.href = item.value
113
+ }
114
+ }
115
+
116
+ return (
117
+ <div
118
+ ref={(el) => (containerRef = el)}
119
+ class={resolvedClasses().root}
120
+ data-slot="root"
121
+ data-theme={props.theme}
122
+ {...rest}
123
+ >
124
+ <Show when={props.labelSlot}>
125
+ <label class={resolvedClasses().label} data-slot="label">
126
+ {props.labelSlot}
127
+ </label>
128
+ </Show>
129
+
130
+ <div class={resolvedClasses().wrapper} data-slot="wrapper">
131
+ <button
132
+ type="button"
133
+ class={`${resolvedClasses().select} flex items-center justify-between gap-2 text-left`}
134
+ data-slot="trigger"
135
+ aria-haspopup="listbox"
136
+ aria-expanded={isOpen() ? "true" : "false"}
137
+ onClick={() => setIsOpen(!isOpen())}
138
+ >
139
+ <span class="truncate">{currentItem()?.label || currentCode()}</span>
140
+ <span class={resolvedClasses().iconWrapper}>
141
+ <RLSIcon name="chevronDown" size="sm" aria-hidden="true" />
142
+ </span>
143
+ </button>
144
+
145
+ <Show when={isOpen()}>
146
+ <div
147
+ class="absolute z-50 mt-1 w-full overflow-hidden rounded-lg border border-default bg-default py-1 shadow-xl"
148
+ data-slot="options"
149
+ role="listbox"
150
+ >
151
+ <For each={items()}>
152
+ {(item) => {
153
+ const selected = item.code === currentCode()
154
+ return (
155
+ <button
156
+ type="button"
157
+ class={`${resolvedClasses().option} flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-accented/50 ${selected ? "font-medium" : ""}`}
158
+ data-slot="option"
159
+ role="option"
160
+ aria-selected={selected ? "true" : "false"}
161
+ onClick={() => selectLocale(item)}
162
+ >
163
+ <span class="truncate">{item.label}</span>
164
+ <Show when={selected}>
165
+ <RLSIcon name="check" size="xs" class="shrink-0" aria-hidden="true" />
166
+ </Show>
167
+ </button>
168
+ )
169
+ }}
170
+ </For>
171
+ </div>
172
+ </Show>
173
+ </div>
174
+ </div>
175
+ )
176
+ }
177
+
178
+ export default RLSLocaleSelector
@@ -6,6 +6,7 @@ import uiConfig from "virtual:rimelight/ui"
6
6
  const {
7
7
  variant = "logomark",
8
8
  mode,
9
+ theme,
9
10
  href = "/",
10
11
  alt,
11
12
  ...rest
@@ -57,24 +58,29 @@ const hasAutoMode = darkSrc && lightSrc && darkSrc !== lightSrc && !mode;
57
58
  href={href}
58
59
  aria-label={alt || variant}
59
60
  data-slot="root"
61
+ data-theme={theme}
62
+ style={theme ? `color-scheme: ${theme};` : undefined}
60
63
  {...rest}
61
64
  >
62
65
  {logoSrc ? (
63
66
  isIcon ? (
64
67
  <span class:list={[logoSrc, "size-full block shrink-0"]} aria-hidden="true" />
65
68
  ) : hasAutoMode ? (
66
- <>
69
+ <span
70
+ class="rla-logo-image size-full flex items-center justify-center shrink-0"
71
+ style={`--rla-logo-light: url('${lightSrc}'); --rla-logo-dark: url('${darkSrc}');`}
72
+ >
67
73
  <img
68
74
  src={lightSrc}
69
75
  alt={alt || ""}
70
- class="size-full block object-contain shrink-0 dark:hidden"
76
+ class="rla-logo-light size-full block object-contain shrink-0"
71
77
  />
72
78
  <img
73
79
  src={darkSrc}
74
80
  alt={alt || ""}
75
- class="size-full hidden object-contain shrink-0 dark:block"
81
+ class="rla-logo-dark size-full hidden object-contain shrink-0"
76
82
  />
77
- </>
83
+ </span>
78
84
  ) : (
79
85
  <img
80
86
  src={logoSrc}
@@ -86,3 +92,62 @@ const hasAutoMode = darkSrc && lightSrc && darkSrc !== lightSrc && !mode;
86
92
  <slot />
87
93
  )}
88
94
  </a>
95
+
96
+ <style>
97
+ :global(:root[data-theme="dark"]) .rla-logo-light,
98
+ :global([data-theme="dark"]) .rla-logo-light,
99
+ :global([data-theme="dark"]) .rla-logo-image .rla-logo-light,
100
+ :global(.rla-logo-image[data-theme="dark"]) .rla-logo-light {
101
+ display: none !important;
102
+ }
103
+
104
+ :global(:root[data-theme="dark"]) .rla-logo-dark,
105
+ :global([data-theme="dark"]) .rla-logo-dark,
106
+ :global([data-theme="dark"]) .rla-logo-image .rla-logo-dark,
107
+ :global(.rla-logo-image[data-theme="dark"]) .rla-logo-dark {
108
+ display: block !important;
109
+ }
110
+
111
+ :global(:root[data-theme="light"]) .rla-logo-light,
112
+ :global([data-theme="light"]) .rla-logo-light,
113
+ :global([data-theme="light"]) .rla-logo-image .rla-logo-light,
114
+ :global(.rla-logo-image[data-theme="light"]) .rla-logo-light {
115
+ display: block !important;
116
+ }
117
+
118
+ :global(:root[data-theme="light"]) .rla-logo-dark,
119
+ :global([data-theme="light"]) .rla-logo-dark,
120
+ :global([data-theme="light"]) .rla-logo-image .rla-logo-dark,
121
+ :global(.rla-logo-image[data-theme="light"]) .rla-logo-dark {
122
+ display: none !important;
123
+ }
124
+
125
+ @media (prefers-color-scheme: dark) {
126
+ :global(:root:not([data-theme="light"])) .rla-logo-light {
127
+ display: none !important;
128
+ }
129
+ :global(:root:not([data-theme="light"])) .rla-logo-dark {
130
+ display: block !important;
131
+ }
132
+ :global(:root:not([data-theme="light"])) :global([data-theme="light"]) .rla-logo-light {
133
+ display: block !important;
134
+ }
135
+ :global(:root:not([data-theme="light"])) :global([data-theme="light"]) .rla-logo-dark {
136
+ display: none !important;
137
+ }
138
+ }
139
+
140
+ @supports (background-image: light-dark(none, none)) {
141
+ .rla-logo-image {
142
+ background-image: light-dark(var(--rla-logo-light), var(--rla-logo-dark));
143
+ background-size: contain;
144
+ background-position: center;
145
+ background-repeat: no-repeat;
146
+ }
147
+ .rla-logo-image > .rla-logo-light,
148
+ .rla-logo-image > .rla-logo-dark {
149
+ opacity: 0 !important;
150
+ visibility: hidden !important;
151
+ }
152
+ }
153
+ </style>
@@ -0,0 +1,129 @@
1
+ import { createMemo, Show, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { LogoProps } from "./logo"
3
+ import { logoTheme } from "./logo.theme"
4
+ import uiConfig from "virtual:rimelight/ui"
5
+
6
+ export interface RLSLogoProps extends LogoProps {
7
+ children?: JSX.Element
8
+ src?: string
9
+ }
10
+
11
+ const RLSLogo: Component<RLSLogoProps> = (allProps) => {
12
+ const [props, rest] = splitProps(allProps, [
13
+ "variant",
14
+ "mode",
15
+ "theme",
16
+ "href",
17
+ "alt",
18
+ "src",
19
+ "ui",
20
+ "class",
21
+ "children"
22
+ ])
23
+
24
+ const variant = () => props.variant || "logomark"
25
+ const href = () => props.href ?? "/"
26
+
27
+ const logoInfo = createMemo(() => {
28
+ if (props.src) {
29
+ return { logoSrc: props.src, darkSrc: null, lightSrc: null }
30
+ }
31
+
32
+ const cfgLogos = (uiConfig as any)?.logos
33
+ const logoVariant = cfgLogos?.[variant()]
34
+
35
+ let logoSrc: string | null = null
36
+ let darkSrc: string | null = null
37
+ let lightSrc: string | null = null
38
+
39
+ if (logoVariant && typeof logoVariant === "object") {
40
+ if (props.mode) {
41
+ logoSrc = logoVariant[props.mode] || logoVariant.color
42
+ } else {
43
+ logoSrc = logoVariant.color || logoVariant.black || logoVariant.white
44
+ darkSrc = logoVariant.white || logoVariant.color
45
+ lightSrc = logoVariant.black || logoVariant.color
46
+ }
47
+ } else if (typeof logoVariant === "string") {
48
+ logoSrc = logoVariant
49
+ }
50
+
51
+ return { logoSrc, darkSrc, lightSrc }
52
+ })
53
+
54
+ const startsWithUrlPrefix = () => {
55
+ const s = logoInfo().logoSrc
56
+ return s && (s.startsWith("http") || s.startsWith("/") || s.startsWith("."))
57
+ }
58
+
59
+ const isIcon = () => {
60
+ const s = logoInfo().logoSrc
61
+ return s && !startsWithUrlPrefix() && (s.includes(":") || s.startsWith("i-"))
62
+ }
63
+
64
+ const hasAutoMode = () => {
65
+ const { darkSrc, lightSrc } = logoInfo()
66
+ return darkSrc && lightSrc && darkSrc !== lightSrc && !props.mode
67
+ }
68
+
69
+ const resolvedClasses = createMemo(() =>
70
+ logoTheme({
71
+ variant: variant(),
72
+ ui: props.ui,
73
+ class: props.class
74
+ })
75
+ )
76
+
77
+ return (
78
+ <a
79
+ class={resolvedClasses().root}
80
+ href={href()}
81
+ aria-label={props.alt || variant()}
82
+ data-slot="root"
83
+ data-theme={props.theme}
84
+ style={props.theme ? { "color-scheme": props.theme } : undefined}
85
+ {...rest}
86
+ >
87
+ <Show when={logoInfo().logoSrc} fallback={props.children}>
88
+ <Show
89
+ when={!isIcon()}
90
+ fallback={
91
+ <span class={`${logoInfo().logoSrc} size-full block shrink-0`} aria-hidden="true" />
92
+ }
93
+ >
94
+ <Show
95
+ when={!hasAutoMode()}
96
+ fallback={
97
+ <span
98
+ class="rla-logo-image size-full flex items-center justify-center shrink-0"
99
+ style={{
100
+ "--rla-logo-light": `url('${logoInfo().lightSrc}')`,
101
+ "--rla-logo-dark": `url('${logoInfo().darkSrc}')`
102
+ }}
103
+ >
104
+ <img
105
+ src={logoInfo().lightSrc || ""}
106
+ alt={props.alt || ""}
107
+ class="rla-logo-light size-full block object-contain shrink-0"
108
+ />
109
+ <img
110
+ src={logoInfo().darkSrc || ""}
111
+ alt={props.alt || ""}
112
+ class="rla-logo-dark size-full hidden object-contain shrink-0"
113
+ />
114
+ </span>
115
+ }
116
+ >
117
+ <img
118
+ src={logoInfo().logoSrc || ""}
119
+ alt={props.alt || ""}
120
+ class="size-full block object-contain shrink-0"
121
+ />
122
+ </Show>
123
+ </Show>
124
+ </Show>
125
+ </a>
126
+ )
127
+ }
128
+
129
+ export default RLSLogo
@@ -0,0 +1,40 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import { Dynamic } from "solid-js/web"
3
+ import type { MainProps } from "./main"
4
+ import { mainTheme } from "./main.theme"
5
+
6
+ export interface RLSMainProps extends MainProps {
7
+ children?: JSX.Element
8
+ }
9
+
10
+ const RLSMain: Component<RLSMainProps> = (allProps) => {
11
+ const [props, rest] = splitProps(allProps, ["as", "ui", "class", "children"])
12
+
13
+ const tag = () => props.as ?? "main"
14
+
15
+ const resolvedClasses = createMemo(() =>
16
+ mainTheme({
17
+ hasContent: props.children !== undefined,
18
+ ui: props.ui,
19
+ class: props.class
20
+ })
21
+ )
22
+
23
+ return (
24
+ <Dynamic
25
+ component={tag()}
26
+ class={`${resolvedClasses().root} rla-main-container`}
27
+ data-slot="main"
28
+ {...rest}
29
+ >
30
+ {props.children}
31
+ <style>{`
32
+ .rla-main-container {
33
+ padding-top: var(--rl-total-header-height, 4rem);
34
+ }
35
+ `}</style>
36
+ </Dynamic>
37
+ )
38
+ }
39
+
40
+ export default RLSMain
@@ -0,0 +1,80 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { MarqueeProps } from "./marquee"
3
+ import { marqueeTheme } from "./marquee.theme"
4
+
5
+ export interface RLSMarqueeProps extends MarqueeProps {
6
+ children?: JSX.Element
7
+ }
8
+
9
+ const MARQUEE_KEYFRAMES = `
10
+ @keyframes marquee-left {
11
+ from { transform: translateX(0); }
12
+ to { transform: translateX(-100%); }
13
+ }
14
+ @keyframes marquee-right {
15
+ from { transform: translateX(-100%); }
16
+ to { transform: translateX(0); }
17
+ }
18
+ @keyframes marquee-up {
19
+ from { transform: translateY(0); }
20
+ to { transform: translateY(-100%); }
21
+ }
22
+ @keyframes marquee-down {
23
+ from { transform: translateY(-100%); }
24
+ to { transform: translateY(0); }
25
+ }
26
+ .animate-marquee,
27
+ .animate-marquee-left {
28
+ animation: marquee-left 30s linear infinite;
29
+ }
30
+ .animate-marquee-right {
31
+ animation: marquee-right 30s linear infinite;
32
+ }
33
+ .animate-marquee-up {
34
+ animation: marquee-up 30s linear infinite;
35
+ }
36
+ .animate-marquee-down {
37
+ animation: marquee-down 30s linear infinite;
38
+ }
39
+ `
40
+
41
+ const RLSMarquee: Component<RLSMarqueeProps> = (allProps) => {
42
+ const [props, rest] = splitProps(allProps, [
43
+ "speed",
44
+ "direction",
45
+ "pauseOnHover",
46
+ "ui",
47
+ "class",
48
+ "children"
49
+ ])
50
+
51
+ const resolvedClasses = createMemo(() =>
52
+ marqueeTheme({
53
+ direction: props.direction ?? "left",
54
+ pauseOnHover: props.pauseOnHover ?? true,
55
+ ui: props.ui,
56
+ class: props.class
57
+ })
58
+ )
59
+
60
+ const trackStyle = () => ({ "animation-duration": `${props.speed ?? 40}s` })
61
+
62
+ return (
63
+ <div class={resolvedClasses().root} data-slot="marquee-root" {...rest}>
64
+ <div class={resolvedClasses().track} data-slot="track" style={trackStyle()}>
65
+ {props.children}
66
+ </div>
67
+ <div
68
+ class={resolvedClasses().track}
69
+ data-slot="track"
70
+ style={trackStyle()}
71
+ aria-hidden="true"
72
+ >
73
+ {props.children}
74
+ </div>
75
+ <style>{MARQUEE_KEYFRAMES}</style>
76
+ </div>
77
+ )
78
+ }
79
+
80
+ export default RLSMarquee
@@ -0,0 +1,27 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { MeterProps } from "./meter"
3
+ import { meterTheme } from "./meter.theme"
4
+
5
+ export interface RLSMeterProps extends MeterProps {
6
+ children?: JSX.Element
7
+ }
8
+
9
+ const RLSMeter: Component<RLSMeterProps> = (allProps) => {
10
+ const [props, rest] = splitProps(allProps, ["ui", "class", "children"])
11
+
12
+ const resolvedClasses = createMemo(() =>
13
+ meterTheme({
14
+ ui: props.ui,
15
+ class: props.class,
16
+ ...allProps
17
+ })
18
+ )
19
+
20
+ return (
21
+ <div class={resolvedClasses().root} data-slot="root" {...rest}>
22
+ {props.children}
23
+ </div>
24
+ )
25
+ }
26
+
27
+ export default RLSMeter
@@ -23,7 +23,7 @@ const classes = modalTheme(Astro.props)
23
23
 
24
24
  const modalId = `rla-modal-${Math.random().toString(36).substring(2, 9)}`
25
25
  ---
26
- <div class={classes.root} data-slot="modal-container">
26
+ <div class={classes.root} data-slot="root">
27
27
  {triggerLabel ? (
28
28
  <button
29
29
  class={classes.trigger}