@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
@@ -13,7 +13,11 @@ export const tableTheme = defineTheme("table", {
13
13
  "td",
14
14
  "separator",
15
15
  "empty",
16
- "loading"
16
+ "loading",
17
+ "trGroup",
18
+ "tdGroup",
19
+ "trExpanded",
20
+ "tdExpanded"
17
21
  ],
18
22
  base: {
19
23
  root: "relative w-full overflow-auto rounded-lg border border-default shadow-sm outline-primary/25 focus-visible:outline-3",
@@ -22,38 +26,42 @@ export const tableTheme = defineTheme("table", {
22
26
  thead:
23
27
  "relative bg-muted/50 border-b border-default text-xs uppercase font-semibold text-muted",
24
28
  tbody:
25
- "isolate divide-y divide-border/60 [&>tr]:data-[selectable=true]:hover:bg-muted/30 [&>tr]:data-[selectable=true]:cursor-pointer",
29
+ "divide-y divide-default/60 [&>tr]:data-[selectable=true]:hover:bg-muted/30 [&>tr]:data-[selectable=true]:cursor-pointer",
26
30
  tfoot: "relative bg-muted/30 border-t border-default font-medium text-xs text-muted",
27
- tr: "transition-colors data-[selected=true]:bg-primary/10 data-[expanded=true]:bg-muted/40 hover:bg-muted/30",
31
+ tr: "transition-colors data-[selected=true]:bg-primary/10 data-[expanded=true]:bg-muted/40",
28
32
  th: "px-4 py-3.5 text-xs font-semibold text-muted text-left uppercase tracking-wider [&:has([role=checkbox])]:pe-0",
29
33
  td: "p-4 text-sm text-highlighted align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0",
30
34
  separator: "absolute z-10 start-0 w-full h-px bg-neutral-200",
31
35
  empty: "py-8 text-center text-sm text-muted",
32
- loading: "py-8 text-center text-sm text-muted"
36
+ loading: "py-8 text-center text-sm text-muted",
37
+ trGroup: "bg-muted/40",
38
+ tdGroup: "px-4 py-2 text-xs font-bold uppercase tracking-wider text-highlighted",
39
+ trExpanded: "bg-muted/20 border-b border-default",
40
+ tdExpanded: "p-4"
33
41
  },
34
42
  variants: {
35
43
  pinned: {
36
44
  true: {
37
- th: "sticky bg-default/95 backdrop-blur z-10",
38
- td: "sticky bg-default/95 backdrop-blur z-10"
45
+ th: "sticky bg-default z-10",
46
+ td: "sticky bg-default z-10"
39
47
  }
40
48
  },
41
49
  sticky: {
42
50
  true: {
43
- thead: "sticky top-0 inset-x-0 bg-default/95 backdrop-blur z-10",
44
- tfoot: "sticky bottom-0 inset-x-0 bg-default/95 backdrop-blur z-10"
51
+ thead: "sticky top-0 inset-x-0 bg-default z-10",
52
+ tfoot: "sticky bottom-0 inset-x-0 bg-default z-10"
45
53
  },
46
54
  header: {
47
- thead: "sticky top-0 inset-x-0 bg-default/95 backdrop-blur z-10"
55
+ thead: "sticky top-0 inset-x-0 bg-default z-10"
48
56
  },
49
57
  footer: {
50
- tfoot: "sticky bottom-0 inset-x-0 bg-default/95 backdrop-blur z-10"
58
+ tfoot: "sticky bottom-0 inset-x-0 bg-default z-10"
51
59
  }
52
60
  },
53
61
  loading: {
54
62
  true: {
55
63
  thead:
56
- "after:absolute after:bottom-0 after:start-0 after:z-10 after:h-0.5 after:w-full motion-reduce:after:animate-pulse"
64
+ "after:absolute after:bottom-0 after:start-0 after:z-10 after:h-0.5 after:w-full motion-reduce:after:w-full motion-reduce:after:animate-pulse"
57
65
  }
58
66
  },
59
67
  externalScroll: {
@@ -63,7 +71,13 @@ export const tableTheme = defineTheme("table", {
63
71
  },
64
72
  striped: {
65
73
  true: {
66
- tr: "odd:bg-default even:bg-muted/20 hover:bg-muted/35"
74
+ tbody:
75
+ "[&>tr:not([data-slot=tr-group]):not([data-slot=tr-expanded])]:odd:bg-default [&>tr:not([data-slot=tr-group]):not([data-slot=tr-expanded])]:even:bg-muted/20"
76
+ }
77
+ },
78
+ hoverable: {
79
+ true: {
80
+ tr: "hover:bg-muted/30 cursor-pointer"
67
81
  }
68
82
  },
69
83
  bordered: {
@@ -91,21 +105,38 @@ export const tableTheme = defineTheme("table", {
91
105
  }
92
106
  },
93
107
  compoundVariants: [
108
+ // Loading color variants
94
109
  { loading: true, loadingColor: "primary", classNames: { thead: "after:bg-primary" } },
95
110
  { loading: true, loadingColor: "secondary", classNames: { thead: "after:bg-secondary" } },
96
111
  { loading: true, loadingColor: "success", classNames: { thead: "after:bg-success" } },
97
112
  { loading: true, loadingColor: "info", classNames: { thead: "after:bg-info" } },
98
113
  { loading: true, loadingColor: "warning", classNames: { thead: "after:bg-warning" } },
99
114
  { loading: true, loadingColor: "error", classNames: { thead: "after:bg-destructive" } },
115
+ { loading: true, loadingColor: "neutral", classNames: { thead: "after:bg-muted" } },
116
+ // Loading animation variants
117
+ // carousel: left-to-right sweep (keyframe: @keyframes carousel { 0%{transform:translateX(-100%)} 100%{transform:translateX(400%)} })
100
118
  {
101
119
  loading: true,
102
- loadingColor: "neutral",
103
- classNames: { thead: "after:bg-muted" }
120
+ loadingAnimation: "carousel",
121
+ classNames: { thead: "motion-safe:after:animate-[carousel_2s_linear_infinite]" }
104
122
  },
123
+ // carousel-inverse: right-to-left sweep
105
124
  {
106
125
  loading: true,
107
- loadingAnimation: "carousel",
108
- classNames: { thead: "motion-safe:after:animate-pulse" }
126
+ loadingAnimation: "carousel-inverse",
127
+ classNames: { thead: "motion-safe:after:animate-[carousel-inverse_2s_linear_infinite]" }
128
+ },
129
+ // swing: pendulum back-and-forth
130
+ {
131
+ loading: true,
132
+ loadingAnimation: "swing",
133
+ classNames: { thead: "motion-safe:after:animate-[swing_2s_ease-in-out_infinite]" }
134
+ },
135
+ // elastic: springy bounce
136
+ {
137
+ loading: true,
138
+ loadingAnimation: "elastic",
139
+ classNames: { thead: "motion-safe:after:animate-[elastic_2s_ease-in-out_infinite]" }
109
140
  }
110
141
  ],
111
142
  defaultVariants: {
@@ -1,17 +1,17 @@
1
1
  export interface TableColumnMeta {
2
2
  class?: {
3
- td?: string | ((cell: any) => string)
4
- th?: string | ((column: any) => string)
3
+ td?: string | ((row: TableRow) => string)
4
+ th?: string | ((column: TableColumn) => string)
5
5
  }
6
6
  style?: {
7
- td?: string | ((cell: any) => string)
8
- th?: string | ((column: any) => string)
7
+ td?: string | ((row: TableRow) => string)
8
+ th?: string | ((column: TableColumn) => string)
9
9
  }
10
10
  colspan?: {
11
- td?: number | string | ((cell: any) => number | string)
11
+ td?: number | string | ((row: TableRow) => number | string)
12
12
  }
13
13
  rowspan?: {
14
- td?: number | string | ((cell: any) => number | string)
14
+ td?: number | string | ((row: TableRow) => number | string)
15
15
  }
16
16
  [key: string]: any
17
17
  }
@@ -20,21 +20,18 @@ export interface TableColumn<T = any> {
20
20
  id?: string
21
21
  accessorKey?: keyof T | string
22
22
  header?: string | ((props: { column: TableColumn<T>; table: any }) => any)
23
- cell?:
24
- | string
25
- | ((props: {
26
- row: TableRow<T>
27
- getValue: () => any
28
- renderValue: () => any
29
- column: TableColumn<T>
30
- table: any
31
- }) => any)
23
+ cell?: (props: {
24
+ row: TableRow<T>
25
+ getValue: () => any
26
+ renderValue: () => any
27
+ column: TableColumn<T>
28
+ table: any
29
+ }) => any
32
30
  footer?: string | ((props: { column: TableColumn<T>; table: any }) => any)
33
31
  meta?: TableColumnMeta
34
32
  enableSorting?: boolean
35
33
  enableHiding?: boolean
36
34
  size?: number | string
37
- aggregationFn?: string | ((rows: any[], id: string) => any)
38
35
  [key: string]: any
39
36
  }
40
37
 
@@ -48,6 +45,8 @@ export interface TableRow<T = any> {
48
45
  toggleSelected: (value?: boolean) => void
49
46
  getIsExpanded: () => boolean
50
47
  toggleExpanded: (value?: boolean) => void
48
+ getToggleExpandedHandler?: () => (e?: Event) => void
49
+ getToggleSelectedHandler?: () => (e?: Event) => void
51
50
  getIsPinned: () => boolean | "top" | "bottom"
52
51
  pin: (position: boolean | "top" | "bottom") => void
53
52
  getIsGrouped: () => boolean
@@ -56,6 +55,13 @@ export interface TableRow<T = any> {
56
55
  [key: string]: any
57
56
  }
58
57
 
58
+ export interface TableGroup<T = any> {
59
+ id: string
60
+ columnId: string
61
+ value: any
62
+ rows: TableRow<T>[]
63
+ }
64
+
59
65
  export interface TableMeta<T = any> {
60
66
  class?: {
61
67
  tr?: string | ((row: TableRow<T>) => string)
@@ -71,11 +77,15 @@ export interface TableSortingItem {
71
77
  desc: boolean
72
78
  }
73
79
 
80
+ export type SortingState = TableSortingItem[]
81
+
74
82
  export interface TableColumnFilter {
75
83
  id: string
76
84
  value: any
77
85
  }
78
86
 
87
+ export type ColumnFiltersState = TableColumnFilter[]
88
+
79
89
  export interface TableRowPinningState {
80
90
  top?: string[]
81
91
  bottom?: string[]
@@ -91,145 +101,173 @@ export interface TablePaginationState {
91
101
  pageSize: number
92
102
  }
93
103
 
104
+ /**
105
+ * Imperative API exposed by RLATable (on the custom element) and RLSTable (via ref callback).
106
+ */
107
+ export interface TableApi<T = any> {
108
+ tableRef: HTMLTableElement | null
109
+ getFilteredRows(): TableRow<T>[]
110
+ getSortedRows(): TableRow<T>[]
111
+ getSelectedRows(): TableRow<T>[]
112
+ getAllColumns(): TableColumn<T>[]
113
+ getColumn(id: string): TableColumn<T> | undefined
114
+ setGlobalFilter(value: string): void
115
+ setColumnFilter(id: string, value: any): void
116
+ setColumnVisibility(id: string, visible: boolean): void
117
+ setColumnPinning(pinning: TableColumnPinningState): void
118
+ setRowPinning(pinning: TableRowPinningState): void
119
+ setSorting(state: SortingState): void
120
+ setPagination(state: TablePaginationState): void
121
+ getState(): {
122
+ sorting: SortingState
123
+ globalFilter: string
124
+ columnFilters: ColumnFiltersState
125
+ columnVisibility: Record<string, boolean>
126
+ columnPinning: TableColumnPinningState
127
+ rowSelection: Record<string, boolean>
128
+ expanded: Record<string, boolean>
129
+ rowPinning: TableRowPinningState
130
+ pagination: TablePaginationState
131
+ }
132
+ }
133
+
94
134
  export interface TableProps<T = any> {
95
135
  /**
96
- * Data rows array.
136
+ * Data rows. Auto-infers columns from the first row's keys when `columns` is omitted.
97
137
  */
98
138
  data?: T[]
99
139
  /**
100
- * Columns definition array.
140
+ * Column definitions.
101
141
  */
102
142
  columns?: TableColumn<T>[]
103
143
  /**
104
- * Column headers array (legacy/backwards-compatible mode).
105
- */
106
- headers?: Array<string | { label: string; key: string; class?: string }>
107
- /**
108
- * Data rows array (legacy/backwards-compatible mode).
109
- */
110
- rows?: Array<Record<string, any> | any[]>
111
- /**
112
- * Accessible description or title of the table.
144
+ * Accessible table caption (visually hidden).
113
145
  */
114
146
  caption?: string
115
147
  /**
116
- * Table meta properties (e.g., dynamic row classes).
148
+ * Table-level metadata, e.g. a per-row `class.tr` function.
117
149
  */
118
150
  meta?: TableMeta<T>
119
151
  /**
120
- * Sticky header or footer ('header', 'footer', or true for both).
152
+ * Stick the header, footer, or both when the table scrolls.
121
153
  */
122
154
  sticky?: boolean | "header" | "footer"
123
155
  /**
124
- * Loading state.
156
+ * Show a loading progress bar.
125
157
  */
126
158
  loading?: boolean
127
159
  /**
128
- * Loading color variant.
160
+ * Color of the loading bar. @default 'primary'
129
161
  */
130
162
  loadingColor?: "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral"
131
163
  /**
132
- * Loading animation variant.
164
+ * Animation of the loading bar. @default 'carousel'
133
165
  */
134
166
  loadingAnimation?: "carousel" | "carousel-inverse" | "swing" | "elastic"
135
167
  /**
136
- * Empty state text message.
168
+ * Empty-state text. @default 'No data available'
137
169
  */
138
170
  empty?: string
139
171
  /**
140
- * Virtualization state or options object.
141
- */
142
- virtualize?: boolean | Record<string, any>
143
- /**
144
- * Striped row style.
172
+ * Alternate row background colors.
145
173
  */
146
174
  striped?: boolean
147
175
  /**
148
- * Hoverable rows state.
176
+ * Show borders on every cell.
149
177
  */
150
- hoverable?: boolean
178
+ bordered?: boolean
151
179
  /**
152
- * Bordered cells.
180
+ * Highlight row on hover.
153
181
  */
154
- bordered?: boolean
182
+ hoverable?: boolean
155
183
  /**
156
- * Global search filter text.
184
+ * Global text filter across all columns.
157
185
  */
158
186
  globalFilter?: string
159
187
  /**
160
- * Per-column filter criteria.
188
+ * Per-column filter state.
161
189
  */
162
- columnFilters?: TableColumnFilter[]
190
+ columnFilters?: ColumnFiltersState
163
191
  /**
164
- * Column visibility toggles (e.g. { id: false }).
192
+ * Column visibility map `{ [columnId]: boolean }`.
165
193
  */
166
194
  columnVisibility?: Record<string, boolean>
167
195
  /**
168
- * Column pinning state ({ left: string[], right: string[] }).
196
+ * Sticky column pinning `{ left?: string[], right?: string[] }`.
169
197
  */
170
198
  columnPinning?: TableColumnPinningState
171
199
  /**
172
- * Active column sorting list.
200
+ * Active sort state.
173
201
  */
174
- sorting?: TableSortingItem[]
202
+ sorting?: SortingState
175
203
  /**
176
- * Grouping column ids list.
204
+ * Column IDs to group rows by (first entry is used).
177
205
  */
178
206
  grouping?: string[]
179
207
  /**
180
- * Row pinning state ({ top: string[], bottom: string[] }).
208
+ * Row pinning `{ top?: string[], bottom?: string[] }`.
181
209
  */
182
210
  rowPinning?: TableRowPinningState
183
211
  /**
184
- * Selected row ids map.
212
+ * Row selection map — `{ [rowId]: boolean }`.
185
213
  */
186
214
  rowSelection?: Record<string, boolean>
187
215
  /**
188
- * Expanded row ids map.
216
+ * Expanded rows map — `{ [rowId]: boolean }`.
189
217
  */
190
218
  expanded?: Record<string, boolean>
191
219
  /**
192
- * Pagination state ({ pageIndex: number, pageSize: number }).
220
+ * Pagination state.
193
221
  */
194
222
  pagination?: TablePaginationState
195
223
  /**
196
- * Function to derive sub-rows for tree/hierarchical data.
224
+ * Extract sub-rows for tree/hierarchical data.
197
225
  */
198
226
  getSubRows?: (row: T, index: number) => T[] | undefined
199
227
  /**
200
- * Custom function to derive unique row ID.
228
+ * Custom row ID extractor. Defaults to `row.id ?? String(index)`.
201
229
  */
202
230
  getRowId?: (row: T, index: number) => string
203
231
  /**
204
- * Row select callback.
232
+ * Called when a data row is clicked (skips clicks on interactive elements).
205
233
  */
206
234
  onSelect?: (e: Event, row: TableRow<T>) => void
207
235
  /**
208
- * Row hover callback.
236
+ * Called when the pointer enters or leaves a row (`null` on leave).
209
237
  */
210
238
  onHover?: (e: Event, row: TableRow<T> | null) => void
211
239
  /**
212
- * Row contextmenu callback.
240
+ * Called on row right-click.
213
241
  */
214
242
  onContextmenu?: (e: Event, row: TableRow<T>) => void
215
- /**
216
- * Enable integrated search toolbar input.
243
+ // Controlled-mode callbacks — provide these to take ownership of state externally
244
+ onSortingChange?: (state: SortingState) => void
245
+ onColumnFiltersChange?: (state: ColumnFiltersState) => void
246
+ onGlobalFilterChange?: (value: string) => void
247
+ onColumnVisibilityChange?: (state: Record<string, boolean>) => void
248
+ onColumnPinningChange?: (state: TableColumnPinningState) => void
249
+ onRowSelectionChange?: (state: Record<string, boolean>) => void
250
+ onExpandedChange?: (state: Record<string, boolean>) => void
251
+ onRowPinningChange?: (state: TableRowPinningState) => void
252
+ onPaginationChange?: (state: TablePaginationState) => void
253
+ /**
254
+ * Render a built-in search input in the toolbar.
217
255
  */
218
256
  searchable?: boolean
219
257
  /**
220
- * Custom placeholder text for integrated search input.
258
+ * Placeholder for the built-in search input. @default 'Filter table...'
221
259
  */
222
260
  searchPlaceholder?: string
223
261
  /**
224
- * Enable integrated column visibility dropdown toggle.
262
+ * Render a column-visibility dropdown in the toolbar.
225
263
  */
226
264
  showColumnsToggle?: boolean
227
265
  /**
228
- * Slot-specific CSS class overrides.
266
+ * Per-slot class overrides.
229
267
  */
230
- ui?: any
268
+ ui?: Partial<Record<string, string>>
231
269
  /**
232
- * Additional CSS classes to apply to root element.
270
+ * Additional classes on the root element.
233
271
  */
234
272
  class?: any
235
273
  [key: string]: unknown
@@ -0,0 +1,196 @@
1
+ import {
2
+ createMemo,
3
+ createSignal,
4
+ For,
5
+ onCleanup,
6
+ onMount,
7
+ splitProps,
8
+ type Component
9
+ } from "solid-js"
10
+ import type { TableOfContentsProps, TableOfContentsHeading } from "./table-of-contents"
11
+ import { tableOfContentsTheme } from "./table-of-contents.theme"
12
+ import RLSIcon from "../icon/RLSIcon"
13
+
14
+ export interface RLSTableOfContentsProps extends TableOfContentsProps {}
15
+
16
+ const RLSTableOfContents: Component<RLSTableOfContentsProps> = (allProps) => {
17
+ const [props, rest] = splitProps(allProps, [
18
+ "headings",
19
+ "collapsible",
20
+ "containerSelector",
21
+ "tableOfContents",
22
+ "as",
23
+ "ui",
24
+ "class"
25
+ ])
26
+
27
+ const [activeId, setActiveId] = createSignal("")
28
+ const [open, setOpen] = createSignal(false)
29
+ let rootRef: HTMLDivElement | undefined
30
+ let detailsRef: HTMLDetailsElement | undefined
31
+
32
+ const collapsible = () => props.collapsible === true
33
+ const containerSelector = () => props.containerSelector ?? ".markdown-content"
34
+
35
+ const minLevel = createMemo(() =>
36
+ props.tableOfContents ? (props.tableOfContents.minHeadingLevel ?? 2) : 2
37
+ )
38
+ const maxLevel = createMemo(() =>
39
+ props.tableOfContents ? (props.tableOfContents.maxHeadingLevel ?? 3) : 3
40
+ )
41
+
42
+ const filteredHeadings = createMemo(() =>
43
+ props.tableOfContents !== false
44
+ ? props.headings.filter((h) => h.depth >= minLevel() && h.depth <= maxLevel())
45
+ : []
46
+ )
47
+
48
+ const headingSelector = createMemo(() =>
49
+ Array.from(
50
+ { length: maxLevel() - minLevel() + 1 },
51
+ (_, i) => `:scope > h${minLevel() + i}`
52
+ ).join(", ")
53
+ )
54
+
55
+ const resolvedClasses = createMemo(() =>
56
+ tableOfContentsTheme({
57
+ ui: props.ui,
58
+ class: props.class
59
+ })
60
+ )
61
+
62
+ onMount(() => {
63
+ if (collapsible() || !rootRef) return
64
+ const update = () => {
65
+ const root = rootRef
66
+ if (!root) return
67
+ const links = root.querySelectorAll(".toc-link")
68
+ if (links.length === 0) return
69
+ const threshold = window.innerHeight * 0.5
70
+ let active: string | undefined
71
+ links.forEach((link) => {
72
+ const href = link.getAttribute("href")
73
+ if (!href || href.charAt(0) !== "#") return
74
+ const id = href.substring(1)
75
+ const heading = document.getElementById(id)
76
+ if (heading && heading.getBoundingClientRect().top <= threshold) {
77
+ active = id
78
+ }
79
+ })
80
+ setActiveId(active ?? "")
81
+ }
82
+ update()
83
+ window.addEventListener("scroll", update, { passive: true })
84
+ onCleanup(() => window.removeEventListener("scroll", update))
85
+ })
86
+
87
+ const depthClass = (depth: number) => {
88
+ if (depth === 2) return "pl-xs"
89
+ if (depth === 3) return "pl-6"
90
+ return "pl-9"
91
+ }
92
+
93
+ if (props.tableOfContents === false || filteredHeadings().length === 0) {
94
+ return null
95
+ }
96
+
97
+ if (collapsible()) {
98
+ return (
99
+ <details
100
+ ref={(el) => (detailsRef = el)}
101
+ class={props.class}
102
+ data-rla-toc-collapsible
103
+ data-container-selector={containerSelector()}
104
+ data-heading-selector={headingSelector()}
105
+ onToggle={(e) => setOpen((e.currentTarget as HTMLDetailsElement).open)}
106
+ {...rest}
107
+ >
108
+ <summary class="flex items-center justify-between gap-3 px-4 h-10 text-sm font-medium text-highlighted cursor-pointer select-none hover:bg-muted/40 transition-colors list-none">
109
+ <span class="flex items-center gap-2">
110
+ <RLSIcon name="i-rl-list" class="size-4 text-primary shrink-0" aria-hidden="true" />
111
+ <span>On this page</span>
112
+ </span>
113
+ <RLSIcon
114
+ name="i-rl-chevronDown"
115
+ class={`rla-toc-chevron size-4 text-muted shrink-0 transition-transform duration-200 ${
116
+ open() ? "rotate-180" : ""
117
+ }`}
118
+ aria-hidden="true"
119
+ />
120
+ </summary>
121
+ <div class="px-4 pt-3 max-h-[40vh] overflow-y-auto border-t border-default/50 bg-default">
122
+ <ul class="flex flex-col gap-0.5 pb-8">
123
+ <For each={filteredHeadings()}>
124
+ {(heading) => (
125
+ <li class={heading.depth === 3 ? "pl-4" : undefined}>
126
+ <a
127
+ href={`#${heading.slug}`}
128
+ class={`toc-link block py-1.5 text-sm transition-colors hover:text-primary no-underline ${
129
+ heading.depth === 2 ? "text-highlighted font-medium" : "text-muted"
130
+ }`}
131
+ data-rla-toc-link
132
+ onClick={() => {
133
+ if (detailsRef) detailsRef.open = false
134
+ setOpen(false)
135
+ }}
136
+ >
137
+ {heading.text}
138
+ </a>
139
+ </li>
140
+ )}
141
+ </For>
142
+ </ul>
143
+ </div>
144
+ </details>
145
+ )
146
+ }
147
+
148
+ return (
149
+ <>
150
+ <style>{`
151
+ .toc-active {
152
+ color: var(--rl-primary-500);
153
+ font-weight: 600;
154
+ }
155
+ `}</style>
156
+ <div
157
+ ref={(el) => (rootRef = el)}
158
+ class={resolvedClasses().root}
159
+ data-slot="root"
160
+ data-container-selector={containerSelector()}
161
+ data-heading-selector={headingSelector()}
162
+ {...rest}
163
+ >
164
+ <div class={resolvedClasses().container} data-slot="container">
165
+ <h4 class={resolvedClasses().title} data-slot="title">
166
+ On this page
167
+ </h4>
168
+ <ul class={`${resolvedClasses().list} mt-2xl flex flex-col gap-xs`} data-slot="list">
169
+ <For each={filteredHeadings()}>
170
+ {(heading: TableOfContentsHeading) => (
171
+ <li
172
+ class={`${resolvedClasses().item} ${depthClass(heading.depth)}`}
173
+ data-slot="item"
174
+ >
175
+ <a
176
+ href={`#${heading.slug}`}
177
+ class={`toc-link ${resolvedClasses().link} ${
178
+ activeId() === heading.slug ? "toc-active" : ""
179
+ }`}
180
+ data-slot="link"
181
+ >
182
+ <span class={resolvedClasses().linkText} data-slot="link-text">
183
+ {heading.text}
184
+ </span>
185
+ </a>
186
+ </li>
187
+ )}
188
+ </For>
189
+ </ul>
190
+ </div>
191
+ </div>
192
+ </>
193
+ )
194
+ }
195
+
196
+ export default RLSTableOfContents