@rimelight/ui 0.0.34 → 0.0.35

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 (185) hide show
  1. package/README.md +1 -0
  2. package/package.json +19 -24
  3. package/src/components/astro/RLAAccordion.astro +94 -18
  4. package/src/components/astro/RLAAvatar.astro +135 -68
  5. package/src/components/astro/RLABadge.astro +4 -2
  6. package/src/components/astro/RLABanner.astro +138 -23
  7. package/src/components/astro/RLABreadcrumb.astro +13 -0
  8. package/src/components/astro/RLAButton.astro +8 -4
  9. package/src/components/astro/RLACallout.astro +112 -0
  10. package/src/components/astro/RLACard.astro +6 -5
  11. package/src/components/astro/RLACarousel.astro +104 -75
  12. package/src/components/astro/RLAChart.astro +4 -1
  13. package/src/components/astro/RLAChip.astro +11 -5
  14. package/src/components/astro/RLACollapsible.astro +4 -1
  15. package/src/components/astro/RLAColorArea.astro +432 -0
  16. package/src/components/astro/RLAColorField.astro +300 -0
  17. package/src/components/astro/RLAColorSlider.astro +413 -0
  18. package/src/components/astro/RLAConfirm.astro +13 -11
  19. package/src/components/astro/RLACopyMarkdown.astro +78 -0
  20. package/src/components/astro/RLADate.astro +30 -0
  21. package/src/components/astro/RLADrawer.astro +50 -3
  22. package/src/components/astro/RLADropdownMenu.astro +78 -51
  23. package/src/components/astro/RLAFieldGroup.astro +4 -1
  24. package/src/components/astro/RLAFileUpload.astro +114 -100
  25. package/src/components/astro/RLAFooter.astro +2 -1
  26. package/src/components/astro/RLAFormField.astro +10 -6
  27. package/src/components/astro/RLAGrid.astro +31 -39
  28. package/src/components/astro/RLAHead.astro +139 -39
  29. package/src/components/astro/RLAHeader.astro +2 -1
  30. package/src/components/astro/RLAImage.astro +274 -251
  31. package/src/components/astro/RLAInput.astro +14 -9
  32. package/src/components/astro/RLAInputMenu.astro +119 -83
  33. package/src/components/astro/RLAKbd.astro +5 -5
  34. package/src/components/astro/RLALayoutGrid.astro +395 -0
  35. package/src/components/astro/RLALink.astro +23 -1
  36. package/src/components/astro/RLALinkGroup.astro +99 -99
  37. package/src/components/astro/RLALocaleSelector.astro +29 -35
  38. package/src/components/astro/RLALogo.astro +117 -90
  39. package/src/components/astro/RLAModal.astro +48 -18
  40. package/src/components/astro/RLANavigationMenu.astro +381 -326
  41. package/src/components/astro/{RLADocsPackageManagers.astro → RLAPackageManagers.astro} +81 -87
  42. package/src/components/astro/RLAPageSection.astro +4 -2
  43. package/src/components/astro/RLAPopover.astro +4 -3
  44. package/src/components/astro/RLAPost.astro +11 -2
  45. package/src/components/astro/RLAScrollArea.astro +4 -1
  46. package/src/components/astro/RLAScrollToTop.astro +200 -172
  47. package/src/components/astro/RLASearch.astro +282 -0
  48. package/src/components/astro/RLASelect.astro +78 -55
  49. package/src/components/astro/RLASeparator.astro +11 -6
  50. package/src/components/astro/RLAShare.astro +60 -0
  51. package/src/components/astro/RLAShortcuts.astro +429 -0
  52. package/src/components/astro/RLASidebar.astro +158 -212
  53. package/src/components/astro/RLASlideover.astro +47 -17
  54. package/src/components/astro/RLASplitter.astro +194 -141
  55. package/src/components/astro/RLASteps.astro +118 -71
  56. package/src/components/astro/RLASurround.astro +39 -0
  57. package/src/components/astro/RLATable.astro +4 -1
  58. package/src/components/astro/RLATableOfContents.astro +109 -23
  59. package/src/components/astro/RLATabs.astro +147 -133
  60. package/src/components/astro/RLATextarea.astro +4 -1
  61. package/src/components/astro/RLAThemeSelector.astro +105 -76
  62. package/src/components/astro/RLAToast.astro +35 -21
  63. package/src/components/vue/RLVBanner.vue +230 -0
  64. package/src/components/vue/RLVButton.vue +3 -2
  65. package/src/components/vue/RLVCheckbox.vue +4 -2
  66. package/src/components/vue/RLVFooter.vue +3 -2
  67. package/src/components/vue/RLVHeader.vue +3 -2
  68. package/src/components/vue/RLVIcon.vue +4 -2
  69. package/src/components/vue/RLVInput.vue +5 -4
  70. package/src/components/vue/RLVLogo.vue +25 -3
  71. package/src/components/vue/RLVPlaceholder.vue +3 -2
  72. package/src/components/vue/RLVPost.vue +8 -2
  73. package/src/components/vue/RLVProgress.vue +60 -0
  74. package/src/components/vue/RLVScrollToTop.vue +65 -52
  75. package/src/components/vue/RLVSection.vue +14 -13
  76. package/src/components/vue/RLVToast.vue +17 -4
  77. package/src/composables/index.ts +1 -0
  78. package/src/composables/useHeaderStore.ts +1 -0
  79. package/src/composables/useShortcuts.ts +11 -0
  80. package/src/config/security.ts +43 -36
  81. package/src/config/site.config.ts +1 -0
  82. package/src/docs/components/ApiChangelog.astro +147 -0
  83. package/src/{plugins/starlightDocsApi → docs}/components/ApiEmits.astro +4 -4
  84. package/src/{plugins/starlightDocsApi → docs}/components/ApiProps.astro +4 -4
  85. package/src/{plugins/starlightDocsApi → docs}/components/ApiSlots.astro +4 -4
  86. package/src/docs/components/ApiTheme.astro +100 -0
  87. package/src/docs/extractAll.ts +94 -0
  88. package/src/docs/extractors/extractAstro.ts +69 -0
  89. package/src/docs/extractors/extractTheme.ts +56 -0
  90. package/src/{plugins/starlightDocsApi/extract-vue.ts → docs/extractors/extractVue.ts} +164 -15
  91. package/src/{plugins/starlightDocsApi → docs}/utils.ts +1 -2
  92. package/src/env.d.ts +0 -12
  93. package/src/integrations/ui.ts +35 -19
  94. package/src/middleware/security.ts +75 -19
  95. package/src/presets/index.ts +118 -293
  96. package/src/styles/index.css +0 -2
  97. package/src/themes/accordion.theme.ts +29 -3
  98. package/src/themes/aspect-ratio.theme.ts +1 -1
  99. package/src/themes/avatar-group.theme.ts +1 -1
  100. package/src/themes/avatar.theme.ts +2 -2
  101. package/src/themes/badge.theme.ts +2 -3
  102. package/src/themes/banner.theme.ts +40 -4
  103. package/src/themes/breadcrumb.theme.ts +1 -1
  104. package/src/themes/button.theme.ts +21 -22
  105. package/src/themes/{alert.theme.ts → callout.theme.ts} +12 -39
  106. package/src/themes/card.theme.ts +17 -9
  107. package/src/themes/carousel.theme.ts +1 -1
  108. package/src/themes/checkbox.theme.ts +1 -2
  109. package/src/themes/chip.theme.ts +2 -3
  110. package/src/themes/color-area.theme.ts +33 -0
  111. package/src/themes/color-field.theme.ts +32 -0
  112. package/src/themes/color-slider.theme.ts +34 -0
  113. package/src/themes/confirm.theme.ts +1 -1
  114. package/src/themes/container.theme.ts +1 -1
  115. package/src/themes/drawer.theme.ts +1 -1
  116. package/src/themes/footer.theme.ts +2 -2
  117. package/src/themes/grid.theme.ts +38 -0
  118. package/src/themes/header.theme.ts +4 -3
  119. package/src/themes/hover-card.theme.ts +1 -1
  120. package/src/themes/image.theme.ts +11 -1
  121. package/src/themes/input.theme.ts +7 -1
  122. package/src/themes/kbd.theme.ts +2 -3
  123. package/src/themes/label.theme.ts +1 -1
  124. package/src/themes/layout-grid.theme.ts +16 -0
  125. package/src/themes/link-group.theme.ts +0 -4
  126. package/src/themes/marquee.theme.ts +1 -1
  127. package/src/themes/modal.theme.ts +1 -1
  128. package/src/themes/navigation-menu.theme.ts +2 -2
  129. package/src/themes/page-section.theme.ts +4 -2
  130. package/src/themes/pagination.theme.ts +1 -1
  131. package/src/themes/pin-input.theme.ts +1 -1
  132. package/src/themes/popover.theme.ts +1 -1
  133. package/src/themes/post.theme.ts +23 -3
  134. package/src/themes/progress.theme.ts +1 -2
  135. package/src/themes/scroll-to-top.theme.ts +2 -3
  136. package/src/themes/search.theme.ts +64 -0
  137. package/src/themes/separator.theme.ts +1 -1
  138. package/src/themes/slideover.theme.ts +1 -1
  139. package/src/themes/slider.theme.ts +1 -2
  140. package/src/themes/spinner.theme.ts +1 -2
  141. package/src/themes/{megamenu.theme.ts → steps.theme.ts} +3 -3
  142. package/src/themes/sticky-surface.theme.ts +1 -1
  143. package/src/themes/switch.theme.ts +1 -2
  144. package/src/themes/table-of-contents.theme.ts +21 -2
  145. package/src/themes/timeline.theme.ts +7 -2
  146. package/src/themes/toast.theme.ts +1 -1
  147. package/src/types/components/accordion.ts +35 -2
  148. package/src/types/components/avatar.ts +16 -0
  149. package/src/types/components/banner.ts +42 -0
  150. package/src/types/components/button.ts +3 -4
  151. package/src/types/components/{alert.ts → callout.ts} +6 -6
  152. package/src/types/components/color-area.ts +19 -0
  153. package/src/types/components/color-field.ts +21 -0
  154. package/src/types/components/color-slider.ts +20 -0
  155. package/src/types/components/grid.ts +23 -0
  156. package/src/types/components/input.ts +4 -0
  157. package/src/types/components/layout-grid.ts +145 -0
  158. package/src/types/components/link-group.ts +4 -2
  159. package/src/types/components/link.ts +15 -0
  160. package/src/types/components/logo.ts +3 -3
  161. package/src/types/components/post.ts +12 -0
  162. package/src/types/components/search.ts +29 -0
  163. package/src/types/components/sidebar.ts +2 -6
  164. package/src/types/components/{megamenu.ts → steps.ts} +7 -1
  165. package/src/types/components/table-of-contents.ts +22 -0
  166. package/src/types/components/toast.ts +4 -0
  167. package/src/types/docs.ts +40 -0
  168. package/src/types/index.ts +151 -1
  169. package/src/types/theme.ts +6 -6
  170. package/src/utils/color.ts +165 -0
  171. package/src/utils/docs.ts +260 -110
  172. package/src/utils/headerStack.ts +24 -4
  173. package/src/utils/index.ts +2 -0
  174. package/src/utils/shortcuts.ts +322 -0
  175. package/src/components/TableOfContents.astro +0 -107
  176. package/src/components/astro/RLAAlert.astro +0 -93
  177. package/src/components/astro/RLAChangelog.astro +0 -23
  178. package/src/components/astro/RLAMegamenu.astro +0 -23
  179. package/src/plugins/index.ts +0 -2
  180. package/src/plugins/starlightDocsApi/components/ApiTheme.astro +0 -27
  181. package/src/plugins/starlightDocsApi/index.ts +0 -272
  182. package/src/styles/prism.css +0 -42
  183. package/src/themes/changelog.theme.ts +0 -13
  184. package/src/types/components/index.ts +0 -134
  185. /package/src/{plugins/starlightDocsApi → docs}/types.ts +0 -0
