@rimelight/ui 0.0.24 → 0.0.25

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 (64) hide show
  1. package/package.json +7 -3
  2. package/src/components/Head.astro +199 -156
  3. package/src/components/astro/RLAAccordion.astro +22 -0
  4. package/src/components/astro/RLAButton.astro +104 -118
  5. package/src/components/astro/RLAFooter.astro +14 -40
  6. package/src/components/astro/RLAHeader.astro +18 -78
  7. package/src/components/astro/RLAIcon.astro +11 -36
  8. package/src/components/astro/RLALogo.astro +9 -44
  9. package/src/components/astro/RLAPlaceholder.astro +8 -33
  10. package/src/components/astro/RLAQuote.astro +15 -0
  11. package/src/components/astro/RLAScrollToTop.astro +171 -221
  12. package/src/components/astro/RLASection.astro +181 -0
  13. package/src/components/vue/RLVButton.vue +172 -139
  14. package/src/components/vue/RLVFooter.vue +12 -49
  15. package/src/components/vue/RLVHeader.vue +15 -98
  16. package/src/components/vue/RLVIcon.vue +11 -37
  17. package/src/components/vue/RLVLogo.vue +8 -56
  18. package/src/components/vue/RLVPlaceholder.vue +11 -33
  19. package/src/components/vue/RLVScrollToTop.vue +17 -88
  20. package/src/components/vue/RLVSection.vue +98 -0
  21. package/src/composables/index.ts +0 -1
  22. package/src/env.d.ts +5 -0
  23. package/src/integrations/ui.ts +2 -6
  24. package/src/plugins/index.ts +5 -2
  25. package/src/plugins/starlightAddons/index.ts +3 -64
  26. package/src/plugins/starlightDocsApi/components/ApiEmits.astro +46 -0
  27. package/src/plugins/starlightDocsApi/components/ApiProps.astro +47 -0
  28. package/src/plugins/starlightDocsApi/components/ApiSlots.astro +50 -0
  29. package/src/plugins/starlightDocsApi/components/ApiTheme.astro +27 -0
  30. package/src/plugins/starlightDocsApi/extract-vue.ts +286 -0
  31. package/src/plugins/starlightDocsApi/index.ts +265 -0
  32. package/src/plugins/starlightDocsApi/types.ts +40 -0
  33. package/src/plugins/starlightDocsApi/utils.ts +45 -0
  34. package/src/themes/button.theme.ts +29 -14
  35. package/src/themes/footer.theme.ts +4 -6
  36. package/src/themes/header.theme.ts +4 -28
  37. package/src/themes/icon.theme.ts +4 -2
  38. package/src/themes/index.ts +15 -20
  39. package/src/themes/logo.theme.ts +4 -2
  40. package/src/themes/placeholder.theme.ts +4 -6
  41. package/src/themes/scroll-to-top.theme.ts +4 -6
  42. package/src/themes/section.theme.ts +185 -0
  43. package/src/types/componentVariant.ts +10 -0
  44. package/src/types/index.ts +1 -0
  45. package/src/utils/defineTheme.ts +11 -0
  46. package/src/utils/index.ts +3 -0
  47. package/src/utils/resolveClasses.ts +21 -0
  48. package/src/utils/useUi.ts +19 -0
  49. package/src/composables/useUi.ts +0 -27
  50. package/src/plugins/starlightAddons/Sidebar.astro +0 -89
  51. package/src/plugins/starlightAddons/data.ts +0 -39
  52. package/src/plugins/starlightAddons/libs/config.ts +0 -107
  53. package/src/plugins/starlightAddons/libs/content.ts +0 -20
  54. package/src/plugins/starlightAddons/libs/i18n.ts +0 -51
  55. package/src/plugins/starlightAddons/libs/locals.ts +0 -12
  56. package/src/plugins/starlightAddons/libs/pathname.ts +0 -22
  57. package/src/plugins/starlightAddons/libs/plugin.ts +0 -9
  58. package/src/plugins/starlightAddons/libs/sidebar.ts +0 -183
  59. package/src/plugins/starlightAddons/libs/vite.ts +0 -46
  60. package/src/plugins/starlightAddons/locals.d.ts +0 -14
  61. package/src/plugins/starlightAddons/middleware.ts +0 -132
  62. package/src/plugins/starlightAddons/overrides/Sidebar.astro +0 -8
  63. package/src/plugins/starlightAddons/schema.ts +0 -13
  64. package/src/plugins/starlightAddons/virtual.d.ts +0 -13
