@rimelight/ui 0.0.47 → 0.0.48

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,171 @@
1
+ import { createMemo, For, splitProps, type Component, type JSX } from "solid-js"
2
+ import { Dynamic } from "solid-js/web"
3
+ import type { TimelineProps, TimelineItem } from "./timeline"
4
+ import { timelineTheme } from "./timeline.theme"
5
+ import RLSAvatar from "../avatar/RLSAvatar"
6
+ import RLSIcon from "../icon/RLSIcon"
7
+
8
+ export interface RLSTimelineProps extends TimelineProps {
9
+ children?: JSX.Element
10
+ indicator?: (ctx: { item: TimelineItem; index: number }) => JSX.Element
11
+ wrapper?: (ctx: { item: TimelineItem; index: number }) => JSX.Element
12
+ }
13
+
14
+ const RLSTimeline: Component<RLSTimelineProps> = (allProps) => {
15
+ const [props, rest] = splitProps(allProps, [
16
+ "as",
17
+ "items",
18
+ "size",
19
+ "color",
20
+ "orientation",
21
+ "valueKey",
22
+ "defaultValue",
23
+ "modelValue",
24
+ "reverse",
25
+ "ui",
26
+ "class",
27
+ "children",
28
+ "indicator",
29
+ "wrapper"
30
+ ])
31
+
32
+ const items = (): TimelineItem[] => props.items ?? []
33
+ const valueKey = (): string => props.valueKey ?? "value"
34
+ const reverse = (): boolean => props.reverse === true
35
+ const orientation = (): string => props.orientation ?? "vertical"
36
+
37
+ const getItemValue = (item: TimelineItem, index: number): string | number =>
38
+ item[valueKey()] !== undefined ? item[valueKey()] : index
39
+
40
+ const getItemState = (_item: TimelineItem, index: number): "active" | "completed" | undefined => {
41
+ const activeVal = props.modelValue !== undefined ? props.modelValue : props.defaultValue
42
+ if (activeVal === undefined) return undefined
43
+
44
+ let currentIndex = -1
45
+ if (items().length > 0) {
46
+ if (typeof activeVal === "string") {
47
+ currentIndex = items().findIndex((i) => getItemValue(i, items().indexOf(i)) === activeVal)
48
+ } else if (typeof activeVal === "number") {
49
+ currentIndex = reverse() ? items().length - 1 - activeVal : activeVal
50
+ }
51
+ }
52
+
53
+ if (currentIndex === -1) return undefined
54
+ if (index === currentIndex) return "active"
55
+ if (reverse()) return index > currentIndex ? "completed" : undefined
56
+ return index < currentIndex ? "completed" : undefined
57
+ }
58
+
59
+ const resolvedClasses = createMemo(() =>
60
+ timelineTheme({
61
+ size: props.size ?? "md",
62
+ color: props.color ?? "primary",
63
+ orientation: props.orientation ?? "vertical",
64
+ reverse: props.reverse ?? false,
65
+ ui: props.ui,
66
+ class: props.class
67
+ })
68
+ )
69
+
70
+ return (
71
+ <Dynamic
72
+ component={props.as || "div"}
73
+ data-slot="root"
74
+ class={resolvedClasses().root}
75
+ data-orientation={orientation()}
76
+ {...rest}
77
+ >
78
+ {items().length > 0 ? (
79
+ <For each={items()}>
80
+ {(item, index) => {
81
+ const state = getItemState(item, index())
82
+ const isLast = index() === items().length - 1
83
+ const avatar =
84
+ typeof item.avatar === "object" && item.avatar !== null ? item.avatar : undefined
85
+
86
+ return (
87
+ <div
88
+ data-slot="item"
89
+ class={`${resolvedClasses().item} ${item.ui?.item || ""} ${item.class || ""}`}
90
+ data-state={state}
91
+ >
92
+ <div
93
+ data-slot="container"
94
+ class={`${resolvedClasses().container} ${item.ui?.container || ""}`}
95
+ >
96
+ <RLSAvatar
97
+ size={props.size ?? "md"}
98
+ src={avatar?.src}
99
+ alt={avatar?.alt}
100
+ {...(avatar ? avatar : {})}
101
+ data-slot="indicator"
102
+ class={`${resolvedClasses().indicator} ${item.ui?.indicator || ""}`}
103
+ ui={{
104
+ icon: "text-highlighted group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted",
105
+ fallback:
106
+ "text-highlighted group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted"
107
+ }}
108
+ >
109
+ {props.indicator ? (
110
+ props.indicator({ item, index: index() })
111
+ ) : item.icon ? (
112
+ <RLSIcon name={item.icon} class="text-inherit" />
113
+ ) : null}
114
+ </RLSAvatar>
115
+
116
+ {!isLast ? (
117
+ <div
118
+ data-slot="separator"
119
+ class={`${resolvedClasses().separator} ${item.ui?.separator || ""}`}
120
+ data-orientation={orientation()}
121
+ />
122
+ ) : null}
123
+ </div>
124
+
125
+ <div
126
+ data-slot="wrapper"
127
+ class={`${resolvedClasses().wrapper} ${item.ui?.wrapper || ""}`}
128
+ >
129
+ {props.wrapper ? (
130
+ props.wrapper({ item, index: index() })
131
+ ) : (
132
+ <>
133
+ {item.date ? (
134
+ <div
135
+ data-slot="date"
136
+ class={`${resolvedClasses().date} ${item.ui?.date || ""}`}
137
+ >
138
+ {item.date}
139
+ </div>
140
+ ) : null}
141
+ {item.title ? (
142
+ <div
143
+ data-slot="title"
144
+ class={`${resolvedClasses().title} ${item.ui?.title || ""}`}
145
+ >
146
+ {item.title}
147
+ </div>
148
+ ) : null}
149
+ {item.description ? (
150
+ <div
151
+ data-slot="description"
152
+ class={`${resolvedClasses().description} ${item.ui?.description || ""}`}
153
+ >
154
+ {item.description}
155
+ </div>
156
+ ) : null}
157
+ </>
158
+ )}
159
+ </div>
160
+ </div>
161
+ )
162
+ }}
163
+ </For>
164
+ ) : props.children ? (
165
+ props.children
166
+ ) : null}
167
+ </Dynamic>
168
+ )
169
+ }
170
+
171
+ export default RLSTimeline
@@ -0,0 +1,179 @@
1
+ import {
2
+ createMemo,
3
+ createSignal,
4
+ onMount,
5
+ onCleanup,
6
+ splitProps,
7
+ type Component,
8
+ type JSX
9
+ } from "solid-js"
10
+ import type { ToastProps } from "./toast"
11
+ import { toastTheme } from "./toast.theme"
12
+ import RLSIcon from "../icon/RLSIcon"
13
+
14
+ export interface RLSToastProps extends ToastProps {
15
+ onDismiss?: () => void
16
+ children?: JSX.Element
17
+ titleSlot?: JSX.Element
18
+ descriptionSlot?: JSX.Element
19
+ actionsSlot?: JSX.Element
20
+ }
21
+
22
+ const variantIcons: Record<string, string> = {
23
+ default: "i-rl-bell",
24
+ error: "i-rl-circleCheck",
25
+ success: "i-rl-circleCheck",
26
+ warning: "i-rl-alertTriangle",
27
+ info: "i-rl-info"
28
+ }
29
+
30
+ const RLSToast: Component<RLSToastProps> = (allProps) => {
31
+ const [props, rest] = splitProps(allProps, [
32
+ "title",
33
+ "description",
34
+ "variant",
35
+ "actionLabel",
36
+ "duration",
37
+ "dismissable",
38
+ "onDismiss",
39
+ "ui",
40
+ "class",
41
+ "children",
42
+ "titleSlot",
43
+ "descriptionSlot",
44
+ "actionsSlot"
45
+ ])
46
+
47
+ const [leaving, setLeaving] = createSignal(false)
48
+ let rootRef: HTMLDivElement | undefined
49
+ let timerId: ReturnType<typeof setTimeout> | null = null
50
+ let dismissTimerId: ReturnType<typeof setTimeout> | undefined
51
+ let startTime = 0
52
+ let remaining = props.duration ?? 6000
53
+
54
+ const isError = () => props.variant === "error"
55
+
56
+ const resolvedClasses = createMemo(() =>
57
+ toastTheme({
58
+ variant: ["success", "error", "warning", "info"].includes(props.variant ?? "")
59
+ ? (props.variant as "success" | "error" | "warning" | "info")
60
+ : "default",
61
+ ui: props.ui,
62
+ class: props.class
63
+ })
64
+ )
65
+
66
+ const icon = () => variantIcons[props.variant ?? ""] ?? variantIcons["default"]!
67
+
68
+ const dismiss = () => {
69
+ if (leaving()) return
70
+ setLeaving(true)
71
+ if (props.onDismiss) {
72
+ if (dismissTimerId !== undefined) clearTimeout(dismissTimerId)
73
+ dismissTimerId = setTimeout(props.onDismiss, 300)
74
+ }
75
+ }
76
+
77
+ const startTimer = () => {
78
+ const duration = props.duration ?? 6000
79
+ if (duration > 0 && remaining > 0 && timerId === null) {
80
+ startTime = Date.now()
81
+ timerId = setTimeout(dismiss, remaining)
82
+ }
83
+ }
84
+
85
+ const pauseTimer = () => {
86
+ if (timerId !== null) {
87
+ clearTimeout(timerId)
88
+ timerId = null
89
+ remaining -= Date.now() - startTime
90
+ }
91
+ }
92
+
93
+ onMount(() => {
94
+ const root = rootRef
95
+ if (!root) return
96
+
97
+ const duration = props.duration ?? 6000
98
+ if (duration > 0) {
99
+ startTimer()
100
+ root.addEventListener("mouseenter", pauseTimer)
101
+ root.addEventListener("mouseleave", startTimer)
102
+ root.addEventListener("focusin", pauseTimer)
103
+ root.addEventListener("focusout", (e) => {
104
+ if (!root.contains(e.relatedTarget as Node)) startTimer()
105
+ })
106
+ }
107
+
108
+ onCleanup(() => {
109
+ if (timerId !== null) clearTimeout(timerId)
110
+ if (dismissTimerId !== undefined) clearTimeout(dismissTimerId)
111
+ root.removeEventListener("mouseenter", pauseTimer)
112
+ root.removeEventListener("mouseleave", startTimer)
113
+ root.removeEventListener("focusin", pauseTimer)
114
+ })
115
+ })
116
+
117
+ return (
118
+ <div
119
+ ref={(el) => (rootRef = el)}
120
+ class={`${resolvedClasses().root} ${leaving() ? "opacity-0 translate-y-2 pointer-events-none" : ""}`}
121
+ data-slot="root"
122
+ data-toast
123
+ data-duration={props.duration ?? 6000}
124
+ data-dismissable={(props.dismissable !== false).toString()}
125
+ role={isError() ? "alert" : "status"}
126
+ aria-live={isError() ? "assertive" : "polite"}
127
+ aria-atomic="true"
128
+ tabindex="-1"
129
+ {...rest}
130
+ >
131
+ <RLSIcon name={icon()} class="size-4 shrink-0 mt-0.5" aria-hidden="true" />
132
+
133
+ <div class="flex flex-col gap-0.5 flex-1 min-w-0">
134
+ {props.titleSlot || props.title ? (
135
+ <div class={resolvedClasses().title} data-slot="title">
136
+ {props.titleSlot ? props.titleSlot : props.title}
137
+ </div>
138
+ ) : null}
139
+ {props.descriptionSlot || props.description ? (
140
+ <div class={resolvedClasses().description} data-slot="description">
141
+ {props.descriptionSlot ? props.descriptionSlot : props.description}
142
+ </div>
143
+ ) : null}
144
+ {props.children}
145
+ {props.actionsSlot || props.actionLabel ? (
146
+ <div class="flex items-center justify-end gap-2 mt-3" data-slot="actions">
147
+ {props.actionsSlot ? (
148
+ props.actionsSlot
149
+ ) : (
150
+ <button
151
+ type="button"
152
+ class={resolvedClasses().action}
153
+ data-slot="action"
154
+ data-toast-action
155
+ >
156
+ {props.actionLabel}
157
+ </button>
158
+ )}
159
+ </div>
160
+ ) : null}
161
+ </div>
162
+
163
+ {props.dismissable !== false && (
164
+ <button
165
+ type="button"
166
+ class={resolvedClasses().close}
167
+ data-slot="close"
168
+ data-toast-close
169
+ aria-label="Dismiss notification"
170
+ onClick={dismiss}
171
+ >
172
+ <RLSIcon name="i-rl-close" class="size-3.5" aria-hidden="true" />
173
+ </button>
174
+ )}
175
+ </div>
176
+ )
177
+ }
178
+
179
+ export default RLSToast
@@ -0,0 +1,82 @@
1
+ import { createSignal, For, onMount, onCleanup, splitProps, type Component } from "solid-js"
2
+ import { toasts, removeToast, addToast } from "../toast/store"
3
+ import type { ToastItem } from "../toast/store"
4
+ import RLSToast from "../toast/RLSToast"
5
+
6
+ export interface RLSToasterProps {
7
+ class?: any
8
+ [key: string]: unknown
9
+ }
10
+
11
+ const RLSToaster: Component<RLSToasterProps> = (allProps) => {
12
+ const [props, rest] = splitProps(allProps, ["class"])
13
+ const [list, setList] = createSignal<ToastItem[]>([])
14
+
15
+ onMount(() => {
16
+ const unsubscribe = toasts.subscribe((items) => setList([...items]))
17
+ onCleanup(unsubscribe)
18
+
19
+ const stored = sessionStorage.getItem("pending_toast")
20
+ if (stored) {
21
+ sessionStorage.removeItem("pending_toast")
22
+ try {
23
+ const parsed = JSON.parse(stored)
24
+ if (parsed && parsed.title) {
25
+ addToast(parsed)
26
+ }
27
+ } catch {}
28
+ }
29
+
30
+ const url = new URL(window.location.href)
31
+ let toastTitle = url.searchParams.get("toast_title")
32
+ const toastDesc = url.searchParams.get("toast_desc") ?? undefined
33
+ let toastVariant = url.searchParams.get("toast_variant") || "success"
34
+
35
+ if (!toastTitle) {
36
+ if (url.searchParams.has("signed_in")) {
37
+ toastTitle = "Signed in successfully"
38
+ } else if (url.searchParams.has("new")) {
39
+ toastTitle = "Account created successfully"
40
+ }
41
+ }
42
+
43
+ if (toastTitle) {
44
+ url.searchParams.delete("toast_title")
45
+ url.searchParams.delete("toast_desc")
46
+ url.searchParams.delete("toast_variant")
47
+ url.searchParams.delete("signed_in")
48
+ url.searchParams.delete("new")
49
+ const cleanUrl = url.pathname + (url.search ? url.search : "")
50
+ window.history.replaceState({}, "", cleanUrl)
51
+
52
+ const payload: Record<string, unknown> = { title: toastTitle, variant: toastVariant }
53
+ if (toastDesc) payload["description"] = toastDesc
54
+ addToast(payload as Omit<ToastItem, "id">)
55
+ }
56
+ })
57
+
58
+ return (
59
+ <div
60
+ id="rla-toaster-container"
61
+ class={`fixed bottom-5 right-5 z-[200] flex flex-col gap-2 max-w-sm w-full pointer-events-none ${props.class || ""}`}
62
+ aria-live="polite"
63
+ aria-atomic="false"
64
+ role="status"
65
+ {...rest}
66
+ >
67
+ <For each={list()}>
68
+ {(item) => (
69
+ <RLSToast
70
+ title={item.title}
71
+ {...(item.description ? { description: item.description } : {})}
72
+ {...(item.variant ? { variant: item.variant } : {})}
73
+ {...(item.duration ? { duration: item.duration } : {})}
74
+ onDismiss={() => removeToast(item.id)}
75
+ />
76
+ )}
77
+ </For>
78
+ </div>
79
+ )
80
+ }
81
+
82
+ export default RLSToaster
@@ -0,0 +1,48 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { TooltipProps } from "./tooltip"
3
+ import { tooltipTheme } from "./tooltip.theme"
4
+
5
+ export interface RLSTooltipProps extends TooltipProps {
6
+ children?: JSX.Element
7
+ contentSlot?: JSX.Element
8
+ }
9
+
10
+ const RLSTooltip: Component<RLSTooltipProps> = (allProps) => {
11
+ const [props, rest] = splitProps(allProps, [
12
+ "content",
13
+ "placement",
14
+ "ui",
15
+ "class",
16
+ "children",
17
+ "contentSlot"
18
+ ])
19
+
20
+ const placement = () => props.placement ?? "top"
21
+
22
+ const resolvedClasses = createMemo(() =>
23
+ tooltipTheme({
24
+ placement: placement(),
25
+ ui: props.ui,
26
+ class: props.class
27
+ })
28
+ )
29
+
30
+ return (
31
+ <div
32
+ class={resolvedClasses().root}
33
+ data-slot="tooltip-container"
34
+ data-placement={placement()}
35
+ {...rest}
36
+ >
37
+ <div class={resolvedClasses().trigger} data-slot="trigger" tabIndex={0}>
38
+ {props.children}
39
+ </div>
40
+
41
+ <div class={resolvedClasses().content} data-slot="content" role="tooltip">
42
+ {props.contentSlot !== undefined ? props.contentSlot : props.content}
43
+ </div>
44
+ </div>
45
+ )
46
+ }
47
+
48
+ export default RLSTooltip
@@ -0,0 +1,26 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { TourProps } from "./tour"
3
+ import { tourTheme } from "./tour.theme"
4
+
5
+ export interface RLSTourProps extends TourProps {
6
+ children?: JSX.Element
7
+ }
8
+
9
+ const RLSTour: Component<RLSTourProps> = (allProps) => {
10
+ const [props, rest] = splitProps(allProps, ["ui", "class", "children"])
11
+
12
+ const resolvedClasses = createMemo(() =>
13
+ tourTheme({
14
+ ui: props.ui,
15
+ class: props.class
16
+ })
17
+ )
18
+
19
+ return (
20
+ <div class={resolvedClasses().root} data-slot="root" {...rest}>
21
+ {props.children}
22
+ </div>
23
+ )
24
+ }
25
+
26
+ export default RLSTour
@@ -0,0 +1,26 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { TreeProps } from "./tree"
3
+ import { treeTheme } from "./tree.theme"
4
+
5
+ export interface RLSTreeProps extends TreeProps {
6
+ children?: JSX.Element
7
+ }
8
+
9
+ const RLSTree: Component<RLSTreeProps> = (allProps) => {
10
+ const [props, rest] = splitProps(allProps, ["ui", "class", "children"])
11
+
12
+ const resolvedClasses = createMemo(() =>
13
+ treeTheme({
14
+ ui: props.ui,
15
+ class: props.class
16
+ })
17
+ )
18
+
19
+ return (
20
+ <div class={resolvedClasses().root} data-slot="root" {...rest}>
21
+ {props.children}
22
+ </div>
23
+ )
24
+ }
25
+
26
+ export default RLSTree
@@ -0,0 +1,26 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { UserProps } from "./user"
3
+ import { userTheme } from "./user.theme"
4
+
5
+ export interface RLSUserProps extends UserProps {
6
+ children?: JSX.Element
7
+ }
8
+
9
+ const RLSUser: Component<RLSUserProps> = (allProps) => {
10
+ const [props, rest] = splitProps(allProps, ["ui", "class", "children"])
11
+
12
+ const classes = createMemo(() =>
13
+ userTheme({
14
+ ui: props.ui,
15
+ class: props.class
16
+ })
17
+ )
18
+
19
+ return (
20
+ <div class={classes()["root"]} data-slot="root" {...rest}>
21
+ {props.children}
22
+ </div>
23
+ )
24
+ }
25
+
26
+ export default RLSUser
@@ -131,10 +131,12 @@ const ariaLabel = isPlayable ? "Play YouTube Video" : "YouTube Video Unavailable
131
131
 
132
132
  <div
133
133
  class:list={[classes.root]}
134
+ data-slot="root"
134
135
  {...rest}
135
136
  >
136
137
  <button
137
138
  type="button"
139
+ data-slot="trigger"
138
140
  data-youtube-trigger
139
141
  aria-label={ariaLabel}
140
142
  data-embed-url={isPlayable ? embedUrl : undefined}
@@ -150,10 +152,11 @@ const ariaLabel = isPlayable ? "Play YouTube Video" : "YouTube Video Unavailable
150
152
  height="720"
151
153
  loading="lazy"
152
154
  class:list={[classes.image]}
155
+ data-slot="image"
153
156
  />
154
157
 
155
158
  <slot name="icon">
156
- <RLAIcon name={icon} class={classes.icon} aria-hidden="true" />
159
+ <RLAIcon name={icon} class={classes.icon} data-slot="icon" aria-hidden="true" />
157
160
  </slot>
158
161
  </button>
159
162
  </div>