@@ -1,23 +1,109 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { TableOfContentsProps } from "../../types"
5
- import tableOfContentsThemeDefault, { createTableOfContentsTheme } from "../../themes/table-of-contents.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
7
-
8
- const uiConfig = getUIConfig()
9
- const tableOfContentsTheme = uiConfig.colors ? createTableOfContentsTheme() : tableOfContentsThemeDefault
10
-
11
- const tableOfContents = scv(tableOfContentsTheme)
12
-
13
- const {
14
- ui: uiProp,
15
- class: className,
16
- ...rest
17
- } = Astro.props as TableOfContentsProps
18
-
19
- const classes = resolveClasses(tableOfContents, {}, useUi("tableOfContents", uiProp), className);
20
- ---
21
- <div class={classes.root} data-slot="root" {...rest}>
22
- <slot />
23
- </div>
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { TableOfContentsProps } from "../../types"
5
+ import tableOfContentsThemeDefault, { createTableOfContentsTheme } from "../../themes/table-of-contents.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+
8
+ const uiConfig = getUIConfig()
9
+ const tableOfContentsTheme = uiConfig.colors ? createTableOfContentsTheme() : tableOfContentsThemeDefault
10
+
11
+ const tableOfContents = scv(tableOfContentsTheme)
12
+
13
+ const {
14
+ headings,
15
+ tableOfContents: tableOfContentsConfig,
16
+ ui: uiProp,
17
+ class: className,
18
+ containerSelector = ".markdown-content",
19
+ ...rest
20
+ } = Astro.props as TableOfContentsProps
21
+
22
+ const classes = resolveClasses(tableOfContents, {}, useUi("tableOfContents", uiProp), className);
23
+
24
+ if (tableOfContentsConfig === false) {
25
+ // Render nothing
26
+ }
27
+
28
+ const minLevel = tableOfContentsConfig ? (tableOfContentsConfig.minHeadingLevel ?? 2) : 2;
29
+ const maxLevel = tableOfContentsConfig ? (tableOfContentsConfig.maxHeadingLevel ?? 3) : 3;
30
+
31
+ const filteredHeadings = tableOfContentsConfig !== false
32
+ ? headings.filter(h => h.depth >= minLevel && h.depth <= maxLevel)
33
+ : [];
34
+
35
+ const headingSelector = Array.from({ length: maxLevel - minLevel + 1 }, (_, i) => `:scope > h${minLevel + i}`).join(", ");
36
+ ---
37
+
38
+ {tableOfContentsConfig !== false && filteredHeadings.length > 0 && (
39
+ <div class={classes.root} data-slot="root" data-container-selector={containerSelector} data-heading-selector={headingSelector} {...rest}>
40
+ <div class={classes.container} data-slot="container">
41
+ <h4 class={classes.title} data-slot="title">On this page</h4>
42
+ <ul class:list={[classes.list, "mt-2xl flex flex-col gap-3xs"]} data-slot="list">
43
+ {filteredHeadings.map(heading => (
44
+ <li
45
+ class:list={[
46
+ classes.item,
47
+ heading.depth === 2 && "pl-3xs",
48
+ heading.depth === 3 && "pl-6",
49
+ heading.depth >= 4 && "pl-9"
50
+ ]}
51
+ data-slot="item"
52
+ >
53
+ <a
54
+ href={`#${heading.slug}`}
55
+ class:list={["toc-link", classes.link]}
56
+ data-slot="link"
57
+ >
58
+ <span class={classes.linkText} data-slot="link-text">{heading.text}</span>
59
+ </a>
60
+ </li>
61
+ ))}
62
+ </ul>
63
+ </div>
64
+ </div>
65
+ )}
66
+
67
+ <style is:global>
68
+ .toc-active {
69
+ color: var(--primary);
70
+ font-weight: 600;
71
+ }
72
+ </style>
73
+
74
+ <script is:inline>
75
+ (function() {
76
+ var root = document.querySelector('[data-container-selector]');
77
+ if (!root) return;
78
+
79
+ function updateActiveHeading() {
80
+ var links = root.querySelectorAll(".toc-link");
81
+ if (links.length === 0) return;
82
+
83
+ var threshold = window.innerHeight * 0.5;
84
+ var activeId = null;
85
+
86
+ for (var i = 0; i < links.length; i++) {
87
+ var href = links[i].getAttribute("href");
88
+ if (!href || href.charAt(0) !== "#") continue;
89
+ var id = href.substring(1);
90
+ var heading = document.getElementById(id);
91
+ if (heading && heading.getBoundingClientRect().top <= threshold) {
92
+ activeId = id;
93
+ }
94
+ }
95
+
96
+ for (var j = 0; j < links.length; j++) {
97
+ links[j].classList.remove("toc-active");
98
+ }
99
+ if (activeId) {
100
+ var targetLink = root.querySelector('a[href="#' + activeId + '"].toc-link');
101
+ if (targetLink) targetLink.classList.add("toc-active");
102
+ }
103
+ }
104
+
105
+ updateActiveHeading();
106
+ window.addEventListener("scroll", updateActiveHeading, { passive: true });
107
+ document.addEventListener("astro:after-swap", updateActiveHeading);
108
+ })();
109
+ </script>
@@ -1,133 +1,147 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { TabsProps } from "../../types"
5
- import tabsThemeDefault, { createTabsTheme } from "../../themes/tabs.theme"
6
-
7
- const tabsTheme = tabsThemeDefault
8
- const tabs = scv(tabsTheme)
9
-
10
- const {
11
- items = [],
12
- value = "",
13
- variant = "solid",
14
- orientation = "horizontal",
15
- size = "md",
16
- color = "primary",
17
- ui: uiProp,
18
- class: className,
19
- ...rest
20
- } = Astro.props as TabsProps
21
-
22
- const classes = resolveClasses(tabs, {
23
- variant,
24
- orientation,
25
- size
26
- }, useUi("tabs", uiProp), className);
27
-
28
- const initialValue = value || (items.length > 0 ? items[0].value : "")
29
- ---
30
- <div class={classes.root} data-slot="root" data-tabs-container data-value={initialValue} {...rest}>
31
- <div class={classes.list} data-slot="list" role="tablist">
32
- {items.map((item) => {
33
- const active = item.value === initialValue
34
- return (
35
- <button
36
- type="button"
37
- class={classes.trigger}
38
- data-slot="trigger"
39
- role="tab"
40
- data-value={item.value}
41
- data-state={active ? "active" : "inactive"}
42
- disabled={item.disabled}
43
- >
44
- {item.icon && <span class={item.icon + " mr-2"} />}
45
- {item.label}
46
- </button>
47
- )
48
- })}
49
- </div>
50
- <div class="flex-1">
51
- <slot>
52
- {items.map(item => {
53
- const active = item.value === initialValue
54
- return (
55
- <div
56
- class={classes.content + (active ? "" : " hidden")}
57
- data-slot="content"
58
- role="tabpanel"
59
- data-value={item.value}
60
- >
61
- {item.content}
62
- </div>
63
- )
64
- })}
65
- </slot>
66
- </div>
67
- </div>
68
-
69
- <script>
70
- function initTabs() {
71
- document.querySelectorAll("[data-tabs-container]").forEach(container => {
72
- const containerValue = (container as HTMLElement).dataset.value;
73
- const triggers = container.querySelectorAll("[role=tab]");
74
- const panels = container.querySelectorAll("[role=tabpanel]");
75
-
76
- triggers.forEach(trigger => {
77
- const val = (trigger as HTMLButtonElement).dataset.value;
78
- trigger.setAttribute("data-state", val === containerValue ? "active" : "inactive");
79
- });
80
-
81
- panels.forEach(panel => {
82
- const val = (panel as HTMLElement).dataset.value;
83
- if (val === containerValue) {
84
- panel.classList.remove("hidden");
85
- (panel as HTMLElement).style.display = "";
86
- } else {
87
- panel.classList.add("hidden");
88
- (panel as HTMLElement).style.display = "none";
89
- }
90
- });
91
- });
92
- }
93
-
94
- // Setup click listeners
95
- function setupTabsListeners() {
96
- document.querySelectorAll("[data-tabs-container]").forEach(container => {
97
- const triggers = container.querySelectorAll("[role=tab]");
98
- const panels = container.querySelectorAll("[role=tabpanel]");
99
-
100
- triggers.forEach(trigger => {
101
- // Prevent duplicate listener registration
102
- if ((trigger as any).__tabsListenerAttached) return;
103
- (trigger as any).__tabsListenerAttached = true;
104
-
105
- trigger.addEventListener("click", () => {
106
- const targetValue = (trigger as HTMLButtonElement).dataset.value;
107
-
108
- triggers.forEach(t => {
109
- t.setAttribute("data-state", t.dataset.value === targetValue ? "active" : "inactive");
110
- });
111
-
112
- panels.forEach(panel => {
113
- if ((panel as HTMLElement).dataset.value === targetValue) {
114
- panel.classList.remove("hidden");
115
- (panel as HTMLElement).style.display = "";
116
- } else {
117
- panel.classList.add("hidden");
118
- (panel as HTMLElement).style.display = "none";
119
- }
120
- });
121
- });
122
- });
123
- });
124
- }
125
-
126
- initTabs();
127
- setupTabsListeners();
128
-
129
- document.addEventListener("astro:after-swap", () => {
130
- initTabs();
131
- setupTabsListeners();
132
- });
133
- </script>
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { TabsProps } from "../../types"
5
+ import tabsThemeDefault, { createTabsTheme } from "../../themes/tabs.theme"
6
+
7
+ import { getUIConfig } from "virtual:rimelight-ui"
8
+
9
+ const uiConfig = getUIConfig()
10
+ const tabsTheme = uiConfig.colors ? createTabsTheme() : tabsThemeDefault
11
+ const tabs = scv(tabsTheme)
12
+
13
+ const {
14
+ items = [],
15
+ value = "",
16
+ variant = "solid",
17
+ orientation = "horizontal",
18
+ size = "md",
19
+ color = "primary",
20
+ ui: uiProp,
21
+ class: className,
22
+ ...rest
23
+ } = Astro.props as TabsProps
24
+
25
+ const classes = resolveClasses(tabs, {
26
+ variant,
27
+ orientation,
28
+ size
29
+ }, useUi("tabs", uiProp), className);
30
+
31
+ const initialValue = value || (items.length > 0 ? items[0]?.value : "")
32
+ ---
33
+ <rla-tabs {...rest}>
34
+ <div class={classes.root} data-slot="root" data-tabs-container data-value={initialValue}>
35
+ <div class={classes.list} data-slot="list" role="tablist">
36
+ {items.map((item) => {
37
+ const active = item.value === initialValue
38
+ return (
39
+ <button
40
+ type="button"
41
+ class={classes.trigger}
42
+ data-slot="trigger"
43
+ role="tab"
44
+ data-value={item.value}
45
+ data-state={active ? "active" : "inactive"}
46
+ disabled={item.disabled}
47
+ >
48
+ {item.icon && <span class={item.icon + " mr-2"} />}
49
+ {item.label}
50
+ </button>
51
+ )
52
+ })}
53
+ </div>
54
+ <div class="flex-1">
55
+ <slot>
56
+ {items.map(item => {
57
+ const active = item.value === initialValue
58
+ return (
59
+ <div
60
+ class={classes.content + (active ? "" : " hidden")}
61
+ data-slot="content"
62
+ role="tabpanel"
63
+ data-value={item.value}
64
+ >
65
+ {item.content}
66
+ </div>
67
+ )
68
+ })}
69
+ </slot>
70
+ </div>
71
+ </div>
72
+ </rla-tabs>
73
+
74
+ <script>
75
+ if (typeof HTMLElement !== 'undefined') {
76
+ class RLATabs extends HTMLElement {
77
+ private tabsCleanup: (() => void) | null = null;
78
+
79
+ connectedCallback() {
80
+ this.style.display = 'contents';
81
+ const container = this.querySelector("[data-tabs-container]") as HTMLElement | null;
82
+ if (!container) return;
83
+
84
+ const containerValue = container.dataset.value;
85
+ const triggers = container.querySelectorAll("[role=tab]");
86
+ const panels = container.querySelectorAll("[role=tabpanel]");
87
+
88
+ triggers.forEach(trigger => {
89
+ const val = (trigger as HTMLButtonElement).dataset.value;
90
+ trigger.setAttribute("data-state", val === containerValue ? "active" : "inactive");
91
+ });
92
+
93
+ panels.forEach(panel => {
94
+ const val = (panel as HTMLElement).dataset.value;
95
+ if (val === containerValue) {
96
+ panel.classList.remove("hidden");
97
+ (panel as HTMLElement).style.display = "";
98
+ } else {
99
+ panel.classList.add("hidden");
100
+ (panel as HTMLElement).style.display = "none";
101
+ }
102
+ });
103
+
104
+ const clickCleanups: (() => void)[] = [];
105
+
106
+ triggers.forEach(triggerNode => {
107
+ const trigger = triggerNode as HTMLButtonElement;
108
+ const onClick = () => {
109
+ const targetValue = trigger.dataset.value;
110
+
111
+ triggers.forEach(tNode => {
112
+ const t = tNode as HTMLButtonElement;
113
+ t.setAttribute("data-state", t.dataset.value === targetValue ? "active" : "inactive");
114
+ });
115
+
116
+ panels.forEach(panel => {
117
+ if ((panel as HTMLElement).dataset.value === targetValue) {
118
+ panel.classList.remove("hidden");
119
+ (panel as HTMLElement).style.display = "";
120
+ } else {
121
+ panel.classList.add("hidden");
122
+ (panel as HTMLElement).style.display = "none";
123
+ }
124
+ });
125
+ };
126
+ trigger.addEventListener("click", onClick);
127
+ clickCleanups.push(() => trigger.removeEventListener("click", onClick));
128
+ });
129
+
130
+ this.tabsCleanup = () => {
131
+ clickCleanups.forEach(fn => fn());
132
+ };
133
+ }
134
+
135
+ disconnectedCallback() {
136
+ if (this.tabsCleanup) {
137
+ this.tabsCleanup();
138
+ this.tabsCleanup = null;
139
+ }
140
+ }
141
+ }
142
+
143
+ if (!customElements.get('rla-tabs')) {
144
+ customElements.define('rla-tabs', RLATabs);
145
+ }
146
+ }
147
+ </script>
@@ -4,7 +4,10 @@ import { useUi, resolveClasses } from "../../utils"
4
4
  import type { TextareaProps } from "../../types"