@@ -1,35 +1,16 @@
1
1
  ---
2
- import { scv, cx } from "css-variants";
3
- import { twMerge } from "tailwind-merge";
4
- import defu from "defu";
5
- import { footerTheme } from "../../themes/footer.theme.ts";
6
- import { getUIConfig } from "virtual:rimelight-ui";
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ComponentVariants } from "../../types"
5
+ import footerTheme from "../../themes/footer.theme"
7
6
 
8
- const footer = scv({
9
- slots: [...footerTheme.slots],
10
- base: footerTheme.base,
11
- variants: footerTheme.variants,
12
- defaultVariants: footerTheme.defaultVariants,
13
- classNameResolver: (...args) => twMerge(cx(...args)),
14
- });
7
+ const footer = scv(footerTheme)
8
+ type FooterVariants = ComponentVariants<typeof footerTheme>
15
9
 
16
10
  export interface RLAFooterProps {
17
- /**
18
- * Whether to contain the footer content in a max-width container.
19
- * @default false
20
- */
21
- contain?: boolean;
22
- /**
23
- * UI overrides for individual slots, derived from the footer theme.
24
- */
25
- ui?: Partial<Record<keyof typeof footerTheme.base, string>>;
26
- /**
27
- * External class — applied to the root element.
28
- */
11
+ contain?: FooterVariants['contain'];
12
+ ui?: Partial<Record<string, string>>;
29
13
  class?: string;
30
- /**
31
- * Standard HTML attributes for <footer>
32
- */
33
14
  [key: string]: unknown;
34
15
  }
35
16
 
@@ -40,29 +21,22 @@ const {
40
21
  ...rest
41
22
  } = Astro.props as RLAFooterProps
42
23
 
43
- const globalConfig = getUIConfig();
44
-
45
- const mergedUI = defu(
46
- uiProp ?? {},
47
- (globalConfig.footer as Record<string, unknown>) ?? {},
48
- ) as Record<keyof typeof footerTheme.base, string | undefined>;
49
-
50
- const { root, container, left, center, right } = footer({ contain });
24
+ const classes = resolveClasses(footer, { contain }, useUi("footer", uiProp), className)
51
25
  ---
52
26
 
53
27
  <footer
54
- class:list={[twMerge(root, mergedUI.root, className)]}
28
+ class:list={[classes.root]}
55
29
  data-slot="rla-footer"
56
30
  {...rest}
57
31
  >
58
- <div class:list={[twMerge(container, mergedUI.container)]}>
59
- <div class:list={[twMerge(left, mergedUI.left)]} data-slot="footer-left">
32
+ <div class:list={[classes.container]}>
33
+ <div class:list={[classes.left]} data-slot="footer-left">
60
34
  <slot name="left" />
61
35
  </div>
62
- <div class:list={[twMerge(center, mergedUI.center)]} data-slot="footer-center">
36
+ <div class:list={[classes.center]} data-slot="footer-center">
63
37
  <slot name="center" />
64
38
  </div>
65
- <div class:list={[twMerge(right, mergedUI.right)]} data-slot="footer-right">
39
+ <div class:list={[classes.right]} data-slot="footer-right">
66
40
  <slot name="right" />
67
41
  </div>
68
42
  </div>
@@ -1,59 +1,20 @@
1
1
  ---
2
- import { scv, cx } from "css-variants";
3
- import { twMerge } from "tailwind-merge";
4
- import defu from "defu";
5
- import { headerTheme } from "../../themes/header.theme.ts";
6
- import { getUIConfig } from "virtual:rimelight-ui";
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ComponentVariants } from "../../types"
5
+ import headerTheme from "../../themes/header.theme"
7
6
 
8
- const header = scv({
9
- slots: [...headerTheme.slots],
10
- base: headerTheme.base,
11
- variants: headerTheme.variants,
12
- defaultVariants: headerTheme.defaultVariants,
13
- classNameResolver: (...args) => twMerge(cx(...args)),
14
- });
7
+ const header = scv(headerTheme)
8
+ type HeaderVariants = ComponentVariants<typeof headerTheme>
15
9
 
