@rimelight/ui 0.0.30 → 0.0.31

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 (152) hide show
  1. package/package.json +1 -1
  2. package/src/components/astro/RLAAlert.astro +60 -0
  3. package/src/components/astro/RLAAlertDialog.astro +86 -0
  4. package/src/components/astro/RLAAspectRatio.astro +23 -0
  5. package/src/components/astro/RLAAvatar.astro +56 -0
  6. package/src/components/astro/RLAAvatarGroup.astro +19 -0
  7. package/src/components/astro/RLABadge.astro +31 -0
  8. package/src/components/astro/RLABreadcrumb.astro +44 -0
  9. package/src/components/astro/RLACard.astro +74 -0
  10. package/src/components/astro/RLACarousel.astro +71 -0
  11. package/src/components/astro/RLAChart.astro +215 -0
  12. package/src/components/astro/RLACheckbox.astro +51 -0
  13. package/src/components/astro/RLACollapsible.astro +38 -0
  14. package/src/components/astro/RLACombobox.astro +131 -0
  15. package/src/components/astro/RLADialog.astro +95 -0
  16. package/src/components/astro/RLADrawer.astro +74 -0
  17. package/src/components/astro/RLADropdownMenu.astro +82 -0
  18. package/src/components/astro/RLADropzone.astro +134 -0
  19. package/src/components/astro/RLAField.astro +43 -0
  20. package/src/components/{Head.astro → astro/RLAHead.astro} +181 -199
  21. package/src/components/astro/RLAHoverCard.astro +31 -0
  22. package/src/components/astro/RLAInput.astro +60 -0
  23. package/src/components/astro/RLAInputGroup.astro +35 -0
  24. package/src/components/astro/RLAKbd.astro +22 -0
  25. package/src/components/astro/RLALabel.astro +23 -0
  26. package/src/components/astro/RLALocaleSelector.astro +110 -0
  27. package/src/components/astro/RLAMarquee.astro +32 -0
  28. package/src/components/astro/RLANativeSelect.astro +51 -0
  29. package/src/components/astro/RLANavigationMenu.astro +136 -0
  30. package/src/components/astro/RLAPagination.astro +94 -0
  31. package/src/components/astro/RLAPopover.astro +31 -0
  32. package/src/components/astro/RLAProgress.astro +43 -0
  33. package/src/components/astro/RLAResizable.astro +177 -0
  34. package/src/components/astro/RLAScrollArea.astro +157 -0
  35. package/src/components/astro/RLASelect.astro +109 -0
  36. package/src/components/astro/RLASeparator.astro +27 -0
  37. package/src/components/astro/RLASheet.astro +72 -0
  38. package/src/components/astro/RLASidebar.astro +135 -0
  39. package/src/components/astro/RLASkeleton.astro +20 -0
  40. package/src/components/astro/RLASlider.astro +53 -0
  41. package/src/components/astro/RLASpinner.astro +25 -0
  42. package/src/components/astro/RLAStickySurface.astro +27 -0
  43. package/src/components/astro/RLASwitch.astro +49 -0
  44. package/src/components/astro/RLATable.astro +60 -0
  45. package/src/components/astro/RLATabs.astro +92 -0
  46. package/src/components/astro/RLATextarea.astro +42 -0
  47. package/src/components/astro/RLAThemeSelector.astro +73 -0
  48. package/src/components/astro/RLAToast.astro +107 -0
  49. package/src/components/astro/RLAToggle.astro +38 -0
  50. package/src/components/astro/RLAToggleGroup.astro +30 -0
  51. package/src/components/astro/RLATooltip.astro +31 -0
  52. package/src/integrations/ui.ts +1 -0
  53. package/src/themes/alert.theme.ts +51 -0
  54. package/src/themes/alertDialog.theme.ts +33 -0
  55. package/src/themes/aspectRatio.theme.ts +11 -0
  56. package/src/themes/avatar.theme.ts +28 -0
  57. package/src/themes/avatarGroup.theme.ts +10 -0
  58. package/src/themes/badge.theme.ts +61 -0
  59. package/src/themes/breadcrumb.theme.ts +15 -0
  60. package/src/themes/card.theme.ts +34 -0
  61. package/src/themes/carousel.theme.ts +32 -0
  62. package/src/themes/chart.theme.ts +21 -0
  63. package/src/themes/checkbox.theme.ts +42 -0
  64. package/src/themes/collapsible.theme.ts +22 -0
  65. package/src/themes/combobox.theme.ts +28 -0
  66. package/src/themes/dialog.theme.ts +37 -0
  67. package/src/themes/drawer.theme.ts +44 -0
  68. package/src/themes/dropdownMenu.theme.ts +27 -0
  69. package/src/themes/dropzone.theme.ts +24 -0
  70. package/src/themes/field.theme.ts +24 -0
  71. package/src/themes/hoverCard.theme.ts +27 -0
  72. package/src/themes/input.theme.ts +36 -0
  73. package/src/themes/inputGroup.theme.ts +23 -0
  74. package/src/themes/kbd.theme.ts +24 -0
  75. package/src/themes/label.theme.ts +20 -0
  76. package/src/themes/localeSelector.theme.ts +50 -0
  77. package/src/themes/marquee.theme.ts +27 -0
  78. package/src/themes/nativeSelect.theme.ts +24 -0
  79. package/src/themes/navigationMenu.theme.ts +19 -0
  80. package/src/themes/pagination.theme.ts +26 -0
  81. package/src/themes/popover.theme.ts +28 -0
  82. package/src/themes/progress.theme.ts +26 -0
  83. package/src/themes/resizable.theme.ts +22 -0
  84. package/src/themes/scrollArea.theme.ts +24 -0
  85. package/src/themes/section.theme.ts +1 -2
  86. package/src/themes/select.theme.ts +27 -0
  87. package/src/themes/separator.theme.ts +19 -0
  88. package/src/themes/sheet.theme.ts +43 -0
  89. package/src/themes/sidebar.theme.ts +33 -0
  90. package/src/themes/skeleton.theme.ts +20 -0
  91. package/src/themes/slider.theme.ts +28 -0
  92. package/src/themes/spinner.theme.ts +30 -0
  93. package/src/themes/stickySurface.theme.ts +10 -0
  94. package/src/themes/switch.theme.ts +59 -0
  95. package/src/themes/table.theme.ts +36 -0
  96. package/src/themes/tabs.theme.ts +44 -0
  97. package/src/themes/textarea.theme.ts +26 -0
  98. package/src/themes/themeSelector.theme.ts +16 -0
  99. package/src/themes/toast.theme.ts +25 -0
  100. package/src/themes/toggle.theme.ts +42 -0
  101. package/src/themes/toggleGroup.theme.ts +21 -0
  102. package/src/themes/tooltip.theme.ts +27 -0
  103. package/src/types/components/alert-dialog.ts +35 -0
  104. package/src/types/components/alert.ts +31 -0
  105. package/src/types/components/aspect-ratio.ts +15 -0
  106. package/src/types/components/avatar.ts +47 -0
  107. package/src/types/components/badge.ts +27 -0
  108. package/src/types/components/breadcrumb.ts +24 -0
  109. package/src/types/components/card.ts +31 -0
  110. package/src/types/components/carousel.ts +25 -0
  111. package/src/types/components/chart.ts +38 -0
  112. package/src/types/components/checkbox.ts +35 -0
  113. package/src/types/components/collapsible.ts +31 -0
  114. package/src/types/components/combobox.ts +43 -0
  115. package/src/types/components/dialog.ts +39 -0
  116. package/src/types/components/drawer.ts +31 -0
  117. package/src/types/components/dropdown-menu.ts +42 -0
  118. package/src/types/components/dropzone.ts +39 -0
  119. package/src/types/components/field.ts +31 -0
  120. package/src/types/components/hover-card.ts +19 -0
  121. package/src/types/components/index.ts +47 -0
  122. package/src/types/components/input-group.ts +23 -0
  123. package/src/types/components/input.ts +59 -0
  124. package/src/types/components/kbd.ts +15 -0
  125. package/src/types/components/label.ts +19 -0
  126. package/src/types/components/localeSelector.ts +33 -0
  127. package/src/types/components/marquee.ts +23 -0
  128. package/src/types/components/native-select.ts +39 -0
  129. package/src/types/components/navigation-menu.ts +27 -0
  130. package/src/types/components/pagination.ts +23 -0
  131. package/src/types/components/popover.ts +23 -0
  132. package/src/types/components/progress.ts +27 -0
  133. package/src/types/components/resizable.ts +19 -0
  134. package/src/types/components/scroll-area.ts +23 -0
  135. package/src/types/components/select.ts +43 -0
  136. package/src/types/components/separator.ts +19 -0
  137. package/src/types/components/sheet.ts +31 -0
  138. package/src/types/components/sidebar.ts +36 -0
  139. package/src/types/components/skeleton.ts +15 -0
  140. package/src/types/components/slider.ts +35 -0
  141. package/src/types/components/spinner.ts +19 -0
  142. package/src/types/components/sticky-surface.ts +19 -0
  143. package/src/types/components/switch.ts +35 -0
  144. package/src/types/components/table.ts +31 -0
  145. package/src/types/components/tabs.ts +43 -0
  146. package/src/types/components/textarea.ts +51 -0
  147. package/src/types/components/themeSelector.ts +15 -0
  148. package/src/types/components/toast.ts +35 -0
  149. package/src/types/components/toggle-group.ts +23 -0
  150. package/src/types/components/toggle.ts +27 -0
  151. package/src/types/components/tooltip.ts +23 -0
  152. package/src/components/ThemeToggle.astro +0 -57
