@rimelight/ui 0.0.57 → 0.0.60

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 (46) hide show
  1. package/package.json +3 -4
  2. package/src/components/avatar/avatar.theme.ts +58 -1
  3. package/src/components/avatar/avatar.ts +21 -1
  4. package/src/components/avatar-group/RLAAvatarGroup.astro +37 -161
  5. package/src/components/avatar-group/RLSAvatarGroup.tsx +37 -121
  6. package/src/components/breadcrumb/RLABreadcrumb.astro +59 -196
  7. package/src/components/breadcrumb/RLSBreadcrumb.tsx +57 -120
  8. package/src/components/card/RLSCard.tsx +1 -2
  9. package/src/components/card/RLVCard.vue +1 -2
  10. package/src/components/carousel/RLACarousel.astro +2 -1
  11. package/src/components/carousel/RLSCarousel.tsx +3 -11
  12. package/src/components/chart/RLAChart.astro +211 -219
  13. package/src/components/dashboard-navbar/RLADashboardNavbar.astro +1 -1
  14. package/src/components/dashboard-navbar/RLSDashboardNavbar.tsx +1 -15
  15. package/src/components/dashboard-panel/RLADashboardPanel.astro +1 -1
  16. package/src/components/dashboard-panel/RLSDashboardPanel.tsx +1 -6
  17. package/src/components/dashboard-search/RLADashboardSearch.astro +1 -1
  18. package/src/components/head/UIHead.astro +1 -12
  19. package/src/components/image/RLAImage.astro +15 -20
  20. package/src/components/image/RLSImage.tsx +5 -12
  21. package/src/components/image/image.theme.ts +4 -4
  22. package/src/components/input-rating/RLAInputRating.astro +19 -14
  23. package/src/components/input-rating/RLSInputRating.tsx +39 -32
  24. package/src/components/input-tags/RLAInputTags.astro +27 -137
  25. package/src/components/layout-grid/RLALayoutGrid.astro +4 -4
  26. package/src/components/logo/RLALogo.astro +0 -16
  27. package/src/components/logo/RLSLogo.tsx +1 -8
  28. package/src/components/marquee/RLAMarquee.astro +55 -62
  29. package/src/components/page-section/RLAPageSection.astro +2 -2
  30. package/src/components/progress/RLAProgress.astro +39 -38
  31. package/src/components/progress/RLSProgress.tsx +16 -5
  32. package/src/components/progress/progress.theme.ts +1 -1
  33. package/src/components/scroll-area/RLAScrollArea.astro +4 -5
  34. package/src/components/scroll-area/RLSScrollArea.tsx +5 -6
  35. package/src/components/splitter/RLASplitter.astro +217 -230
  36. package/src/components/splitter/RLSSplitter.tsx +2 -6
  37. package/src/components/steps/RLASteps.astro +110 -110
  38. package/src/components/sticky-surface/RLAStickySurface.astro +49 -67
  39. package/src/components/table/RLATable.astro +16 -46
  40. package/src/components/tabs/RLATabs.astro +352 -385
  41. package/src/components/textarea/RLATextarea.astro +1 -2
  42. package/src/components/theme-selector/RLAThemeSelector.astro +6 -6
  43. package/src/components/timeline/RLATimeline.astro +49 -23
  44. package/src/components/timeline/RLSTimeline.tsx +38 -13
  45. package/src/components/timeline/timeline.ts +10 -0
  46. package/src/components/tooltip/RLATooltip.astro +7 -11