16
10
  export interface RLAHeaderProps {
17
- /**
18
- * Whether to contain the header content in a max-width container.
19
- * @default true
20
- */
21
- contain?: boolean;
22
- /**
23
- * Sticky positioning when `fixed` is false.
24
- * @default true
25
- */
26
- sticky?: boolean;
27
- /**
28
- * Switches to `position: fixed; left: 0; right: 0` (layer mode).
29
- * When true, `stackIndex` controls the exact position and layer order.
30
- * A module `<script>` is emitted to apply styles and attach scroll listeners.
31
- * @default false
32
- */
33
- fixed?: boolean;
34
- /**
35
- * Controls z-index when `fixed` is true: `z-index = 100 - stackIndex`.
36
- * @default 0
37
- */
11
+ contain?: HeaderVariants['contain'];
12
+ sticky?: HeaderVariants['sticky'];
13
+ fixed?: HeaderVariants['fixed'];
38
14
  stackIndex?: number;
39
- /**
40
- * When true, hides the header on scroll-down and shows it on scroll-up.
41
- * Implemented via a bundled Astro `<script>` — no Vue hydration needed.
42
- * Only meaningful when `fixed` is true.
43
- * @default false
44
- */
45
15
  hideOnScroll?: boolean;
46
- /**
47
- * UI overrides for individual slots, derived from the header theme.
48
- */
49
- ui?: Partial<Record<keyof typeof headerTheme.base, string>>;
50
- /**
51
- * External class — applied to the root element.
52
- */
16
+ ui?: Partial<Record<string, string>>;
53
17
  class?: string;
54
- /**
55
- * Standard HTML attributes for <header>.
56
- */
57
18
  [key: string]: unknown;
58
19
  }
59
20
 
@@ -68,69 +29,48 @@ const {
68
29
  ...rest
69
30
  } = Astro.props as RLAHeaderProps;
70
31
 
71
- const globalConfig = getUIConfig();
72
-
73
- const mergedUI = defu(
74
- uiProp ?? {},
75
- (globalConfig.header as Record<string, unknown>) ?? {},
76
- ) as Record<keyof typeof headerTheme.base, string | undefined>;
77
-
78
- // Resolve classes — note: sticky variant is suppressed when fixed is true,
79
- // since the fixed variant's classes replace it.
80
- const { root, content, container, left, center, right } = header({
32
+ const classes = resolveClasses(header, {
81
33
  contain,
82
34
  sticky: fixed ? false : sticky,
83
35
  fixed,
84
- });
36
+ }, useUi("header", uiProp), className);
85
37
 
86
- // Build a unique ID so the script can target this specific header element.
87
38
  const headerId = `rla-header-${Math.random().toString(36).slice(2, 8)}`;
88
39
  const zIndex = 100 - stackIndex;
89
40
  ---
90
41
 
91
42
  <header
92
43
  id={headerId}
93
- class:list={[twMerge(root, mergedUI.root, className)]}
44
+ class:list={[classes.root]}
94
45
  data-rla-header={fixed ? "true" : undefined}
95
46
  data-stack-index={stackIndex}
96
47
  data-hide-on-scroll={String(hideOnScroll)}
97
48
  style={fixed ? `z-index: ${zIndex};` : undefined}
98
49
  {...rest}
99
50
  >
100
- <!--
101
- content wrapper: present in all modes; in fixed+hideOnScroll mode the inline
102
- script observes this element's offsetHeight for accurate measurement.
103
- -->
104
- <div class:list={[twMerge(content, mergedUI.content)]} data-header-content>
105
- <div class:list={[twMerge(container, mergedUI.container)]}>
106
- <div class:list={[twMerge(left, mergedUI.left)]} data-slot="header-left">
51
+ <div class:list={[classes.content]} data-header-content>
52
+ <div class:list={[classes.container]}>
53
+ <div class:list={[classes.left]} data-slot="header-left">
107
54
  <slot name="left" />
108
55
  </div>
109
- <div class:list={[twMerge(center, mergedUI.center)]} data-slot="header-center">
56
+ <div class:list={[classes.center]} data-slot="header-center">
110
57
  <slot name="center" />
111
58
  </div>
112
- <div class:list={[twMerge(right, mergedUI.right)]} data-slot="header-right">
59
+ <div class:list={[classes.right]} data-slot="header-right">
113
60
  <slot name="right" />
114
61
  </div>
115
62
  </div>
116
63
  </div>
117
64
  </header>
118
65
 