@@ -0,0 +1,60 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { TableProps } from "../../types"
5
+ import tableThemeDefault, { createTableTheme } from "../../themes/table.theme"
6
+
7
+ const tableTheme = tableThemeDefault
8
+ const table = scv(tableTheme)
9
+
10
+ const {
11
+ headers = [],
12
+ rows = [],
13
+ striped = false,
14
+ bordered = false,
15
+ hoverable = true,
16
+ ui: uiProp,
17
+ class: className,
18
+ ...rest
19
+ } = Astro.props as TableProps
20
+
21
+ const classes = resolveClasses(table, {
22
+ striped,
23
+ bordered
24
+ }, useUi("table", uiProp), className);
25
+ ---
26
+ <div class={classes.root} data-slot="root">
27
+ <table class={classes.table} data-slot="table" {...rest}>
28
+ {headers.length > 0 && (
29
+ <thead class={classes.thead} data-slot="thead">
30
+ <tr class={classes.tr} data-slot="tr">
31
+ {headers.map(header => {
32
+ const label = typeof header === "string" ? header : header.label
33
+ const cellClass = typeof header === "string" ? "" : (header.class || "")
34
+ return (
35
+ <th class={classes.th + " " + cellClass} data-slot="th">
36
+ {label}
37
+ </th>
38
+ )
39
+ })}
40
+ </tr>
41
+ </thead>
42
+ )}
43
+ <tbody class={classes.tbody} data-slot="tbody">
44
+ <slot>
45
+ {rows.map(row => {
46
+ const cells = Array.isArray(row) ? row : Object.values(row)
47
+ return (
48
+ <tr class={classes.tr} data-slot="tr">
49
+ {cells.map(cell => (
50
+ <td class={classes.td} data-slot="td">
51
+ {cell}
52
+ </td>
53
+ ))}
54
+ </tr>
55
+ )
56
+ })}
57
+ </slot>
58
+ </tbody>
59
+ </table>
60
+ </div>
@@ -0,0 +1,92 @@
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
+ document.querySelectorAll("[data-tabs-container]").forEach(container => {
71
+ const triggers = container.querySelectorAll("[role=tab]");
72
+ const panels = container.querySelectorAll("[role=tabpanel]");
73
+
74
+ triggers.forEach(trigger => {
75
+ trigger.addEventListener("click", () => {
76
+ const targetValue = (trigger as HTMLButtonElement).dataset.value;
77
+
78
+ triggers.forEach(t => {
79
+ t.setAttribute("data-state", t.dataset.value === targetValue ? "active" : "inactive");
80
+ });
81
+
82
+ panels.forEach(panel => {
83
+ if ((panel as HTMLElement).dataset.value === targetValue) {
84
+ panel.classList.remove("hidden");
85
+ } else {
86
+ panel.classList.add("hidden");
87
+ }
88
+ });
89
+ });
90
+ });
91
+ });
92
+ </script>
@@ -0,0 +1,42 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { TextareaProps } from "../../types"
5
+ import textareaThemeDefault, { createTextareaTheme } from "../../themes/textarea.theme"
6
+
7
+ const textareaTheme = textareaThemeDefault
8
+ const textarea = scv(textareaTheme)
9
+
10
+ const {
11
+ value = "",
12
+ placeholder,
13
+ disabled = false,
14
+ readonly = false,
15
+ name,
16
+ required = false,
17
+ rows = 4,
18
+ error = false,
19
+ size = "md",
20
+ color = "primary",
21
+ ui: uiProp,
22
+ class: className,
23
+ ...rest
24
+ } = Astro.props as TextareaProps
25
+
26
+ const classes = resolveClasses(textarea, {
27
+ size,
28
+ error: !!error
29
+ }, useUi("textarea", uiProp), className);
30
+ ---
31
+ <div class={classes.root} data-slot="root">
32
+ <textarea
33
+ class={classes.textarea}
34
+ placeholder={placeholder}
35
+ disabled={disabled}
36
+ readonly={readonly}
37
+ name={name}
38
+ required={required}
39
+ rows={rows}
40
+ {...rest}
41
+ >{value}</textarea>
42
+ </div>
@@ -0,0 +1,73 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ThemeSelectorProps } from "../../types"
5
+ import themeSelectorTheme from "../../themes/themeSelector.theme"
6
+ import RLAButton from "./RLAButton.astro"
7
+
8
+ const themeSelector = scv(themeSelectorTheme)
9
+
10
+ const {
11
+ size = "md",
12
+ ui: uiProp,
13
+ class: className,
14
+ ...rest
15
+ } = Astro.props as ThemeSelectorProps
16
+
17
+ const classes = resolveClasses(themeSelector, {
18
+ size
19
+ }, useUi("themeSelector", uiProp), className);
20
+ ---
21
+
22
+ <RLAButton
23
+ size={size}
24
+ class:list={["theme-toggle-button", classes.root]}
25
+ variant="ghost"
26
+ aria-label="Toggle theme"
27
+ {...rest}
28
+ >
29
+ <span class:list={[classes.sun]} />
30
+ <span class:list={[classes.moon]} />
31
+ </RLAButton>
32
+
33
+ <script>
34
+ function applyStoredTheme() {
35
+ const stored = localStorage.getItem('theme');
36
+ if (stored === 'dark') {
37
+ document.documentElement.classList.add('dark');
38
+ } else if (stored === 'light') {
39
+ document.documentElement.classList.remove('dark');
40
+ }
41
+ }
42
+
43
+ function setupThemeToggle() {
44
+ const buttons = document.querySelectorAll('.theme-toggle-button');
45
+
46
+ const updateButtons = (isDark: boolean) => {
47
+ buttons.forEach(btn => {
48
+ btn.setAttribute('data-state', isDark ? 'on' : 'off');
49
+ btn.setAttribute('aria-pressed', isDark.toString());
50
+ });
51
+ };
52
+
53
+ const currentIsDark = document.documentElement.classList.contains('dark');
54
+ updateButtons(currentIsDark);
55
+
56
+ buttons.forEach(button => {
57
+ if (button.hasAttribute('data-initialized')) return;
58
+ button.setAttribute('data-initialized', '');
59
+ button.addEventListener('click', () => {
60
+ const isDark = document.documentElement.classList.toggle('dark');
61
+ localStorage.setItem('theme', isDark ? 'dark' : 'light');
62
+ updateButtons(isDark);
63
+ });
64
+ });
65
+ }
66
+
67
+ applyStoredTheme();
68
+ setupThemeToggle();
69
+ document.addEventListener('astro:page-load', () => {
70
+ applyStoredTheme();
71
+ setupThemeToggle();
72
+ });
73
+ </script>
@@ -0,0 +1,107 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ToastProps } from "../../types"
5
+ import toastThemeDefault, { createToastTheme } from "../../themes/toast.theme"
6
+
7
+ const toastTheme = toastThemeDefault
8
+ const toast = scv(toastTheme)
9
+
10
+ const {
11
+ title,
12
+ description,
13
+ variant = "default",
14
+ actionLabel,
15
+ duration = 5000,
16
+ color = "primary",
17
+ ui: uiProp,
18
+ class: className,
19
+ ...rest
20
+ } = Astro.props as ToastProps
21
+
22
+ const classes = resolveClasses(toast, {
23
+ variant
24
+ }, useUi("toast", uiProp), className)
25
+
26
+ const variantIcons: Record<string, string> = {
27
+ default: "i-lucide-bell",
28
+ destructive: "i-lucide-alert-circle",
29
+ success: "i-lucide-check-circle-2",
30
+ warning: "i-lucide-alert-triangle",
31
+ info: "i-lucide-info",
32
+ }
33
+
34
+ const icon = variantIcons[variant] ?? variantIcons.default!
35
+ ---
36
+
37
+ <div
38
+ class={classes.root}
39
+ data-slot="root"
40
+ data-toast
41
+ data-duration={duration}
42
+ role="alert"
43
+ aria-live="assertive"
44
+ aria-atomic="true"
45
+ {...rest}
46
+ >
47
+ {/* Icon */}
48
+ <span class={icon + " size-4 shrink-0 mt-0.5"} aria-hidden="true" />
49
+
50
+ {/* Text body */}
51
+ <div class="flex flex-col gap-0.5 flex-1 min-w-0">
52
+ {title && (
53
+ <div class={classes.title} data-slot="title">
54
+ <slot name="title">{title}</slot>
55
+ </div>
56
+ )}
57
+ {description && (
58
+ <div class={classes.description} data-slot="description">
59
+ <slot name="description">{description}</slot>
60
+ </div>
61
+ )}
62
+ <slot />
63
+ </div>
64
+
65
+ {/* Action */}
66
+ {actionLabel && (
67
+ <button
68
+ type="button"
69
+ class={classes.action}
70
+ data-slot="action"
71
+ data-toast-action
72
+ >
73
+ {actionLabel}
74
+ </button>
75
+ )}
76
+
77
+ {/* Close button */}
78
+ <button
79
+ type="button"
80
+ class={classes.close}
81
+ data-slot="close"
82
+ data-toast-close
83
+ aria-label="Dismiss notification"
84
+ >
85
+ <span class="i-lucide-x size-3.5" aria-hidden="true" />
86
+ </button>
87
+ </div>
88
+
89
+ <script>
90
+ document.querySelectorAll("[data-toast]").forEach(toast => {
91
+ const close = toast.querySelector("[data-toast-close]");
92
+ const duration = parseInt((toast as HTMLElement).dataset.duration ?? "5000", 10);
93
+
94
+ const dismiss = () => {
95
+ toast.classList.add("opacity-0", "translate-y-2", "pointer-events-none");
96
+ toast.addEventListener("transitionend", () => toast.remove(), { once: true });
97
+ };
98
+
99
+ // Auto-dismiss
100
+ if (duration > 0) {
101
+ setTimeout(dismiss, duration);
102
+ }
103
+
104
+ // Manual close
105
+ close?.addEventListener("click", dismiss);
106
+ });
107
+ </script>
@@ -0,0 +1,38 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ToggleProps } from "../../types"
5
+ import toggleThemeDefault, { createToggleTheme } from "../../themes/toggle.theme"
6
+ import { getUIConfig } from "virtual:rimelight-ui"
7
+
8
+ const uiConfig = getUIConfig()
9
+ const toggleTheme = uiConfig.colors ? createToggleTheme(uiConfig.colors) : toggleThemeDefault
10
+
11
+ const toggle = scv(toggleTheme)
12
+
13
+ const {
14
+ active = false,
15
+ disabled = false,
16
+ color = "primary",
17
+ size = "md",
18
+ ui: uiProp,
19
+ class: className,
20
+ ...rest
21
+ } = Astro.props as ToggleProps
22
+
23
+ const classes = resolveClasses(toggle, {
24
+ color,
25
+ size,
26
+ active
27
+ }, useUi("toggle", uiProp), className);
28
+ ---
29
+ <button
30
+ type="button"
31
+ class={classes.root}
32
+ data-slot="root"
33
+ data-state={active ? "on" : "off"}
34
+ disabled={disabled}
35
+ {...rest}
36
+ >
37
+ <slot />
38
+ </button>
@@ -0,0 +1,30 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ToggleGroupProps } from "../../types"
5
+ import toggleGroupThemeDefault, { createToggleGroupTheme } from "../../themes/toggleGroup.theme"
6
+
7
+ const toggleGroupTheme = toggleGroupThemeDefault
8
+ const toggleGroup = scv(toggleGroupTheme)
9
+
10
+ const {
11
+ value = [],
12
+ type = "single",
13
+ size = "md",
14
+ ui: uiProp,
15
+ class: className,
16
+ ...rest
17
+ } = Astro.props as ToggleGroupProps
18
+
19
+ const classes = resolveClasses(toggleGroup, {
20
+ size
21
+ }, useUi("toggleGroup", uiProp), className);
22
+ ---
23
+ <div
24
+ class={classes.root}
25
+ data-slot="root"
26
+ data-type={type}
27
+ {...rest}
28
+ >
29
+ <slot />
30
+ </div>
@@ -0,0 +1,31 @@
1
+ ---
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { TooltipProps } from "../../types"
5
+ import tooltipTheme from "../../themes/tooltip.theme"
6
+
7
+ const tooltip = scv(tooltipTheme)
8
+
9
+ const {
10
+ content,
11
+ placement = "top",
12
+ ui: uiProp,
13
+ class: className,
14
+ ...rest
15
+ } = Astro.props as TooltipProps
16
+
17
+ const classes = resolveClasses(tooltip, {
18
+ placement
19
+ }, useUi("tooltip", uiProp), className)
20
+ ---
21
+ <div class={classes.root} data-slot="tooltip-container" {...rest}>
22
+ <div class={classes.trigger} data-slot="trigger" tabindex="0">
23
+ <slot />
24
+ </div>
25
+
26
+ <div class={classes.content} data-slot="content" role="tooltip">
27
+ <slot name="content">
28
+ {content}
29
+ </slot>
30
+ </div>
31
+ </div>
@@ -100,6 +100,7 @@ export function ui(options: UIOptions = {}): AstroIntegration[] {
100
100
  plugins: [
101
101
  uiPlugin({
102
102
  router: false,
103
+ colorMode: false,
103
104
  scanPackages: ["@rimelight/ui"]
104
105
  }),
105
106
  tailwindcss(),
@@ -0,0 +1,51 @@
1
+ import { defineTheme } from "../utils/defineTheme"
2
+
3
+ const defaultColors = ["primary", "secondary", "info", "success", "warning", "error"]
4
+
5
+ export const createAlertTheme = (colors: string[] = defaultColors) =>
6
+ defineTheme({
7
+ slots: ["root", "icon", "content", "title", "description"],
8
+ base: {
9
+ root: "relative w-full rounded-lg border p-4 flex gap-3 text-sm transition-all shadow-sm",
10
+ icon: "shrink-0 size-5 text-current",
11
+ content: "flex flex-col gap-1 w-full",
12
+ title: "font-semibold leading-none tracking-tight text-foreground",
13
+ description: "text-xs opacity-90 leading-relaxed"
14
+ },
15
+ variants: {
16
+ variant: {
17
+ default: { root: "bg-background text-foreground border-border" },
18
+ destructive: { root: "bg-error-500/10 text-error-700 border-error-500/20 dark:text-error-400" },
19
+ outline: { root: "border bg-transparent" },
20
+ solid: { root: "border-transparent text-white" }
21
+ },
22
+ color: Object.fromEntries(colors.map((color) => [color, { root: "" }])),
23
+ hasIcon: {
24
+ true: { icon: "block" },
25
+ false: { icon: "hidden" }
26
+ }
27
+ },
28
+ compoundVariants: [
29
+ ...colors.map((color) => ({
30
+ variant: "solid" as const,
31
+ color,
32
+ classNames: {
33
+ root: `bg-${color}-500 text-white border-transparent`
34
+ }
35
+ })),
36
+ ...colors.map((color) => ({
37
+ variant: "outline" as const,
38
+ color,
39
+ classNames: {
40
+ root: `border-${color}-500/20 text-${color}-600 bg-${color}-500/5`
41
+ }
42
+ }))
43
+ ],
44
+ defaultVariants: {
45
+ variant: "default",
46
+ color: "primary",
47
+ hasIcon: false
48
+ }
49
+ })
50
+
51
+ export default createAlertTheme()
@@ -0,0 +1,33 @@
1
+ import { defineTheme } from "../utils/defineTheme"
2
+
3
+ export const alertDialogTheme = defineTheme({
4
+ slots: ["root", "trigger", "backdrop", "content", "header", "title", "description", "footer", "cancelButton", "actionButton"],
5
+ base: {
6
+ root: "relative inline-block",
7
+ trigger: "",
8
+ backdrop: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm transition-all duration-300",
9
+ content: [
10
+ "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-xl border border-border",
11
+ "bg-background p-6 shadow-xl transition-all duration-300 outline-none",
12
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-1/2",
13
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-1/2"
14
+ ],
15
+ header: "flex flex-col gap-1.5 text-center sm:text-left mb-4",
16
+ title: "text-lg font-semibold leading-none tracking-tight text-foreground",
17
+ description: "text-sm text-muted-foreground leading-relaxed",
18
+ footer: "flex flex-col-reverse sm:flex-row sm:justify-end gap-2 mt-6",
19
+ cancelButton: "w-full sm:w-auto",
20
+ actionButton: "w-full sm:w-auto"
21
+ },
22
+ variants: {
23
+ variant: {
24
+ default: { actionButton: "" },
25
+ destructive: { actionButton: "bg-error-500 hover:bg-error-600 focus-visible:ring-error-500/50" }
26
+ }
27
+ },
28
+ defaultVariants: {
29
+ variant: "default"
30
+ }
31
+ })
32
+
33
+ export default alertDialogTheme
@@ -0,0 +1,11 @@
1
+ import { defineTheme } from "../utils/defineTheme"
2
+
3
+ export const aspectRatioTheme = defineTheme({
4
+ slots: ["root", "content"],
5
+ base: {
6
+ root: "relative w-full overflow-hidden",
7
+ content: "absolute inset-0 h-full w-full object-cover"
8
+ }
9
+ })
10
+
11
+ export default aspectRatioTheme
@@ -0,0 +1,28 @@
1
+ import { defineTheme } from "../utils/defineTheme"
2
+
3
+ export const avatarTheme = defineTheme({
4
+ slots: ["root", "image", "fallback", "badge"],
5
+ base: {
6
+ root: "relative flex shrink-0 overflow-hidden rounded-full select-none",
7
+ image: "aspect-square h-full w-full object-cover",
8
+ fallback: "flex h-full w-full items-center justify-center rounded-full bg-muted font-semibold text-muted-foreground uppercase",
9
+ badge: "absolute bottom-0 right-0 block size-2.5 rounded-full ring-2 ring-background"
10
+ },
11
+ variants: {
12
+ size: {
13
+ sm: { root: "size-8", fallback: "text-xs" },
14
+ md: { root: "size-10", fallback: "text-sm" },
15
+ lg: { root: "size-12", fallback: "text-base" }
16
+ },
17
+ hasBadge: {
18
+ true: { badge: "block" },
19
+ false: { badge: "hidden" }
20
+ }
21
+ },
22
+ defaultVariants: {
23
+ size: "md",
24
+ hasBadge: false
25
+ }
26
+ })
27
+
28
+ export default avatarTheme
@@ -0,0 +1,10 @@
1
+ import { defineTheme } from "../utils/defineTheme"
2
+
3
+ export const avatarGroupTheme = defineTheme({
4
+ slots: ["root"],
5
+ base: {
6
+ root: "flex -space-x-3 hover:space-x-0 transition-all duration-300 [&_[data-slot=root]]:ring-2 [&_[data-slot=root]]:ring-background [&_[data-slot=root]]:transition-all"
7
+ }
8
+ })
9
+
10
+ export default avatarGroupTheme
@@ -0,0 +1,61 @@
1
+ import { defineTheme } from "../utils/defineTheme"
2
+
3
+ const defaultColors = ["primary", "secondary", "info", "success", "warning", "error"]
4
+
5
+ export const createBadgeTheme = (colors: string[] = defaultColors) =>
6
+ defineTheme({
7
+ slots: ["root"],
8
+ base: {
9
+ root: "inline-flex items-center gap-1.5 font-medium select-none overflow-hidden transition-all duration-150"
10
+ },
11
+ variants: {
12
+ variant: {
13
+ solid: { root: "border border-transparent text-white" },
14
+ outline: { root: "border" },
15
+ soft: { root: "border border-transparent" },
16
+ ghost: { root: "bg-transparent hover:bg-muted" }
17
+ },
18
+ color: Object.fromEntries(colors.map((color) => [color, { root: "" }])),
19
+ size: {
20
+ sm: { root: "px-2 py-0.5 text-2xs rounded-full h-5" },
21
+ md: { root: "px-2.5 py-0.5 text-xs rounded-full h-6" },
22
+ lg: { root: "px-3 py-1 text-sm rounded-full h-7" }
23
+ },
24
+ shape: {
25
+ square: { root: "rounded-sm" },
26
+ rounded: { root: "rounded-md" },
27
+ pill: { root: "rounded-full" }
28
+ }
29
+ },
30
+ compoundVariants: [
31
+ ...colors.map((color) => ({
32
+ variant: "solid" as const,
33
+ color,
34
+ classNames: {
35
+ root: `bg-${color}-500 text-white hover:bg-${color}-600`
36
+ }
37
+ })),
38
+ ...colors.map((color) => ({
39
+ variant: "outline" as const,
40
+ color,
41
+ classNames: {
42
+ root: `border-${color}-500/20 text-${color}-600 bg-transparent hover:bg-${color}-500/5`
43
+ }
44
+ })),
45
+ ...colors.map((color) => ({
46
+ variant: "soft" as const,
47
+ color,
48
+ classNames: {
49
+ root: `text-${color}-600 bg-${color}-500/10 hover:bg-${color}-500/20`
50
+ }
51
+ }))
52
+ ],
53
+ defaultVariants: {
54
+ variant: "solid",
55
+ color: "primary",
56
+ size: "md",
57
+ shape: "pill"
58
+ }
59
+ })
60
+
61
+ export default createBadgeTheme()