@rimelight/ui 0.0.21 → 0.0.23
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.
- package/package.json +12 -13
- package/src/components/ThemeToggle.astro +2 -4
- package/src/components/astro/RLAFooter.astro +69 -0
- package/src/components/astro/RLAHeader.astro +178 -75
- package/src/components/astro/RLAIcon.astro +61 -0
- package/src/components/astro/RLALogo.astro +100 -0
- package/src/components/astro/RLAPlaceholder.astro +71 -0
- package/src/components/astro/RLAScrollToTop.astro +61 -15
- package/src/components/vue/RLVFooter.vue +81 -0
- package/src/components/vue/RLVHeader.vue +140 -18
- package/src/components/vue/RLVIcon.vue +64 -0
- package/src/components/vue/RLVLogo.vue +123 -0
- package/src/components/vue/RLVPlaceholder.vue +76 -0
- package/src/components/vue/RLVScrollToTop.vue +214 -154
- package/src/integrations/ui.ts +20 -8
- package/src/plugins/index.ts +2 -2
- package/src/plugins/starlightAddons/index.ts +119 -125
- package/src/presets/index.ts +7 -0
- package/src/styles/index.css +107 -107
- package/src/themes/footer.theme.ts +29 -0
- package/src/themes/header.theme.ts +32 -2
- package/src/themes/icon.theme.ts +18 -0
- package/src/themes/index.ts +12 -4
- package/src/themes/logo.theme.ts +8 -0
- package/src/themes/placeholder.theme.ts +14 -0
- package/src/utils/headerStack.ts +88 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
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"
|
|
7
|
+
|
|
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
|
+
})
|
|
16
|
+
|
|
17
|
+
export interface RLVPlaceholderProps {
|
|
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
|
+
*/
|
|
25
|
+
class?: string
|
|
26
|
+
/**
|
|
27
|
+
* Standard HTML attributes.
|
|
28
|
+
*/
|
|
29
|
+
[key: string]: unknown
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const { class: className, ui: uiProp } = defineProps<RLVPlaceholderProps>()
|
|
33
|
+
|
|
34
|
+
defineSlots<{
|
|
35
|
+
/**
|
|
36
|
+
* The default slot for placeholder content.
|
|
37
|
+
*/
|
|
38
|
+
default(props: {}): any
|
|
39
|
+
}>()
|
|
40
|
+
|
|
41
|
+
const globalConfig = getUIConfig()
|
|
42
|
+
|
|
43
|
+
const mergedUI = defu(
|
|
44
|
+
uiProp ?? {},
|
|
45
|
+
(globalConfig.placeholder as Record<string, unknown>) ?? {}
|
|
46
|
+
) as Record<keyof typeof placeholderTheme.base, string | undefined>
|
|
47
|
+
|
|
48
|
+
const { base, svg } = placeholder()
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<template>
|
|
52
|
+
<div :class="twMerge(base, mergedUI.base, className)" v-bind="$attrs">
|
|
53
|
+
<svg :class="twMerge(svg, mergedUI.svg)">
|
|
54
|
+
<defs>
|
|
55
|
+
<pattern
|
|
56
|
+
id="pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e"
|
|
57
|
+
x="0"
|
|
58
|
+
y="0"
|
|
59
|
+
width="10"
|
|
60
|
+
height="10"
|
|
61
|
+
patternUnits="userSpaceOnUse"
|
|
62
|
+
>
|
|
63
|
+
<path d="M-3 13 15-5M-5 5l18-18M-1 21 17 3" />
|
|
64
|
+
</pattern>
|
|
65
|
+
</defs>
|
|
66
|
+
<rect
|
|
67
|
+
stroke="none"
|
|
68
|
+
fill="url(#pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e)"
|
|
69
|
+
width="100%"
|
|
70
|
+
height="100%"
|
|
71
|
+
/>
|
|
72
|
+
</svg>
|
|
73
|
+
|
|
74
|
+
<slot />
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
@@ -1,154 +1,214 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { getUIConfig } from "virtual:rimelight-ui"
|
|
9
|
-
|
|
10
|
-
export interface RLVScrollToTopProps {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { scv, cx } from "css-variants"
|
|
3
|
+
import { twMerge } from "tailwind-merge"
|
|
4
|
+
import defu from "defu"
|
|
5
|
+
import { scrollToTopTheme } from "../../themes/scroll-to-top.theme.ts"
|
|
6
|
+
import { useScrollToTop } from "../../composables/useScrollToTop"
|
|
7
|
+
import { computed } from "vue"
|
|
8
|
+
import { getUIConfig } from "virtual:rimelight-ui"
|
|
9
|
+
|
|
10
|
+
export interface RLVScrollToTopProps {
|
|
11
|
+
/**
|
|
12
|
+
* Button color.
|
|
13
|
+
*
|
|
14
|
+
* @default "primary"
|
|
15
|
+
*/
|
|
16
|
+
color?: keyof typeof scrollToTopTheme.variants.color
|
|
17
|
+
/**
|
|
18
|
+
* Transition duration for the progress circle (in seconds).
|
|
19
|
+
*
|
|
20
|
+
* @default 0.1
|
|
21
|
+
*/
|
|
22
|
+
duration?: number
|
|
23
|
+
/**
|
|
24
|
+
* Scroll threshold (in pixels) before the button becomes visible.
|
|
25
|
+
*
|
|
26
|
+
* @default 200
|
|
27
|
+
*/
|
|
28
|
+
threshold?: number
|
|
29
|
+
/**
|
|
30
|
+
* Whether to show the scroll progress indicator.
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
showProgress?: boolean
|
|
35
|
+
/**
|
|
36
|
+
* Stroke width of the progress circle.
|
|
37
|
+
*
|
|
38
|
+
* @default 6
|
|
39
|
+
*/
|
|
40
|
+
progressWidth?: number
|
|
41
|
+
/**
|
|
42
|
+
* UI overrides for individual slots, derived from the scroll-to-top theme.
|
|
43
|
+
*/
|
|
44
|
+
ui?: Partial<Record<keyof typeof scrollToTopTheme.base, string>>
|
|
45
|
+
/**
|
|
46
|
+
* External class — applied to the root element.
|
|
47
|
+
*/
|
|
48
|
+
class?: string
|
|
49
|
+
/**
|
|
50
|
+
* Standard HTML attributes.
|
|
51
|
+
*/
|
|
52
|
+
[key: string]: unknown
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const scrollToTop = scv({
|
|
56
|
+
slots: [...scrollToTopTheme.slots],
|
|
57
|
+
base: scrollToTopTheme.base,
|
|
58
|
+
variants: scrollToTopTheme.variants,
|
|
59
|
+
compoundVariants: [...scrollToTopTheme.compoundVariants],
|
|
60
|
+
defaultVariants: scrollToTopTheme.defaultVariants,
|
|
61
|
+
classNameResolver: (...args) => twMerge(cx(...args))
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const {
|
|
65
|
+
color = "primary",
|
|
66
|
+
progressWidth = 6,
|
|
67
|
+
duration = 0.1,
|
|
68
|
+
threshold = 200,
|
|
69
|
+
showProgress = false,
|
|
70
|
+
ui: uiProp,
|
|
71
|
+
class: className
|
|
72
|
+
} = defineProps<RLVScrollToTopProps>()
|
|
73
|
+
|
|
74
|
+
const globalConfig = getUIConfig()
|
|
75
|
+
|
|
76
|
+
const mergedUI = defu(
|
|
77
|
+
uiProp ?? {},
|
|
78
|
+
(globalConfig["scroll-to-top"] as Record<string, unknown>) ?? {}
|
|
79
|
+
) as Record<keyof typeof scrollToTopTheme.base, string | undefined>
|
|
80
|
+
|
|
81
|
+
const {
|
|
82
|
+
root,
|
|
83
|
+
button,
|
|
84
|
+
progressBase,
|
|
85
|
+
svg: svgClass,
|
|
86
|
+
iconContainer,
|
|
87
|
+
icon
|
|
88
|
+
} = scrollToTop({
|
|
89
|
+
color
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
const {
|
|
93
|
+
isVisible,
|
|
94
|
+
scrollPercentage,
|
|
95
|
+
scrollToTop: scrollToTopFn
|
|
96
|
+
} = useScrollToTop({
|
|
97
|
+
threshold
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const circumference = 2 * Math.PI * 45
|
|
101
|
+
const percentPx = circumference / 100
|
|
102
|
+
|
|
103
|
+
const currentPercent = computed(() => scrollPercentage.value)
|
|
104
|
+
const percentageInPx = computed(() => `${percentPx}px`)
|
|
105
|
+
const durationInSeconds = computed(() => `${duration}s`)
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<template>
|
|
109
|
+
<div
|
|
110
|
+
:class="[
|
|
111
|
+
'rla-scroll-to-top fixed bottom-6 right-6 z-50',
|
|
112
|
+
{ visible: isVisible },
|
|
113
|
+
twMerge(root, mergedUI.root, className)
|
|
114
|
+
]"
|
|
115
|
+
v-bind="$attrs"
|
|
116
|
+
>
|
|
117
|
+
<button
|
|
118
|
+
type="button"
|
|
119
|
+
:class="twMerge(button, mergedUI.button)"
|
|
120
|
+
aria-label="Scroll to top"
|
|
121
|
+
@click="scrollToTopFn"
|
|
122
|
+
>
|
|
123
|
+
<div :class="twMerge(progressBase, mergedUI.progressBase)">
|
|
124
|
+
<svg
|
|
125
|
+
:class="twMerge(svgClass, mergedUI.svg)"
|
|
126
|
+
viewBox="0 0 100 100"
|
|
127
|
+
shape-rendering="geometricPrecision"
|
|
128
|
+
>
|
|
129
|
+
<circle
|
|
130
|
+
cx="50"
|
|
131
|
+
cy="50"
|
|
132
|
+
r="45"
|
|
133
|
+
fill="var(--color-primary-950)"
|
|
134
|
+
:stroke-width="progressWidth"
|
|
135
|
+
stroke-dashoffset="0"
|
|
136
|
+
stroke-linecap="round"
|
|
137
|
+
class="gauge-secondary-stroke opacity-100"
|
|
138
|
+
/>
|
|
139
|
+
<circle
|
|
140
|
+
v-if="showProgress"
|
|
141
|
+
cx="50"
|
|
142
|
+
cy="50"
|
|
143
|
+
r="45"
|
|
144
|
+
fill="transparent"
|
|
145
|
+
:stroke-width="progressWidth"
|
|
146
|
+
stroke-linecap="round"
|
|
147
|
+
class="gauge-primary-stroke opacity-100"
|
|
148
|
+
:style="{
|
|
149
|
+
'--stroke-percent': currentPercent,
|
|
150
|
+
'--percent-to-px': percentageInPx,
|
|
151
|
+
'--circumference': circumference,
|
|
152
|
+
'--duration': durationInSeconds
|
|
153
|
+
}"
|
|
154
|
+
/>
|
|
155
|
+
</svg>
|
|
156
|
+
<div :class="twMerge(iconContainer, mergedUI.iconContainer)">
|
|
157
|
+
<svg
|
|
158
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
159
|
+
width="24"
|
|
160
|
+
height="24"
|
|
161
|
+
viewBox="0 0 24 24"
|
|
162
|
+
fill="none"
|
|
163
|
+
stroke="currentColor"
|
|
164
|
+
stroke-width="2"
|
|
165
|
+
stroke-linecap="round"
|
|
166
|
+
stroke-linejoin="round"
|
|
167
|
+
:class="twMerge(icon, mergedUI.icon)"
|
|
168
|
+
>
|
|
169
|
+
<path d="m5 12 7-7 7 7" />
|
|
170
|
+
<path d="M12 19V5" />
|
|
171
|
+
</svg>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</button>
|
|
175
|
+
</div>
|
|
176
|
+
</template>
|
|
177
|
+
|
|
178
|
+
<style scoped>
|
|
179
|
+
.rla-scroll-to-top {
|
|
180
|
+
opacity: 0;
|
|
181
|
+
pointer-events: none;
|
|
182
|
+
transition: opacity 0.3s ease-in-out;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.rla-scroll-to-top.visible {
|
|
186
|
+
opacity: 1;
|
|
187
|
+
pointer-events: auto;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.progress-circle-base {
|
|
191
|
+
transform: translateZ(0);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.gauge-primary-stroke {
|
|
195
|
+
stroke: var(--color-primary-500);
|
|
196
|
+
--stroke-percent: v-bind(currentPercent);
|
|
197
|
+
--percent-to-px: v-bind(percentageInPx);
|
|
198
|
+
--circumference: v-bind(circumference);
|
|
199
|
+
stroke-dasharray: calc(var(--stroke-percent) * var(--percent-to-px)) var(--circumference);
|
|
200
|
+
transition:
|
|
201
|
+
stroke-dasharray v-bind(durationInSeconds) ease,
|
|
202
|
+
stroke v-bind(durationInSeconds) ease;
|
|
203
|
+
transform: rotate(-90deg);
|
|
204
|
+
transform-origin: center;
|
|
205
|
+
shape-rendering: geometricPrecision;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.gauge-secondary-stroke {
|
|
209
|
+
stroke: var(--color-primary-900);
|
|
210
|
+
stroke-dasharray: 282.6;
|
|
211
|
+
transform: rotate(-90deg);
|
|
212
|
+
transform-origin: center;
|
|
213
|
+
}
|
|
214
|
+
</style>
|
package/src/integrations/ui.ts
CHANGED
|
@@ -3,7 +3,6 @@ import UnoCSS from "unocss/astro"
|
|
|
3
3
|
import vue from "@astrojs/vue"
|
|
4
4
|
import uiPlugin from "@nuxt/ui/vite"
|
|
5
5
|
import defu from "defu"
|
|
6
|
-
import Icons from "unplugin-icons/vite"
|
|
7
6
|
import tailwindcss from "@tailwindcss/vite"
|
|
8
7
|
import { defaultUIConfig } from "../themes"
|
|
9
8
|
|
|
@@ -11,12 +10,28 @@ import { defaultUIConfig } from "../themes"
|
|
|
11
10
|
* Shape of the `ui` config that can be passed to the integration.
|
|
12
11
|
*/
|
|
13
12
|
export type UIConfigOverrides = {
|
|
14
|
-
button?: Partial<(typeof defaultUIConfig)["button"]>
|
|
15
|
-
header?: Partial<(typeof defaultUIConfig)["header"]>
|
|
13
|
+
"button"?: Partial<(typeof defaultUIConfig)["button"]>
|
|
14
|
+
"header"?: Partial<(typeof defaultUIConfig)["header"]>
|
|
16
15
|
"scroll-to-top"?: Partial<(typeof defaultUIConfig)["scroll-to-top"]>
|
|
16
|
+
"logo"?: Partial<(typeof defaultUIConfig)["logo"]>
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface UIOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for the Logo component variants.
|
|
22
|
+
*/
|
|
23
|
+
logos?: Record<
|
|
24
|
+
string,
|
|
25
|
+
| string
|
|
26
|
+
| {
|
|
27
|
+
light?: string
|
|
28
|
+
dark?: string
|
|
29
|
+
color?: string
|
|
30
|
+
white?: string
|
|
31
|
+
black?: string
|
|
32
|
+
[key: string]: string | undefined
|
|
33
|
+
}
|
|
34
|
+
>
|
|
20
35
|
/**
|
|
21
36
|
* Global UI overrides applied to all components. Merged with defaults via `defu` (first arg
|
|
22
37
|
* wins).
|
|
@@ -47,7 +62,8 @@ export interface UIOptions {
|
|
|
47
62
|
* })
|
|
48
63
|
*/
|
|
49
64
|
export function ui(options: UIOptions = {}): AstroIntegration[] {
|
|
50
|
-
const
|
|
65
|
+
const resolvedUI = defu(options.ui ?? {}, defaultUIConfig)
|
|
66
|
+
const resolvedConfig = { ...resolvedUI, logos: options.logos ?? {} }
|
|
51
67
|
|
|
52
68
|
const virtualModuleId = "virtual:rimelight-ui"
|
|
53
69
|
const resolvedVirtualModuleId = "\0" + virtualModuleId
|
|
@@ -74,10 +90,6 @@ export function ui(options: UIOptions = {}): AstroIntegration[] {
|
|
|
74
90
|
router: false,
|
|
75
91
|
scanPackages: ["@rimelight/ui"]
|
|
76
92
|
}),
|
|
77
|
-
Icons({
|
|
78
|
-
compiler: "astro",
|
|
79
|
-
autoInstall: true
|
|
80
|
-
}),
|
|
81
93
|
tailwindcss(),
|
|
82
94
|
{
|
|
83
95
|
name: "vite-plugin-rimelight-ui-config",
|
package/src/plugins/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default as starlightAddons } from "../plugins/starlightAddons"
|
|
2
|
-
export type { StarlightAddonsConfig } from "../plugins/starlightAddons"
|
|
1
|
+
export { default as starlightAddons } from "../plugins/starlightAddons"
|
|
2
|
+
export type { StarlightAddonsConfig } from "../plugins/starlightAddons"
|