119
- {/*
120
- Astro Module Script — automatically hydrates all static Astro headers
121
- with the global Vanilla JS stack manager. It only executes once per page
122
- load, managing all headers efficiently.
123
- */}
124
66
  {fixed && (
125
67
  <script>
126
68
  import { getHeaderStack } from "../../utils/headerStack";
127
69
 
128
- // This script runs exactly once per page load, managing all Astro headers
129
70
  const stack = getHeaderStack();
130
71
  const headers = document.querySelectorAll("[data-rla-header='true']");
131
72
 
132
73
  headers.forEach(header => {
133
- // Prevent double-initialization
134
74
  if ((header as any)._rl_initialized) return;
135
75
  (header as any)._rl_initialized = true;
136
76
 
@@ -1,36 +1,17 @@
1
1
  ---
2
- import { scv, cx } from "css-variants"
3
- import { twMerge } from "tailwind-merge"
4
- import defu from "defu"
5
- import { iconTheme } from "../../themes/icon.theme"
6
- import { getUIConfig } from "virtual:rimelight-ui"
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import type { ComponentVariants } from "../../types"
5
+ import iconTheme from "../../themes/icon.theme"
7
6
 
8
- const icon = scv({
9
- slots: [...iconTheme.slots],
10
- base: iconTheme.base,
11
- variants: iconTheme.variants,
12
- defaultVariants: iconTheme.defaultVariants,
13
- classNameResolver: (...args) => twMerge(cx(...args))
14
- })
7
+ const icon = scv(iconTheme)
8
+ type IconVariants = ComponentVariants<typeof iconTheme>
15
9
 
16
10
  export interface RLAIconProps {
17
- /**
18
- * Icon name following the UnoCSS icons format.
19
- * @example "i-lucide-home"
20
- */
21
11
  name: string
22
- /**
23
- * Size variant for the icon.
24
- */
25
- size?: keyof typeof iconTheme.variants.size
26
- /**
27
- * External class applied to the root element.
28
- */
12
+ size?: IconVariants['size']
29
13
  class?: string
30
- /**
31
- * UI overrides for individual slots.
32
- */
33
- ui?: Partial<Record<keyof typeof iconTheme.base, string>>
14
+ ui?: Partial<Record<string, string>>
34
15
  [key: string]: unknown
35
16
  }
36
17
 
@@ -42,20 +23,14 @@ const {
42
23
  ...rest
43
24
  } = Astro.props as RLAIconProps
44
25
 
45
- const globalConfig = getUIConfig()
46
-
47
- const mergedUI = defu(
48
- uiProp ?? {},
49
- (globalConfig.icon as Record<string, unknown>) ?? {}
50
- ) as Record<keyof typeof iconTheme.base, string | undefined>
51
-
52
- const { root } = icon({ size })
26
+ const classes = resolveClasses(icon, { size }, useUi("icon", uiProp), className)
53
27
  ---
54
28
 
55
29
  <span
56
- class={twMerge(root, mergedUI.root, className, name)}
30
+ class={classes.root}
57
31
  data-slot="rla-icon"
58
32
  aria-hidden="true"
59
33
  {...rest}
60
34
  >
35
+ <span class={name} />
61
36
  </span>
@@ -1,48 +1,18 @@
1
1
  ---
2
- import { scv, cx } from "css-variants"
3
- import { twMerge } from "tailwind-merge"
4
- import defu from "defu"
5
- import { logoTheme } from "../../themes/logo.theme.ts"
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import logoTheme from "../../themes/logo.theme"
6
5
  import { getUIConfig } from "virtual:rimelight-ui"
7
6
 
8
- const logo = scv({
9
- slots: [...logoTheme.slots],
10
- base: logoTheme.base,
11
- variants: logoTheme.variants,
12
- defaultVariants: logoTheme.defaultVariants,
13
- classNameResolver: (...args) => twMerge(cx(...args)),
14
- });
7
+ const logo = scv(logoTheme)
15
8
 
16
9
  export interface RLALogoProps {
17
- /**
18
- * The variant of the logo to display.
19
- * @default "logomark"
20
- */
21
10
  variant?: string;
22
- /**
23
- * Override the color mode.
24
- */
25
11
  mode?: "color" | "white" | "black";
26
- /**
27
- * The URL to link to.
28
- * @default "/"
29
- */
30
12
  href?: string;
31
- /**
32
- * UI overrides for individual slots, derived from the logo theme.
33
- */
34
- ui?: Partial<Record<keyof typeof logoTheme.base, string>>;
35
- /**
36
- * External class — applied to the root element.
37
- */
13
+ ui?: Partial<Record<string, string>>;
38
14
  class?: string;
39
- /**
40
- * The alt text for the logo image.
41
- */
42
15
  alt?: string;
43
- /**
44
- * Standard HTML attributes for <a>
45
- */
46
16
  [key: string]: unknown;
47
17
  }
48
18
 
@@ -56,16 +26,11 @@ const {
56
26
  ...rest
57
27
  } = Astro.props as RLALogoProps;
58
28
 
59
- const globalConfig = getUIConfig();
60
-
61
- const mergedUI = defu(
62
- uiProp ?? {},
63
- (globalConfig.logo as Record<string, unknown>) ?? {},
64
- ) as Record<keyof typeof logoTheme.base, string | undefined>;
65
-
66
- const { root } = logo();
29
+ const classes = resolveClasses(logo, {}, useUi("logo", uiProp), className);
67
30
 
31
+ const globalConfig = getUIConfig();
68
32
  const rcLogos = globalConfig.logos as Record<string, any>;
33
+
69
34
  let logoSrc: string | null = null;
70
35
 
71
36
  if (rcLogos && typeof rcLogos === "object") {
@@ -82,7 +47,7 @@ const isIcon = logoSrc && (logoSrc.includes(":") || logoSrc.startsWith("i-"));
82
47
  ---
83
48
 
84
49
  <a
85
- class={twMerge(root, mergedUI.root, className)}
50
+ class={classes.root}
86
51
  href={href}
87
52
  aria-label={alt || variant}
88
53
  data-slot="rla-logo"
@@ -1,31 +1,13 @@
1
1
  ---
2
- import { scv, cx } from "css-variants"
3
- import { twMerge } from "tailwind-merge"
4
- import defu from "defu"
5
- import { placeholderTheme } from "../../themes/placeholder.theme.ts"
6
- import { getUIConfig } from "virtual:rimelight-ui"
2
+ import { scv } from "css-variants"
3
+ import { useUi, resolveClasses } from "../../utils"
4
+ import placeholderTheme from "../../themes/placeholder.theme"
7
5
 
8
- const placeholder = scv({
9
- slots: [...placeholderTheme.slots],
10
- base: placeholderTheme.base,
11
- variants: placeholderTheme.variants,
12
- compoundVariants: [...placeholderTheme.compoundVariants],
13
- defaultVariants: placeholderTheme.defaultVariants,
14
- classNameResolver: (...args) => twMerge(cx(...args))
15
- })
6
+ const placeholder = scv(placeholderTheme)
16
7
 
17
8
  export interface RLAPlaceholderProps {
18
- /**
19
- * UI overrides for individual slots, derived from the placeholder theme.
20
- */
21
- ui?: Partial<Record<keyof typeof placeholderTheme.base, string>>
22
- /**
23
- * External class — applied to the root element.
24
- */
9
+ ui?: Partial<Record<string, string>>
25
10
  class?: string
26
- /**
27
- * Standard HTML attributes.
28
- */
29
11
  [key: string]: unknown
30
12
  }
31
13
 
@@ -35,18 +17,11 @@ const {
35
17
  ...rest
36
18
  } = Astro.props as RLAPlaceholderProps
37
19
 
38
- const globalConfig = getUIConfig()
39
-
40
- const mergedUI = defu(
41
- uiProp ?? {},
42
- (globalConfig.placeholder as Record<string, unknown>) ?? {}
43
- ) as Record<keyof typeof placeholderTheme.base, string | undefined>
44
-
45
- const { base, svg } = placeholder()
20
+ const classes = resolveClasses(placeholder, {}, useUi("placeholder", uiProp), className)
46
21
  ---
47
22
 
48
- <div class={twMerge(base, mergedUI.base, className)} {...rest}>
49
- <svg class={twMerge(svg, mergedUI.svg)}>
23
+ <div class={classes.base} {...rest}>
24
+ <svg class={classes.svg}>
50
25
  <defs>
51
26
  <pattern
52
27
  id="pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e"
@@ -0,0 +1,15 @@
1
+ ---
2
+
3
+ ---
4
+
5
+ <figure class="relative my-8 border-y-[3px] border-astro-gray-500 py-4">
6
+ <span class="i-lucide-quote mb-2 s-10 md:absolute md:right-[calc(100%+1rem)] md:top-6" />
7
+ <blockquote
8
+ class="font-heading heading-3 text-xl font-medium text-white md:text-[32px] md:leading-[40px]"
9
+ >
10
+ <slot name="quote" />
11
+ </blockquote>
12
+ <figcaption class="font-mono mt-4 text-right text-astro-pink-light">
13
+ <slot name="caption" />
14
+ </figcaption>
15
+ </figure>