@rimelight/ui 0.0.46 → 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 (222) hide show
  1. package/dist/icons-DPnFQCts.d.mts +72 -0
  2. package/dist/icons.d.mts +1 -1
  3. package/dist/index.d.mts +5 -6
  4. package/dist/preset.d.mts +1 -1
  5. package/dist/preset.mjs +73 -1
  6. package/dist/resolver.d.mts +4 -5
  7. package/dist/resolver.mjs +2 -4
  8. package/dist/shortcuts.d.mts +10 -11
  9. package/dist/stores.d.mts +3 -4
  10. package/dist/{types-DqAgCNcm.d.mts → types-DWmKMcYC.d.mts} +1 -1
  11. package/dist/types.d.mts +1 -1
  12. package/package.json +8 -6
  13. package/src/components/3d-hover/RLS3dHover.tsx +21 -0
  14. package/src/components/accordion/RLSAccordion.tsx +112 -0
  15. package/src/components/app/RLSApp.tsx +21 -0
  16. package/src/components/aspect-ratio/RLSAspectRatio.tsx +30 -0
  17. package/src/components/audio/RLSAudio.tsx +27 -0
  18. package/src/components/avatar/RLSAvatar.tsx +142 -0
  19. package/src/components/avatar/avatar.ts +22 -21
  20. package/src/components/avatar-group/RLSAvatarGroup.tsx +163 -0
  21. package/src/components/badge/RLSBadge.tsx +1 -1
  22. package/src/components/badge/RLVBadge.vue +5 -3
  23. package/src/components/banner/RLABanner.astro +1 -1
  24. package/src/components/banner/RLSBanner.tsx +151 -0
  25. package/src/components/breadcrumb/RLSBreadcrumb.tsx +194 -0
  26. package/src/components/browser-mockup/RLSBrowserMockup.tsx +21 -0
  27. package/src/components/button/RLSButton.tsx +53 -38
  28. package/src/components/button/RLVButton.vue +44 -32
  29. package/src/components/calendar/RLSCalendar.tsx +26 -0
  30. package/src/components/callout/RLSCallout.tsx +151 -0
  31. package/src/components/card/RLSCard.tsx +4 -0
  32. package/src/components/card/RLVCard.vue +4 -0
  33. package/src/components/card/card.ts +10 -0
  34. package/src/components/carousel/RLACarousel.astro +14 -1
  35. package/src/components/carousel/RLSCarousel.tsx +260 -0
  36. package/src/components/chart/RLSChart.tsx +299 -0
  37. package/src/components/chat/RLSChat.tsx +27 -0
  38. package/src/components/chat-message/RLSChatMessage.tsx +27 -0
  39. package/src/components/chat-messages/RLSChatMessages.tsx +27 -0
  40. package/src/components/chat-palette/RLSChatPalette.tsx +27 -0
  41. package/src/components/chat-prompt/RLSChatPrompt.tsx +27 -0
  42. package/src/components/chat-prompt-submit/RLSChatPromptSubmit.tsx +27 -0
  43. package/src/components/chat-reasoning/RLSChatReasoning.tsx +27 -0
  44. package/src/components/chat-shimmer/RLSChatShimmer.tsx +27 -0
  45. package/src/components/chat-tool/RLSChatTool.tsx +27 -0
  46. package/src/components/checkbox/RLACheckbox.astro +1 -0
  47. package/src/components/checkbox/RLSCheckbox.tsx +1 -1
  48. package/src/components/checkbox/checkbox.theme.ts +2 -2
  49. package/src/components/chip/RLSChip.tsx +65 -0
  50. package/src/components/collapsible/RLSCollapsible.tsx +89 -0
  51. package/src/components/color-area/RLSColorArea.tsx +554 -0
  52. package/src/components/color-field/RLSColorField.tsx +236 -0
  53. package/src/components/color-picker/RLSColorPicker.tsx +26 -0
  54. package/src/components/color-slider/RLSColorSlider.tsx +373 -0
  55. package/src/components/command-palette/RLSCommandPalette.tsx +26 -0
  56. package/src/components/compare/RLSCompare.tsx +26 -0
  57. package/src/components/confirm/RLSConfirm.tsx +173 -0
  58. package/src/components/container/RLSContainer.tsx +24 -0
  59. package/src/components/context-menu/RLSContextMenu.tsx +26 -0
  60. package/src/components/copy-markdown/RLSCopyMarkdown.tsx +57 -0
  61. package/src/components/dashboard-group/RLSDashboardGroup.tsx +29 -0
  62. package/src/components/dashboard-navbar/RLSDashboardNavbar.tsx +116 -0
  63. package/src/components/dashboard-panel/RLSDashboardPanel.tsx +84 -0
  64. package/src/components/dashboard-resize-handle/RLSDashboardResizeHandle.tsx +35 -0
  65. package/src/components/dashboard-search/RLADashboardSearch.astro +1 -1
  66. package/src/components/dashboard-search/RLSDashboardSearch.tsx +125 -0
  67. package/src/components/dashboard-search-button/RLSDashboardSearchButton.tsx +82 -0
  68. package/src/components/dashboard-sidebar/RLADashboardSidebar.astro +4 -4
  69. package/src/components/dashboard-sidebar/RLSDashboardSidebar.tsx +184 -0
  70. package/src/components/dashboard-sidebar-collapse/RLSDashboardSidebarCollapse.tsx +46 -0
  71. package/src/components/dashboard-sidebar-toggle/RLSDashboardSidebarToggle.tsx +35 -0
  72. package/src/components/dashboard-toolbar/RLSDashboardToolbar.tsx +49 -0
  73. package/src/components/date/RLSDate.tsx +34 -0
  74. package/src/components/dock/RLSDock.tsx +26 -0
  75. package/src/components/drawer/RLSDrawer.tsx +177 -0
  76. package/src/components/dropdown-menu/RLADropdownMenu.astro +250 -241
  77. package/src/components/dropdown-menu/RLSDropdownMenu.tsx +183 -86
  78. package/src/components/editor/RLSEditor.tsx +26 -0
  79. package/src/components/empty/RLSEmpty.tsx +132 -0
  80. package/src/components/error/RLSError.tsx +26 -0
  81. package/src/components/field-group/RLSFieldGroup.tsx +46 -0
  82. package/src/components/fieldset/RLSFieldset.tsx +26 -0
  83. package/src/components/file-upload/RLAFileUpload.astro +1 -1
  84. package/src/components/file-upload/RLSFileUpload.tsx +163 -0
  85. package/src/components/floating-action/RLSFloatingAction.tsx +26 -0
  86. package/src/components/footer/RLSFooter.tsx +56 -0
  87. package/src/components/form/RLSForm.tsx +34 -0
  88. package/src/components/gallery/RLSGallery.tsx +21 -0
  89. package/src/components/gamepad/RLSGamepad.tsx +269 -0
  90. package/src/components/grid/RLSGrid.tsx +29 -0
  91. package/src/components/head/RLAHead.astro +9 -0
  92. package/src/components/head/RLSHead.tsx +42 -0
  93. package/src/components/head/UIHead.astro +3 -0
  94. package/src/components/header/HeaderLayer.astro +1 -1
  95. package/src/components/header/RLSHeader.tsx +87 -0
  96. package/src/components/hover-card/RLSHoverCard.tsx +72 -0
  97. package/src/components/icon/RLSIcon.tsx +3 -1
  98. package/src/components/image/RLAImage.astro +447 -138
  99. package/src/components/image/RLSImage.tsx +545 -0
  100. package/src/components/image/image.theme.ts +19 -3
  101. package/src/components/image/image.ts +31 -1
  102. package/src/components/input/RLAInput.astro +62 -51
  103. package/src/components/input/RLSInput.tsx +1 -1
  104. package/src/components/input-date/RLSInputDate.tsx +92 -0
  105. package/src/components/input-menu/RLAInputMenu.astro +3 -3
  106. package/src/components/input-menu/RLSInputMenu.tsx +199 -0
  107. package/src/components/input-number/RLSInputNumber.tsx +184 -0
  108. package/src/components/input-pin/RLSInputPin.tsx +185 -0
  109. package/src/components/input-rating/RLAInputRating.astro +8 -8
  110. package/src/components/input-rating/RLSInputRating.tsx +198 -0
  111. package/src/components/input-rating/input-rating.ts +4 -0
  112. package/src/components/input-tags/RLSInputTags.tsx +94 -0
  113. package/src/components/input-time/RLSInputTime.tsx +92 -0
  114. package/src/components/kbd/RLSKbd.tsx +37 -0
  115. package/src/components/keyboard/RLSKeyboard.tsx +476 -0
  116. package/src/components/knob/RLSKnob.tsx +27 -0
  117. package/src/components/label/RLSLabel.tsx +27 -0
  118. package/src/components/layout-grid/RLALayoutGrid.astro +29 -29
  119. package/src/components/layout-grid/RLSLayoutGrid.tsx +402 -0
  120. package/src/components/layout-grid/layout-grid.ts +25 -1
  121. package/src/components/link/RLALink.astro +5 -5
  122. package/src/components/link/RLSLink.tsx +6 -5
  123. package/src/components/link/link.ts +21 -12
  124. package/src/components/link-group/RLSLinkGroup.tsx +76 -0
  125. package/src/components/listbox/RLSListbox.tsx +27 -0
  126. package/src/components/locale-selector/RLALocaleSelector.astro +110 -102
  127. package/src/components/locale-selector/RLSLocaleSelector.tsx +178 -0
  128. package/src/components/locale-selector/locale-selector.ts +2 -7
  129. package/src/components/logo/RLALogo.astro +153 -102
  130. package/src/components/logo/RLSLogo.tsx +129 -0
  131. package/src/components/main/RLSMain.tsx +40 -0
  132. package/src/components/marquee/RLSMarquee.tsx +80 -0
  133. package/src/components/meter/RLSMeter.tsx +27 -0
  134. package/src/components/modal/RLAModal.astro +1 -1
  135. package/src/components/modal/RLSModal.tsx +109 -72
  136. package/src/components/navigation-menu/RLANavigationMenu.astro +6 -6
  137. package/src/components/navigation-menu/RLSNavigationMenu.tsx +228 -0
  138. package/src/components/navigation-menu/navigation-menu.ts +2 -2
  139. package/src/components/package-managers/RLSPackageManagers.tsx +204 -0
  140. package/src/components/page/RLSPage.tsx +21 -0
  141. package/src/components/page-aside/RLSPageAside.tsx +21 -0
  142. package/src/components/page-body/RLSPageBody.tsx +21 -0
  143. package/src/components/page-header/RLSPageHeader.tsx +21 -0
  144. package/src/components/page-section/RLSPageSection.tsx +201 -0
  145. package/src/components/pagination/RLSPagination.tsx +114 -0
  146. package/src/components/password/RLSPassword.tsx +27 -0
  147. package/src/components/phone-mockup/RLSPhoneMockup.tsx +27 -0
  148. package/src/components/placeholder/RLSPlaceholder.tsx +47 -0
  149. package/src/components/popover/RLAPopover.astro +2 -2
  150. package/src/components/popover/RLSPopover.tsx +124 -0
  151. package/src/components/post/RLSPost.tsx +134 -0
  152. package/src/components/pricing-plan/RLSPricingPlan.tsx +26 -0
  153. package/src/components/pricing-table/RLSPricingTable.tsx +26 -0
  154. package/src/components/progress/RLSProgress.tsx +53 -0
  155. package/src/components/prose/RLSProse.tsx +26 -0
  156. package/src/components/qr-code/RLSQrCode.tsx +26 -0
  157. package/src/components/quote/RLAQuote.astro +10 -6
  158. package/src/components/quote/RLSQuote.tsx +37 -0
  159. package/src/components/quote/quote.theme.ts +5 -2
  160. package/src/components/radio-group/RLSRadioGroup.tsx +37 -0
  161. package/src/components/rating/RLSRating.tsx +27 -0
  162. package/src/components/scroll-area/RLAScrollArea.astro +1 -1
  163. package/src/components/scroll-area/RLSScrollArea.tsx +210 -0
  164. package/src/components/scroll-to-top/RLAScrollToTop.astro +5 -4
  165. package/src/components/scroll-to-top/RLSScrollToTop.tsx +145 -0
  166. package/src/components/search/RLASearch.astro +6 -6
  167. package/src/components/search/RLSSearch.tsx +237 -0
  168. package/src/components/select/RLASelect.astro +67 -4
  169. package/src/components/select/RLSSelect.tsx +107 -39
  170. package/src/components/select/RLVSelect.vue +50 -1
  171. package/src/components/select/select.theme.ts +30 -10
  172. package/src/components/select/select.ts +20 -1
  173. package/src/components/separator/RLSSeparator.tsx +92 -0
  174. package/src/components/share/RLSShare.tsx +66 -0
  175. package/src/components/shortcuts/RLAShortcuts.astro +2 -2
  176. package/src/components/shortcuts/RLSShortcuts.tsx +393 -0
  177. package/src/components/sidebar/RLASidebar.astro +1 -1
  178. package/src/components/sidebar/RLSSidebar.tsx +271 -0
  179. package/src/components/skeleton/RLSSkeleton.tsx +21 -0
  180. package/src/components/slideover/RLASlideover.astro +1 -1
  181. package/src/components/slideover/RLSSlideover.tsx +159 -0
  182. package/src/components/slider/RLSSlider.tsx +112 -0
  183. package/src/components/speed-dial/RLSSpeedDial.tsx +27 -0
  184. package/src/components/spinner/RLSSpinner.tsx +22 -0
  185. package/src/components/splitter/RLASplitter.astro +1 -1
  186. package/src/components/splitter/RLSSplitter.tsx +178 -0
  187. package/src/components/spoiler/RLSSpoiler.tsx +26 -0
  188. package/src/components/stepper/RLAStepper.astro +9 -9
  189. package/src/components/stepper/RLSStepper.tsx +205 -0
  190. package/src/components/steps/RLSSteps.tsx +108 -0
  191. package/src/components/sticky-surface/RLSStickySurface.tsx +63 -0
  192. package/src/components/surround/RLSSurround.tsx +57 -0
  193. package/src/components/switch/RLSSwitch.tsx +56 -0
  194. package/src/components/table/RLATable.astro +1044 -579
  195. package/src/components/table/RLSTable.tsx +893 -0
  196. package/src/components/table/table.theme.ts +47 -16
  197. package/src/components/table/table.ts +104 -66
  198. package/src/components/table-of-contents/RLSTableOfContents.tsx +196 -0
  199. package/src/components/tabs/RLATabs.astro +8 -8
  200. package/src/components/tabs/RLSTabs.tsx +298 -0
  201. package/src/components/textarea/RLATextarea.astro +1 -0
  202. package/src/components/textarea/RLSTextarea.tsx +3 -1
  203. package/src/components/theme-selector/RLAThemeSelector.astro +85 -56
  204. package/src/components/theme-selector/RLSThemeSelector.tsx +131 -0
  205. package/src/components/theme-selector/theme-selector.theme.ts +5 -7
  206. package/src/components/theme-selector/theme-selector.ts +11 -1
  207. package/src/components/timeline/RLSTimeline.tsx +171 -0
  208. package/src/components/toast/RLAToast.astro +2 -2
  209. package/src/components/toast/RLSToast.tsx +179 -0
  210. package/src/components/toaster/RLSToaster.tsx +82 -0
  211. package/src/components/tooltip/RLSTooltip.tsx +48 -0
  212. package/src/components/tour/RLSTour.tsx +26 -0
  213. package/src/components/tree/RLSTree.tsx +26 -0
  214. package/src/components/user/RLSUser.tsx +26 -0
  215. package/src/components/video/RLAVideo.astro +4 -1
  216. package/src/components/video/RLSVideo.tsx +158 -0
  217. package/src/components/watermark/RLSWatermark.tsx +27 -0
  218. package/src/components/window-mockup/RLSWindowMockup.tsx +27 -0
  219. package/src/preset.ts +73 -1
  220. package/src/resolver.ts +6 -1
  221. package/src/virtual.d.ts +6 -0
  222. package/dist/icons--RzV1RTU.d.mts +0 -72