@@ -1,230 +1,217 @@
1
- ---
2
- import type { SplitterProps } from "./splitter"
3
- import { splitterTheme } from "./splitter.theme"
4
-
5
- import RLAIcon from "../icon/RLAIcon.astro"
6
-
7
-
8
- const {
9
- direction = "horizontal",
10
- defaultSizes = [50, 50],
11
- ...rest
12
- } = Astro.props as SplitterProps
13
-
14
- const classes = splitterTheme(Astro.props)
15
-
16
- // Normalise sizes so they sum to 100
17
- const total = defaultSizes.reduce((s, v) => s + v, 0)
18
- const sizes = defaultSizes.map(s => (s / (total || 100)) * 100)
19
-
20
- const panelCount = sizes.length
21
- const id = `splitter-${Math.random().toString(36).substring(2, 9)}`
22
-
23
- const panelContents: string[] = []
24
- await Promise.all(
25
- sizes.map(async (_, i) => {
26
- if (Astro.slots.has(`panel-${i}`)) {
27
- panelContents[i] = await Astro.slots.render(`panel-${i}`)
28
- }
29
- })
30
- )
31
- ---
32
-
33
- <rla-splitter {...rest}>
34
- <div
35
- class:list={[classes.root, id]}
36
- data-slot="root"
37
- data-resizable
38
- data-direction={direction}
39
- >
40
- {sizes.map((_size, i) => (
41
- <>
42
- <div
43
- class={classes.panel}
44
- data-slot="panel"
45
- data-resizable-panel={i}
46
- >
47
- {Astro.slots.has(`panel-${i}`) ? (
48
- <Fragment set:html={panelContents[i]} />
49
- ) : (
50
- i === 0
51
- ? <slot />
52
- : <slot name="panel" />
53
- )}
54
- </div>
55
-
56
- {/* Render a handle between panels, not after the last one */}
57
- {i < panelCount - 1 && (
58
- <div
59
- class={classes.handle}
60
- data-slot="handle"
61
- data-resizable-handle={i}
62
- role="separator"
63
- aria-orientation={direction === "horizontal" ? "vertical" : "horizontal"}
64
- tabindex={0}
65
- aria-label="Resize panels"
66
- >
67
- <RLAIcon
68
- name={direction === "horizontal" ? "gripVertical" : "gripHorizontal"}
69
- class="size-3.5 text-muted/50"
70
- aria-hidden="true"
71
- />
72
- </div>
73
- )}
74
- </>
75
- ))}
76
- </div>
77
- </rla-splitter>
78
-
79
- <script>
80
- class RLASplitter extends HTMLElement {
81
- private splitterCleanup: (() => void) | null = null;
82
-
83
- connectedCallback() {
84
- this.style.display = 'contents';
85
- const container = this.querySelector("[data-resizable]") as HTMLElement | null;
86
- if (!container) return;
87
-
88
- const direction = container.dataset["direction"] ?? "horizontal";
89
- const isHorizontal = direction === "horizontal";
90
-
91
- const panels = Array.from(
92
- container.querySelectorAll("[data-resizable-panel]")
93
- ) as HTMLElement[];
94
-
95
- const handles = Array.from(
96
- container.querySelectorAll("[data-resizable-handle]")
97
- ) as HTMLElement[];
98
-
99
- const cleanupFns: (() => void)[] = [];
100
-
101
- handles.forEach((handle, idx) => {
102
- const panelA = panels[idx];
103
- const panelB = panels[idx + 1];
104
- if (!panelA || !panelB) return;
105
-
106
- const containerSize = () =>
107
- isHorizontal
108
- ? container.clientWidth
109
- : container.clientHeight;
110
-
111
- let isDragging = false;
112
- let startPos = 0;
113
- let startASize = 0;
114
- let startBSize = 0;
115
-
116
- const getSize = (el: HTMLElement) =>
117
- isHorizontal ? el.offsetWidth : el.offsetHeight;
118
-
119
- const setSize = (el: HTMLElement, px: number) => {
120
- const pct = (px / containerSize()) * 100;
121
- if (isHorizontal) {
122
- el.style.width = `${pct}%`;
123
- } else {
124
- el.style.height = `${pct}%`;
125
- }
126
- };
127
-
128
- const onMouseMove = (e: MouseEvent) => {
129
- if (!isDragging) return;
130
- const delta = isHorizontal
131
- ? e.clientX - startPos
132
- : e.clientY - startPos;
133
-
134
- const newASize = Math.max(48, startASize + delta);
135
- const newBSize = Math.max(48, startBSize - delta);
136
-
137
- // Only resize if both panels have enough space
138
- if (startASize + startBSize - newASize < 48) return;
139
-
140
- setSize(panelA, newASize);
141
- setSize(panelB, newBSize);
142
- };
143
-
144
- const onMouseUp = () => {
145
- isDragging = false;
146
- document.body.style.cursor = "";
147
- document.body.style.userSelect = "";
148
- handle.classList.remove("bg-primary/30");
149
- panels.forEach(p => p.style.transition = "");
150
- document.removeEventListener("mousemove", onMouseMove);
151
- document.removeEventListener("mouseup", onMouseUp);
152
- };
153
-
154
- const onMouseDown = (e: MouseEvent) => {
155
- e.preventDefault();
156
- isDragging = true;
157
- startPos = isHorizontal ? e.clientX : e.clientY;
158
- startASize = getSize(panelA);
159
- startBSize = getSize(panelB);
160
- document.body.style.cursor = isHorizontal ? "col-resize" : "row-resize";
161
- document.body.style.userSelect = "none";
162
- handle.classList.add("bg-primary/30");
163
- panels.forEach(p => p.style.transition = "none");
164
- document.addEventListener("mousemove", onMouseMove);
165
- document.addEventListener("mouseup", onMouseUp);
166
- };
167
-
168
- handle.addEventListener("mousedown", onMouseDown);
169
- cleanupFns.push(() => {
170
- handle.removeEventListener("mousedown", onMouseDown);
171
- document.removeEventListener("mousemove", onMouseMove);
172
- document.removeEventListener("mouseup", onMouseUp);
173
- });
174
-
175
- // Keyboard resize: arrow keys shift by 2%
176
- const onKeyDown = (e: KeyboardEvent) => {
177
- const step = containerSize() * 0.02;
178
- const forward = isHorizontal
179
- ? e.key === "ArrowRight"
180
- : e.key === "ArrowDown";
181
- const backward = isHorizontal
182
- ? e.key === "ArrowLeft"
183
- : e.key === "ArrowUp";
184
-
185
- if (!forward && !backward) return;
186
- e.preventDefault();
187
-
188
- const aSize = getSize(panelA);
189
- const bSize = getSize(panelB);
190
- const delta = forward ? step : -step;
191
-
192
- setSize(panelA, Math.max(48, aSize + delta));
193
- setSize(panelB, Math.max(48, bSize - delta));
194
- };
195
-
196
- handle.addEventListener("keydown", onKeyDown);
197
- cleanupFns.push(() => {
198
- handle.removeEventListener("keydown", onKeyDown);
199
- });
200
- });
201
-
202
- this.splitterCleanup = () => {
203
- cleanupFns.forEach(fn => fn());
204
- };
205
- }
206
-
207
- disconnectedCallback() {
208
- if (this.splitterCleanup) {
209
- this.splitterCleanup();
210
- this.splitterCleanup = null;
211
- }
212
- }
213
- }
214
-
215
- if (!customElements.get('rla-splitter')) {
216
- customElements.define('rla-splitter', RLASplitter);
217
- }
218
- </script>
219
-
220
- <style is:inline set:html={`
221
- .${id}[data-direction="horizontal"] > [data-resizable-panel="0"] { width: ${sizes[0] ?? 50}%; }
222
- .${id}[data-direction="horizontal"] > [data-resizable-panel="1"] { width: ${sizes[1] ?? 50}%; }
223
- .${id}[data-direction="horizontal"] > [data-resizable-panel="2"] { width: ${sizes[2] ?? 0}%; }
224
- .${id}[data-direction="horizontal"] > [data-resizable-panel="3"] { width: ${sizes[3] ?? 0}%; }
225
-
226
- .${id}[data-direction="vertical"] > [data-resizable-panel="0"] { height: ${sizes[0] ?? 50}%; }
227
- .${id}[data-direction="vertical"] > [data-resizable-panel="1"] { height: ${sizes[1] ?? 50}%; }
228
- .${id}[data-direction="vertical"] > [data-resizable-panel="2"] { height: ${sizes[2] ?? 0}%; }
229
- .${id}[data-direction="vertical"] > [data-resizable-panel="3"] { height: ${sizes[3] ?? 0}%; }
230
- `} />
1
+ ---
2
+ import type { SplitterProps } from "./splitter"
3
+ import { splitterTheme } from "./splitter.theme"
4
+
5
+ import RLAIcon from "../icon/RLAIcon.astro"
6
+
7
+
8
+ const {
9
+ direction = "horizontal",
10
+ defaultSizes = [50, 50],
11
+ ...rest
12
+ } = Astro.props as SplitterProps
13
+
14
+ const classes = splitterTheme(Astro.props)
15
+
16
+ // Normalise sizes so they sum to 100
17
+ const total = defaultSizes.reduce((s, v) => s + v, 0)
18
+ const sizes = defaultSizes.map(s => (s / (total || 100)) * 100)
19
+
20
+ const panelCount = sizes.length
21
+
22
+ const panelContents: string[] = []
23
+ await Promise.all(
24
+ sizes.map(async (_, i) => {
25
+ if (Astro.slots.has(`panel-${i}`)) {
26
+ panelContents[i] = await Astro.slots.render(`panel-${i}`)
27
+ }
28
+ })
29
+ )
30
+ ---
31
+
32
+ <rla-splitter {...rest}>
33
+ <div
34
+ class:list={[classes.root]}
35
+ data-slot="root"
36
+ data-resizable
37
+ data-direction={direction}
38
+ >
39
+ {sizes.map((_size, i) => (
40
+ <>
41
+ <div
42
+ class:list={[classes.panel, direction === "horizontal" ? `w-[${sizes[i]}%]` : `h-[${sizes[i]}%]`]}
43
+ data-slot="panel"
44
+ data-resizable-panel={i}
45
+ >
46
+ {Astro.slots.has(`panel-${i}`) ? (
47
+ <Fragment set:html={panelContents[i]} />
48
+ ) : (
49
+ i === 0
50
+ ? <slot />
51
+ : <slot name="panel" />
52
+ )}
53
+ </div>
54
+
55
+ {/* Render a handle between panels, not after the last one */}
56
+ {i < panelCount - 1 && (
57
+ <div
58
+ class={classes.handle}
59
+ data-slot="handle"
60
+ data-resizable-handle={i}
61
+ role="separator"
62
+ aria-orientation={direction === "horizontal" ? "vertical" : "horizontal"}
63
+ tabindex={0}
64
+ aria-label="Resize panels"
65
+ >
66
+ <RLAIcon
67
+ name={direction === "horizontal" ? "gripVertical" : "gripHorizontal"}
68
+ class="size-3.5 text-muted/50"
69
+ aria-hidden="true"
70
+ />
71
+ </div>
72
+ )}
73
+ </>
74
+ ))}
75
+ </div>
76
+ </rla-splitter>
77
+
78
+ <script>
79
+ class RLASplitter extends HTMLElement {
80
+ private splitterCleanup: (() => void) | null = null;
81
+
82
+ connectedCallback() {
83
+ this.style.display = 'contents';
84
+ const container = this.querySelector("[data-resizable]") as HTMLElement | null;
85
+ if (!container) return;
86
+
87
+ const direction = container.dataset["direction"] ?? "horizontal";
88
+ const isHorizontal = direction === "horizontal";
89
+
90
+ const panels = Array.from(
91
+ container.querySelectorAll("[data-resizable-panel]")
92
+ ) as HTMLElement[];
93
+
94
+ const handles = Array.from(
95
+ container.querySelectorAll("[data-resizable-handle]")
96
+ ) as HTMLElement[];
97
+
98
+ const cleanupFns: (() => void)[] = [];
99
+
100
+ handles.forEach((handle, idx) => {
101
+ const panelA = panels[idx];
102
+ const panelB = panels[idx + 1];
103
+ if (!panelA || !panelB) return;
104
+
105
+ const containerSize = () =>
106
+ isHorizontal
107
+ ? container.clientWidth
108
+ : container.clientHeight;
109
+
110
+ let isDragging = false;
111
+ let startPos = 0;
112
+ let startASize = 0;
113
+ let startBSize = 0;
114
+
115
+ const getSize = (el: HTMLElement) =>
116
+ isHorizontal ? el.offsetWidth : el.offsetHeight;
117
+
118
+ const setSize = (el: HTMLElement, px: number) => {
119
+ const pct = (px / containerSize()) * 100;
120
+ if (isHorizontal) {
121
+ el.style.width = `${pct}%`;
122
+ } else {
123
+ el.style.height = `${pct}%`;
124
+ }
125
+ };
126
+
127
+ const onMouseMove = (e: MouseEvent) => {
128
+ if (!isDragging) return;
129
+ const delta = isHorizontal
130
+ ? e.clientX - startPos
131
+ : e.clientY - startPos;
132
+
133
+ const newASize = Math.max(48, startASize + delta);
134
+ const newBSize = Math.max(48, startBSize - delta);
135
+
136
+ // Only resize if both panels have enough space
137
+ if (startASize + startBSize - newASize < 48) return;
138
+
139
+ setSize(panelA, newASize);
140
+ setSize(panelB, newBSize);
141
+ };
142
+
143
+ const onMouseUp = () => {
144
+ isDragging = false;
145
+ document.body.style.cursor = "";
146
+ document.body.style.userSelect = "";
147
+ handle.classList.remove("bg-primary/30");
148
+ panels.forEach(p => p.style.transition = "");
149
+ document.removeEventListener("mousemove", onMouseMove);
150
+ document.removeEventListener("mouseup", onMouseUp);
151
+ };
152
+
153
+ const onMouseDown = (e: MouseEvent) => {
154
+ e.preventDefault();
155
+ isDragging = true;
156
+ startPos = isHorizontal ? e.clientX : e.clientY;
157
+ startASize = getSize(panelA);
158
+ startBSize = getSize(panelB);
159
+ document.body.style.cursor = isHorizontal ? "col-resize" : "row-resize";
160
+ document.body.style.userSelect = "none";
161
+ handle.classList.add("bg-primary/30");
162
+ panels.forEach(p => p.style.transition = "none");
163
+ document.addEventListener("mousemove", onMouseMove);
164
+ document.addEventListener("mouseup", onMouseUp);
165
+ };
166
+
167
+ handle.addEventListener("mousedown", onMouseDown);
168
+ cleanupFns.push(() => {
169
+ handle.removeEventListener("mousedown", onMouseDown);
170
+ document.removeEventListener("mousemove", onMouseMove);
171
+ document.removeEventListener("mouseup", onMouseUp);
172
+ });
173
+
174
+ // Keyboard resize: arrow keys shift by 2%
175
+ const onKeyDown = (e: KeyboardEvent) => {
176
+ const step = containerSize() * 0.02;
177
+ const forward = isHorizontal
178
+ ? e.key === "ArrowRight"
179
+ : e.key === "ArrowDown";
180
+ const backward = isHorizontal
181
+ ? e.key === "ArrowLeft"
182
+ : e.key === "ArrowUp";
183
+
184
+ if (!forward && !backward) return;
185
+ e.preventDefault();
186
+
187
+ const aSize = getSize(panelA);
188
+ const bSize = getSize(panelB);
189
+ const delta = forward ? step : -step;
190
+
191
+ setSize(panelA, Math.max(48, aSize + delta));
192
+ setSize(panelB, Math.max(48, bSize - delta));
193
+ };
194
+
195
+ handle.addEventListener("keydown", onKeyDown);
196
+ cleanupFns.push(() => {
197
+ handle.removeEventListener("keydown", onKeyDown);
198
+ });
199
+ });
200
+
201
+ this.splitterCleanup = () => {
202
+ cleanupFns.forEach(fn => fn());
203
+ };
204
+ }
205
+
206
+ disconnectedCallback() {
207
+ if (this.splitterCleanup) {
208
+ this.splitterCleanup();
209
+ this.splitterCleanup = null;
210
+ }
211
+ }
212
+ }
213
+
214
+ if (!customElements.get('rla-splitter')) {
215
+ customElements.define('rla-splitter', RLASplitter);
216
+ }
217
+ </script>
@@ -121,10 +121,7 @@ const RLSSplitter: Component<RLSSplitterProps> = (allProps) => {
121
121
  setSizes(next)
122
122
  }
123
123
 
124
- const panelStyle = (size: number) =>
125
- isHorizontal()
126
- ? { "flex": `0 0 ${size}%` as const, "min-width": "0" }
127
- : { "flex": `0 0 ${size}%` as const, "min-height": "0" }
124
+ const panelClass = (size: number) => (isHorizontal() ? `w-[${size}%]` : `h-[${size}%]`)
128
125
 
129
126
  return (
130
127
  <div
@@ -139,10 +136,9 @@ const RLSSplitter: Component<RLSSplitterProps> = (allProps) => {
139
136
  {(size, i) => (
140
137
  <>
141
138
  <div
142
- class={resolvedClasses().panel}
139
+ class={`${resolvedClasses().panel} ${panelClass(size)}`}
143
140
  data-slot="panel"
144
141
  data-resizable-panel={i()}
145
- style={panelStyle(size)}
146
142
  >
147
143
  {panelContents()[i()]}
148
144
  </div>