5
5
  import textareaThemeDefault, { createTextareaTheme } from "../../themes/textarea.theme"
6
6
 
7
- const textareaTheme = textareaThemeDefault
7
+ import { getUIConfig } from "virtual:rimelight-ui"
8
+
9
+ const uiConfig = getUIConfig()
10
+ const textareaTheme = uiConfig.colors ? createTextareaTheme() : textareaThemeDefault
8
11
  const textarea = scv(textareaTheme)
9
12
 
10
13
  const {
@@ -1,77 +1,106 @@
1
- ---
2
- import { scv } from "css-variants"
3
- import { useUi, resolveClasses } from "../../utils"
4
- import type { ThemeSelectorProps } from "../../types"
5
- import themeSelectorThemeDefault, { createThemeSelectorTheme } from "../../themes/theme-selector.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
7
- import RLAButton from "./RLAButton.astro"
8
-
9
- const uiConfig = getUIConfig()
10
- const themeSelectorTheme = uiConfig.colors ? createThemeSelectorTheme() : themeSelectorThemeDefault
11
-
12
- const themeSelector = scv(themeSelectorTheme)
13
-
14
- const {
15
- size = "md",
16
- ui: uiProp,
17
- class: className,
18
- ...rest
19
- } = Astro.props as ThemeSelectorProps
20
-
21
- const classes = resolveClasses(themeSelector, {
22
- size
23
- }, useUi("themeSelector", uiProp), className);
24
- ---
25
-
26
- <RLAButton
27
- size={size}
28
- class:list={["theme-toggle-button", classes.root]}
29
- variant="ghost"
30
- aria-label="Toggle theme"
31
- {...rest}
32
- >
33
- <span class:list={[classes.sun]} />
34
- <span class:list={[classes.moon]} />
35
- </RLAButton>
36
-
37
- <script>
38
- function applyStoredTheme() {
39
- const stored = localStorage.getItem('theme');
40
- if (stored === 'dark') {
41
- document.documentElement.classList.add('dark');
42
- } else if (stored === 'light') {
43
- document.documentElement.classList.remove('dark');
44
- }
45
- }
46
-
47
- function setupThemeToggle() {
48
- const buttons = document.querySelectorAll('.theme-toggle-button');
49
-
50
- const updateButtons = (isDark: boolean) => {
51
- buttons.forEach(btn => {
52
- btn.setAttribute('data-state', isDark ? 'on' : 'off');
53
- btn.setAttribute('aria-pressed', isDark.toString());
54
- });
55
- };
56
-
57
- const currentIsDark = document.documentElement.classList.contains('dark');
58
- updateButtons(currentIsDark);
59
-
60
- buttons.forEach(button => {
61
- if (button.hasAttribute('data-initialized')) return;
62
- button.setAttribute('data-initialized', '');
63
- button.addEventListener('click', () => {
64
- const isDark = document.documentElement.classList.toggle('dark');
65
- localStorage.setItem('theme', isDark ? 'dark' : 'light');
66
- updateButtons(isDark);
67
- });
68
- });
69
- }
70
-
71
- applyStoredTheme();
72
- setupThemeToggle();
73
- document.addEventListener('astro:page-load', () => {
74
- applyStoredTheme();
75
- setupThemeToggle();
76
- });
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ThemeSelectorProps } from "../../types"
5
+ import themeSelectorThemeDefault, { createThemeSelectorTheme } from "../../themes/theme-selector.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+ import RLAButton from "./RLAButton.astro"
8
+
9
+ const uiConfig = getUIConfig()
10
+ const themeSelectorTheme = uiConfig.colors ? createThemeSelectorTheme() : themeSelectorThemeDefault
11
+
12
+ const themeSelector = scv(themeSelectorTheme)
13
+
14
+ const {
15
+ size = "md",
16
+ ui: uiProp,
17
+ class: className,
18
+ ...rest
19
+ } = Astro.props as ThemeSelectorProps
20
+
21
+ const classes = resolveClasses(themeSelector, {
22
+ size
23
+ }, useUi("themeSelector", uiProp), className);
24
+ ---
25
+
26
+ <rla-theme-selector {...rest}>
27
+ <RLAButton
28
+ size={size}
29
+ class:list={["theme-toggle-button", classes.root]}
30
+ variant="ghost"
31
+ aria-label="Toggle theme"
32
+ >
33
+ <span class:list={[classes.sun]} />
34
+ <span class:list={[classes.moon]} />
35
+ </RLAButton>
36
+ </rla-theme-selector>
37
+
38
+ <script>
39
+ import { defineShortcuts } from "../../utils/shortcuts"
40
+
41
+ function applyStoredTheme() {
42
+ const stored = localStorage.getItem('theme');
43
+ if (stored === 'dark') {
44
+ document.documentElement.classList.add('dark');
45
+ document.documentElement.classList.remove('light');
46
+ } else if (stored === 'light') {
47
+ document.documentElement.classList.remove('dark');
48
+ document.documentElement.classList.add('light');
49
+ }
50
+ }
51
+
52
+ applyStoredTheme();
53
+
54
+ function onToggle() {
55
+ const willBeDark = !document.documentElement.classList.contains('dark');
56
+ document.documentElement.classList.toggle('dark', willBeDark);
57
+ document.documentElement.classList.toggle('light', !willBeDark);
58
+ localStorage.setItem('theme', willBeDark ? 'dark' : 'light');
59
+
60
+ document.querySelectorAll('.theme-toggle-button').forEach(btn => {
61
+ btn.setAttribute('data-state', willBeDark ? 'on' : 'off');
62
+ btn.setAttribute('aria-pressed', willBeDark.toString());
63
+ });
64
+ }
65
+
66
+ class RLAThemeSelector extends HTMLElement {
67
+ private buttonCleanup: (() => void) | null = null;
68
+
69
+ connectedCallback() {
70
+ this.style.display = 'contents';
71
+ const button = this.querySelector('.theme-toggle-button');
72
+ if (!button) return;
73
+
74
+ const isDark = document.documentElement.classList.contains('dark');
75
+ button.setAttribute('data-state', isDark ? 'on' : 'off');
76
+ button.setAttribute('aria-pressed', isDark.toString());
77
+
78
+ button.addEventListener('click', onToggle);
79
+
80
+ const cleanupShortcut = defineShortcuts({
81
+ meta_alt_t: {
82
+ handler: onToggle,
83
+ label: "Toggle Theme",
84
+ description: "Switch between light and dark theme mode",
85
+ category: "system"
86
+ }
87
+ });
88
+
89
+ this.buttonCleanup = () => {
90
+ button.removeEventListener('click', onToggle);
91
+ cleanupShortcut();
92
+ };
93
+ }
94
+
95
+ disconnectedCallback() {
96
+ if (this.buttonCleanup) {
97
+ this.buttonCleanup();
98
+ this.buttonCleanup = null;
99
+ }
100
+ }
101
+ }
102
+
103
+ if (!customElements.get('rla-theme-selector')) {
104
+ customElements.define('rla-theme-selector', RLAThemeSelector);
105
+ }
77
106
  </script>