@@ -0,0 +1,142 @@
1
+ import { createMemo, splitProps, type Component, type JSX } from "solid-js"
2
+ import type { AvatarProps } from "./avatar"
3
+ import { avatarTheme } from "./avatar.theme"
4
+ import RLSIcon from "../icon/RLSIcon"
5
+
6
+ export interface RLSAvatarProps extends AvatarProps {
7
+ children?: JSX.Element
8
+ fallbackSlot?: JSX.Element
9
+ badgeSlot?: JSX.Element
10
+ imgProps?: JSX.ImgHTMLAttributes<HTMLImageElement>
11
+ }
12
+
13
+ const RLSAvatar: Component<RLSAvatarProps> = (allProps) => {
14
+ const [props, rest] = splitProps(allProps, [
15
+ "src",
16
+ "alt",
17
+ "fallback",
18
+ "initials",
19
+ "title",
20
+ "subtitle",
21
+ "label",
22
+ "badge",
23
+ "badgeColor",
24
+ "badgePosition",
25
+ "size",
26
+ "color",
27
+ "loading",
28
+ "referrerpolicy",
29
+ "crossorigin",
30
+ "decoding",
31
+ "height",
32
+ "width",
33
+ "sizes",
34
+ "srcset",
35
+ "ui",
36
+ "class",
37
+ "children",
38
+ "fallbackSlot",
39
+ "badgeSlot",
40
+ "imgProps"
41
+ ])
42
+
43
+ const resolvedClasses = createMemo(() =>
44
+ avatarTheme({
45
+ size: props.size ?? "md",
46
+ color: props.color ?? "neutral",
47
+ badgePosition: props.badgePosition ?? "bottom-right",
48
+ ui: props.ui,
49
+ class: props.class
50
+ })
51
+ )
52
+
53
+ const avatarFallback = () => props.fallback || props.initials
54
+ const hasTextLayout = () => Boolean(props.title || props.subtitle)
55
+ const badgeClass = () =>
56
+ props.badgeColor?.startsWith("bg-")
57
+ ? props.badgeColor
58
+ : `bg-${props.badgeColor ?? "success"}-500`
59
+
60
+ const image = () => (
61
+ <>
62
+ {props.src ? (
63
+ <img
64
+ src={props.src}
65
+ alt={props.alt ?? ""}
66
+ class={resolvedClasses().image}
67
+ data-slot="image"
68
+ loading={props.loading}
69
+ referrerPolicy={props.referrerpolicy || undefined}
70
+ crossorigin={props.crossorigin || undefined}
71
+ decoding={props.decoding}
72
+ {...props.imgProps}
73
+ />
74
+ ) : (
75
+ <span class={resolvedClasses().fallback} data-slot="fallback">
76
+ {props.fallbackSlot ? (
77
+ props.fallbackSlot
78
+ ) : avatarFallback() ? (
79
+ avatarFallback()
80
+ ) : (
81
+ <RLSIcon name="i-rl-user" class={resolvedClasses().icon} aria-hidden="true" />
82
+ )}
83
+ </span>
84
+ )}
85
+ </>
86
+ )
87
+
88
+ const badgeEl = () =>
89
+ props.badge || props.badgeSlot ? (
90
+ <span class={`${resolvedClasses().badge} ${badgeClass()}`} data-slot="badge">
91
+ {props.badgeSlot
92
+ ? props.badgeSlot
93
+ : typeof props.badge === "string" || typeof props.badge === "number"
94
+ ? props.badge
95
+ : null}
96
+ </span>
97
+ ) : null
98
+
99
+ if (hasTextLayout()) {
100
+ return (
101
+ <div class="flex items-center gap-3" data-slot="profile-wrapper">
102
+ <span
103
+ class={resolvedClasses().root}
104
+ data-slot="root"
105
+ aria-label={props.label || props.title}
106
+ role={props.label || props.title ? "img" : undefined}
107
+ {...rest}
108
+ >
109
+ {props.children ? props.children : image()}
110
+ {badgeEl()}
111
+ </span>
112
+ <div class="flex flex-col leading-tight">
113
+ {props.title && (
114
+ <span class="font-medium text-sm text-default" data-slot="title">
115
+ {props.title}
116
+ </span>
117
+ )}
118
+ {props.subtitle && (
119
+ <span class="text-xs text-muted" data-slot="subtitle">
120
+ {props.subtitle}
121
+ </span>
122
+ )}
123
+ </div>
124
+ </div>
125
+ )
126
+ }
127
+
128
+ return (
129
+ <span
130
+ class={resolvedClasses().root}
131
+ data-slot="root"
132
+ aria-label={props.label}
133
+ role={props.label ? "img" : undefined}
134
+ {...rest}
135
+ >
136
+ {props.children ? props.children : image()}
137
+ {badgeEl()}
138
+ </span>
139
+ )
140
+ }
141
+
142
+ export default RLSAvatar
@@ -8,24 +8,24 @@ export interface AvatarProps {
8
8
  * @default "span"
9
9
  */
10
10
  as?: any
11
- src?: string
12
- alt?: string
11
+ src?: string | undefined
12
+ alt?: string | undefined
13
13
  icon?: any
14
- text?: string
15
- fallback?: string
14
+ text?: string | undefined
15
+ fallback?: string | undefined
16
16
  /**
17
17
  * @default "md"
18
18
  */
19
- size?: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl"
19
+ size?: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | undefined
20
20
  /**
21
21
  * @default "neutral"
22
22
  */
23
- color?: ThemeColor
24
- chip?: boolean | ChipProps
25
- badge?: boolean | string | number
26
- badgeColor?: string
27
- badgePosition?: "top-right" | "bottom-right" | "top-left" | "bottom-left"
28
- loading?: "lazy" | "eager"
23
+ color?: ThemeColor | undefined
24
+ chip?: boolean | ChipProps | undefined
25
+ badge?: boolean | string | number | undefined
26
+ badgeColor?: string | undefined
27
+ badgePosition?: "top-right" | "bottom-right" | "top-left" | "bottom-left" | undefined
28
+ loading?: "lazy" | "eager" | undefined
29
29
  referrerpolicy?:
30
30
  | ""
31
31
  | "no-referrer"
@@ -36,25 +36,26 @@ export interface AvatarProps {
36
36
  | "strict-origin"
37
37
  | "strict-origin-when-cross-origin"
38
38
  | "unsafe-url"
39
- crossorigin?: "" | "anonymous" | "use-credentials"
40
- decoding?: "async" | "auto" | "sync"
41
- height?: string | number
42
- width?: string | number
43
- sizes?: string
44
- srcset?: string
45
- usemap?: string
39
+ | undefined
40
+ crossorigin?: "" | "anonymous" | "use-credentials" | undefined
41
+ decoding?: "async" | "auto" | "sync" | undefined
42
+ height?: string | number | undefined
43
+ width?: string | number | undefined
44
+ sizes?: string | undefined
45
+ srcset?: string | undefined
46
+ usemap?: string | undefined
46
47
  /**
47
48
  * Compact initials displayed inside the avatar circle (alias for fallback)
48
49
  */
49
- initials?: string
50
+ initials?: string | undefined
50
51
  /**
51
52
  * Display name rendered adjacent to the avatar (e.g. "Daniel Marchi")
52
53
  */
53
- title?: string
54
+ title?: string | undefined
54
55
  /**
55
56
  * Secondary description rendered below the title (e.g. "Lead Developer")
56
57
  */
57
- subtitle?: string
58
+ subtitle?: string | undefined
58
59
  /**
59
60
  * Accessible aria-label fallback for screen readers when avatar is purely visual
60
61
  */
@@ -0,0 +1,163 @@
1
+ import { createMemo, splitProps, For, type Component, type JSX } from "solid-js"
2
+ import type { AvatarGroupProps } from "./avatar-group"
3
+ import { avatarGroupTheme } from "./avatar-group.theme"
4
+ import RLSAvatar from "../avatar/RLSAvatar"
5
+
6
+ export interface RLSAvatarGroupProps extends AvatarGroupProps {
7
+ children?: JSX.Element
8
+ }
9
+
10
+ const sizePx: Record<string, number> = {
11
+ "3xs": 16,
12
+ "2xs": 20,
13
+ "xs": 24,
14
+ "sm": 28,
15
+ "md": 32,
16
+ "lg": 36,
17
+ "xl": 40,
18
+ "2xl": 44,
19
+ "3xl": 48
20
+ }
21
+
22
+ const sizeCls: Record<string, string> = {
23
+ "3xs": "size-4 text-[7px]",
24
+ "2xs": "size-5 text-[8px]",
25
+ "xs": "size-6 text-[9px]",
26
+ "sm": "size-7 text-[10px]",
27
+ "md": "size-8 text-[11px]",
28
+ "lg": "size-9 text-xs",
29
+ "xl": "size-10 text-xs",
30
+ "2xl": "size-11 text-sm",
31
+ "3xl": "size-12 text-sm"
32
+ }
33
+
34
+ const RLSAvatarGroup: Component<RLSAvatarGroupProps> = (allProps) => {
35
+ const [props, rest] = splitProps(allProps, [
36
+ "items",
37
+ "displayLimit",
38
+ "size",
39
+ "ui",
40
+ "class",
41
+ "children"
42
+ ])
43
+
44
+ const normalizedItems = props.items ?? []
45
+ const displayLimit = props.displayLimit ?? 5
46
+ const size = props.size ?? "md"
47
+
48
+ const resolvedClasses = createMemo(() => avatarGroupTheme({ ui: props.ui, class: props.class }))
49
+
50
+ const uid = Math.random().toString(36).substring(2, 9)
51
+ const cName = `rla-ag-${uid}`
52
+
53
+ const avatarPx = sizePx[size] ?? 32
54
+ const overlapPx = 12
55
+ const effectivePx = avatarPx - overlapPx
56
+ const morePx = avatarPx + 4
57
+
58
+ const renderedItems = normalizedItems.slice(0, displayLimit)
59
+ const baseHiddenCount = Math.max(0, normalizedItems.length - displayLimit)
60
+ const needsOverflow = normalizedItems.length >= displayLimit
61
+
62
+ let instanceCss = ""
63
+ if (needsOverflow && renderedItems.length > 1) {
64
+ const maxBreaks = renderedItems.length - 1
65
+ for (let i = 0; i < maxBreaks; i++) {
66
+ const hiddenItems = i + 1
67
+ const visibleCount = renderedItems.length - hiddenItems
68
+ const maxWidth = avatarPx + Math.max(0, visibleCount - 1) * effectivePx + morePx + 4
69
+ const hideNthChild = renderedItems.length - i
70
+
71
+ instanceCss += `\n@container ${cName} (max-width: ${maxWidth}px) {`
72
+ instanceCss += `\n [data-ag="${uid}"] { --hidden-items: ${hiddenItems}; }`
73
+ instanceCss += `\n [data-ag="${uid}"] > .rla-ag-item.hidable:nth-child(${hideNthChild}) { display: none; }`
74
+ if (baseHiddenCount === 0) {
75
+ instanceCss += `\n [data-ag="${uid}"] > .rla-ag-more-hidden { display: inline-flex; }`
76
+ }
77
+ instanceCss += `\n}`
78
+ }
79
+ }
80
+
81
+ if (normalizedItems.length > 0) {
82
+ return (
83
+ <>
84
+ <div
85
+ class="rla-ag-host"
86
+ style={`container-type: inline-size; container-name: ${cName};`}
87
+ {...rest}
88
+ >
89
+ <div
90
+ class={`${resolvedClasses().root} rla-ag-list`}
91
+ data-slot="avatar-group"
92
+ data-ag={uid}
93
+ style={`--base-hidden: ${baseHiddenCount}; --hidden-items: 0;`}
94
+ >
95
+ <For each={renderedItems}>
96
+ {(item, idx) => (
97
+ <span class={needsOverflow && idx() > 0 ? "rla-ag-item hidable" : "rla-ag-item"}>
98
+ <RLSAvatar
99
+ src={item.src}
100
+ alt={item.alt ?? ""}
101
+ fallback={item.fallback}
102
+ initials={item.initials}
103
+ size={size}
104
+ color={(item.color ?? "neutral") as any}
105
+ />
106
+ </span>
107
+ )}
108
+ </For>
109
+
110
+ {needsOverflow && (
111
+ <span
112
+ class={`${resolvedClasses().more} ${sizeCls[size] ?? sizeCls["md"]} rla-ag-more${baseHiddenCount === 0 ? " rla-ag-more-hidden" : ""}`}
113
+ aria-hidden="true"
114
+ data-slot="more"
115
+ >
116
+ +<span class="rla-ag-count" />
117
+ </span>
118
+ )}
119
+ </div>
120
+ </div>
121
+
122
+ <style>{instanceCss}</style>
123
+
124
+ <style>{`
125
+ .rla-ag-host {
126
+ display: inline-block;
127
+ }
128
+
129
+ .rla-ag-item {
130
+ display: inline-flex;
131
+ flex-shrink: 0;
132
+ }
133
+
134
+ .rla-ag-more {
135
+ display: inline-flex;
136
+ align-items: center;
137
+ justify-content: center;
138
+ flex-shrink: 0;
139
+ white-space: nowrap;
140
+ font-feature-settings: "tnum";
141
+ }
142
+
143
+ .rla-ag-more-hidden {
144
+ display: none;
145
+ }
146
+
147
+ .rla-ag-count::after {
148
+ counter-reset: rla-ag-cnt calc(var(--base-hidden, 0) + var(--hidden-items, 0));
149
+ content: counter(rla-ag-cnt);
150
+ }
151
+ `}</style>
152
+ </>
153
+ )
154
+ }
155
+
156
+ return (
157
+ <div class={resolvedClasses().root} data-slot="avatar-group" {...rest}>
158
+ {props.children}
159
+ </div>
160
+ )
161
+ }
162
+
163
+ export default RLSAvatarGroup
@@ -32,7 +32,7 @@ const RLSBadge: Component<RLSBadgeProps> = (allProps) => {
32
32
  )
33
33
 
34
34
  return (
35
- <span class={resolvedClasses().root} data-slot="root" {...rest}>
35
+ <span class={resolvedClasses().root} data-slot="root" data-theme={props.theme} {...rest}>
36
36
  {props.children !== undefined && props.children !== null ? props.children : props.label}
37
37
  </span>
38
38
  )
@@ -11,7 +11,7 @@ const props = withDefaults(defineProps<BadgeProps>(), {
11
11
  variant: "solid",
12
12
  color: "primary",
13
13
  size: "md",
14
- shape: "rounded"
14
+ shape: "pill"
15
15
  })
16
16
 
17
17
  const resolvedClasses = computed(() =>
@@ -20,13 +20,15 @@ const resolvedClasses = computed(() =>
20
20
  color: props.color,
21
21
  size: props.size,
22
22
  shape: props.shape,
23
+ theme: props.theme,
24
+ ui: props.ui,
23
25
  class: props.class
24
26
  })
25
27
  )
26
28
  </script>
27
29
 
28
30
  <template>
29
- <span v-bind="attrs" :class="resolvedClasses.root" data-slot="root">
30
- <slot />
31
+ <span v-bind="attrs" :class="resolvedClasses.root" data-slot="root" :data-theme="theme">
32
+ <slot>{{ label }}</slot>
31
33
  </span>
32
34
  </template>
@@ -21,7 +21,7 @@ const classes = bannerTheme({
21
21
  sticky: fixed ? false : sticky
22
22
  })
23
23
 
24
- const bannerId = (rest.id as string) || `rla-banner-${Math.random().toString(36).slice(2, 8)}`
24
+ const bannerId = (rest["id"] as string) || `rla-banner-${Math.random().toString(36).slice(2, 8)}`
25
25
  const storageKey = dismissId || bannerId
26
26
  ---
27
27
 
@@ -0,0 +1,151 @@
1
+ import { createMemo, createSignal, splitProps, For, Show, type Component, type JSX } from "solid-js"
2
+ import type { BannerAction, BannerProps } from "./banner"
3
+ import { bannerTheme } from "./banner.theme"
4
+ import RLSButton from "../button/RLSButton"
5
+
6
+ export interface RLSBannerProps extends BannerProps {
7
+ children?: JSX.Element
8
+ left?: JSX.Element
9
+ center?: JSX.Element
10
+ right?: JSX.Element
11
+ actions?: BannerAction[]
12
+ }
13
+
14
+ const RLSBanner: Component<RLSBannerProps> = (allProps) => {
15
+ const [props, rest] = splitProps(allProps, [
16
+ "contain",
17
+ "sticky",
18
+ "fixed",
19
+ "stackIndex",
20
+ "hideOnScroll",
21
+ "dismissable",
22
+ "dismissId",
23
+ "actions",
24
+ "ui",
25
+ "class",
26
+ "children",
27
+ "left",
28
+ "center",
29
+ "right"
30
+ ])
31
+
32
+ const classes = createMemo(() =>
33
+ bannerTheme({
34
+ contain: props.contain ?? true,
35
+ sticky: (props.fixed ?? true) ? false : (props.sticky ?? false),
36
+ fixed: props.fixed ?? true,
37
+ ui: props.ui,
38
+ class: props.class
39
+ })
40
+ )
41
+
42
+ const bannerId = (rest["id"] as string) || `rla-banner-${Math.random().toString(36).slice(2, 8)}`
43
+ const storageKey = props.dismissId || bannerId
44
+ const dismissKey = `rl-banner-dismiss-${storageKey}`
45
+ const actions = props.actions ?? []
46
+
47
+ const readDismissed = () => {
48
+ if (typeof window === "undefined") return false
49
+ try {
50
+ return window.localStorage.getItem(dismissKey) !== null
51
+ } catch {
52
+ return false
53
+ }
54
+ }
55
+
56
+ const [dismissed, setDismissed] = createSignal<boolean>(readDismissed())
57
+
58
+ const handleDismiss = () => {
59
+ try {
60
+ window.localStorage.setItem(dismissKey, "1")
61
+ } catch {}
62
+ setDismissed(true)
63
+ }
64
+
65
+ return (
66
+ <Show when={!dismissed()}>
67
+ <div
68
+ id={bannerId}
69
+ data-slot="root"
70
+ class={classes()["root"]}
71
+ data-contain={(props.contain ?? true) ? "true" : "false"}
72
+ data-rla-banner="true"
73
+ data-stack-index={props.stackIndex ?? 0}
74
+ data-hide-on-scroll={String(props.hideOnScroll ?? true)}
75
+ data-header-layer-id={bannerId}
76
+ data-layer-type="banner"
77
+ data-dismiss-key={dismissKey}
78
+ {...rest}
79
+ >
80
+ <div class={classes()["content"]} data-header-content>
81
+ <div class={classes()["container"]} data-slot="container">
82
+ <Show when={actions.length > 0}>
83
+ <input type="checkbox" id={`${bannerId}-act`} class="peer sr-only shrink-0" />
84
+ </Show>
85
+
86
+ <div class={`${classes()["left"]} peer-checked:hidden`} data-slot="left">
87
+ {props.left}
88
+ </div>
89
+ <div class={`${classes()["center"]} peer-checked:hidden`} data-slot="center">
90
+ {props.center !== undefined
91
+ ? props.center
92
+ : props.children !== undefined
93
+ ? props.children
94
+ : null}
95
+ </div>
96
+
97
+ <div class="flex-1"></div>
98
+
99
+ <div class={classes()["side"]}>{props.right}</div>
100
+
101
+ <Show when={actions.length > 0}>
102
+ <label
103
+ for={`${bannerId}-act`}
104
+ class="flex-none flex items-center justify-center size-7 rounded-md hover:bg-black/10 dark:hover:bg-white/10 cursor-pointer md:hidden text-sm leading-none peer-checked:order-first"
105
+ aria-label="Show actions"
106
+ >
107
+ ···
108
+ </label>
109
+
110
+ <div
111
+ class={`${classes()["actions"]} hidden peer-checked:flex md:flex flex-row items-center justify-center gap-2 peer-checked:order-first`}
112
+ >
113
+ <For each={actions}>
114
+ {(action) => (
115
+ <a
116
+ href={action.href || "#"}
117
+ class={`inline-flex items-center justify-center gap-1 px-3 py-1 rounded-md text-xs font-semibold transition-colors no-underline cursor-pointer shrink-0 ${
118
+ action.variant === "solid" || !action.variant
119
+ ? "bg-neutral-950 text-neutral-50 hover:opacity-90"
120
+ : "bg-white/20 text-white hover:bg-white/30"
121
+ } ${action.class ?? ""}`}
122
+ data-banner-action
123
+ >
124
+ {action.label}
125
+ </a>
126
+ )}
127
+ </For>
128
+ </div>
129
+ </Show>
130
+
131
+ <Show when={props.dismissable}>
132
+ <RLSButton
133
+ type="button"
134
+ variant="ghost"
135
+ color="neutral"
136
+ square
137
+ leadingIcon="close"
138
+ ariaLabel="Close banner"
139
+ class={classes()["dismiss"]}
140
+ data-banner-close
141
+ onClick={handleDismiss}
142
+ />
143
+ </Show>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </Show>
148
+ )
149
+ }
150
+
151
+ export default RLSBanner