@rxdrag/website-lib 0.0.104 → 0.0.106
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/components/AnimationNumber.astro +218 -0
- package/components/Background.astro +106 -0
- package/components/BackgroundGroup.astro +21 -0
- package/components/Box.astro +25 -0
- package/components/Collapse.astro +125 -0
- package/components/CollapseIndicator.astro +20 -0
- package/components/Container.astro +13 -0
- package/components/Dialog.astro +374 -0
- package/components/DialogTrigger.astro +26 -0
- package/components/FooterShell.astro +43 -0
- package/components/Grid.astro +26 -0
- package/components/GridCell.astro +22 -0
- package/components/HeaderShell.astro +43 -0
- package/components/Icon.astro +30 -0
- package/components/Image.astro +18 -0
- package/components/Link.astro +71 -0
- package/components/Meta.astro +65 -0
- package/components/Popover.astro +187 -0
- package/components/RichTextView.astro +47 -0
- package/components/Section.astro +43 -0
- package/components/SiteShell.astro +152 -0
- package/components/Video.astro +51 -0
- package/index.ts +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
start?: number;
|
|
4
|
+
end: number;
|
|
5
|
+
duration?: number;
|
|
6
|
+
class?: string;
|
|
7
|
+
sign?: string;
|
|
8
|
+
once?: boolean;
|
|
9
|
+
type?: "int" | "float";
|
|
10
|
+
fractionDigits?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
start = 0,
|
|
15
|
+
end,
|
|
16
|
+
duration = 1200,
|
|
17
|
+
class: className,
|
|
18
|
+
sign = "+",
|
|
19
|
+
once = false,
|
|
20
|
+
type = "int",
|
|
21
|
+
fractionDigits = 1,
|
|
22
|
+
} = Astro.props;
|
|
23
|
+
|
|
24
|
+
const id = crypto.randomUUID();
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<span
|
|
28
|
+
class={className}
|
|
29
|
+
data-light-number
|
|
30
|
+
data-id={id}
|
|
31
|
+
data-start={start}
|
|
32
|
+
data-end={end}
|
|
33
|
+
data-duration={duration}
|
|
34
|
+
data-once={once ? "1" : "0"}
|
|
35
|
+
data-type={type}
|
|
36
|
+
data-fraction-digits={fractionDigits}
|
|
37
|
+
>
|
|
38
|
+
<span data-light-number-value>{start}</span>
|
|
39
|
+
{
|
|
40
|
+
sign && (
|
|
41
|
+
<span data-light-number-sign style="display:none">
|
|
42
|
+
{sign}
|
|
43
|
+
</span>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
</span>
|
|
47
|
+
|
|
48
|
+
<script is:inline>
|
|
49
|
+
(() => {
|
|
50
|
+
const bindAstroLifecycle = (key, fn) => {
|
|
51
|
+
const w = window;
|
|
52
|
+
const bound = (w.__astro_lifecycle_bound__ ||= Object.create(null));
|
|
53
|
+
if (bound[key]) return;
|
|
54
|
+
bound[key] = true;
|
|
55
|
+
|
|
56
|
+
const boot = () => fn();
|
|
57
|
+
|
|
58
|
+
if (document.readyState === "loading") {
|
|
59
|
+
document.addEventListener("DOMContentLoaded", boot, { once: true });
|
|
60
|
+
} else {
|
|
61
|
+
boot();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
document.addEventListener("astro:page-load", boot);
|
|
65
|
+
document.addEventListener("astro:after-swap", boot);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const globalKey = "__light_number_state__";
|
|
69
|
+
const w = window;
|
|
70
|
+
const state = (w[globalKey] ||= {
|
|
71
|
+
docBound: false,
|
|
72
|
+
moBound: false,
|
|
73
|
+
scheduled: false,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const scheduleInit = () => {
|
|
77
|
+
if (state.scheduled) return;
|
|
78
|
+
state.scheduled = true;
|
|
79
|
+
requestAnimationFrame(() => {
|
|
80
|
+
state.scheduled = false;
|
|
81
|
+
init();
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const init = () => {
|
|
86
|
+
const nodes = document.querySelectorAll("[data-light-number]");
|
|
87
|
+
nodes.forEach((root) => {
|
|
88
|
+
if (!(root instanceof HTMLElement)) return;
|
|
89
|
+
if (root.dataset.bound === "1") return;
|
|
90
|
+
root.dataset.bound = "1";
|
|
91
|
+
|
|
92
|
+
const valueEl = root.querySelector("[data-light-number-value]");
|
|
93
|
+
const signEl = root.querySelector("[data-light-number-sign]");
|
|
94
|
+
if (!(valueEl instanceof HTMLElement)) return;
|
|
95
|
+
|
|
96
|
+
const start = Number(root.dataset.start ?? "0");
|
|
97
|
+
const end = Number(root.dataset.end ?? "0");
|
|
98
|
+
const duration = Number(root.dataset.duration ?? "1200");
|
|
99
|
+
const once = root.dataset.once === "1";
|
|
100
|
+
const type = root.dataset.type === "float" ? "float" : "int";
|
|
101
|
+
const fractionDigits = Number(root.dataset.fractionDigits ?? "1");
|
|
102
|
+
|
|
103
|
+
let running = false;
|
|
104
|
+
let played = false;
|
|
105
|
+
let rafId = 0;
|
|
106
|
+
|
|
107
|
+
const format = (n) => {
|
|
108
|
+
if (type === "float") {
|
|
109
|
+
return n.toFixed(
|
|
110
|
+
Number.isFinite(fractionDigits) ? fractionDigits : 1
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return String(Math.round(n));
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const setValue = (n) => {
|
|
117
|
+
valueEl.textContent = format(n);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const showSign = () => {
|
|
121
|
+
if (signEl instanceof HTMLElement) {
|
|
122
|
+
signEl.style.display = "";
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const animate = () => {
|
|
127
|
+
if (running) return;
|
|
128
|
+
if (once && played) return;
|
|
129
|
+
|
|
130
|
+
running = true;
|
|
131
|
+
played = true;
|
|
132
|
+
showSign();
|
|
133
|
+
|
|
134
|
+
const from = start;
|
|
135
|
+
const to = end;
|
|
136
|
+
const t0 = performance.now();
|
|
137
|
+
|
|
138
|
+
const step = (t) => {
|
|
139
|
+
const p = Math.min(1, (t - t0) / Math.max(16, duration));
|
|
140
|
+
const eased = 1 - Math.pow(1 - p, 3);
|
|
141
|
+
const v = from + (to - from) * eased;
|
|
142
|
+
setValue(v);
|
|
143
|
+
if (p < 1) {
|
|
144
|
+
rafId = requestAnimationFrame(step);
|
|
145
|
+
} else {
|
|
146
|
+
running = false;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
cancelAnimationFrame(rafId);
|
|
151
|
+
rafId = requestAnimationFrame(step);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const isInViewport = () => {
|
|
155
|
+
const rect = root.getBoundingClientRect();
|
|
156
|
+
const vh = window.innerHeight || document.documentElement.clientHeight;
|
|
157
|
+
return rect.bottom > 0 && rect.top < vh;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
161
|
+
if (isInViewport()) animate();
|
|
162
|
+
else window.addEventListener("scroll", animate, { passive: true, once: true });
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const io = new IntersectionObserver(
|
|
167
|
+
(entries) => {
|
|
168
|
+
entries.forEach((entry) => {
|
|
169
|
+
if (!entry.isIntersecting) return;
|
|
170
|
+
animate();
|
|
171
|
+
if (once) io.disconnect();
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
{ threshold: 0.25 }
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
io.observe(root);
|
|
178
|
+
|
|
179
|
+
if (isInViewport()) animate();
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const boot = () => {
|
|
184
|
+
init();
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
bindAstroLifecycle("light-number:boot", boot);
|
|
188
|
+
|
|
189
|
+
if (!state.moBound) {
|
|
190
|
+
state.moBound = true;
|
|
191
|
+
const mo = new MutationObserver((mutations) => {
|
|
192
|
+
for (const m of mutations) {
|
|
193
|
+
if (!m.addedNodes || m.addedNodes.length === 0) continue;
|
|
194
|
+
for (const n of m.addedNodes) {
|
|
195
|
+
if (!(n instanceof Element)) continue;
|
|
196
|
+
if (n.matches && n.matches("[data-light-number]")) {
|
|
197
|
+
scheduleInit();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (n.querySelector && n.querySelector("[data-light-number]")) {
|
|
201
|
+
scheduleInit();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
if (document.body) {
|
|
208
|
+
mo.observe(document.body, { childList: true, subtree: true });
|
|
209
|
+
} else {
|
|
210
|
+
document.addEventListener(
|
|
211
|
+
"DOMContentLoaded",
|
|
212
|
+
() => mo.observe(document.body, { childList: true, subtree: true }),
|
|
213
|
+
{ once: true }
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
218
|
+
</script>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { BackgroundConfig, Locals } from "@rxdrag/website-lib-core";
|
|
3
|
+
import {
|
|
4
|
+
BackgroundVideoPlayer,
|
|
5
|
+
BackgroundHlsVideoPlayer,
|
|
6
|
+
Entify,
|
|
7
|
+
} from "@rxdrag/website-lib-core";
|
|
8
|
+
|
|
9
|
+
export interface Props {
|
|
10
|
+
background: BackgroundConfig;
|
|
11
|
+
index?: number;
|
|
12
|
+
defaultClass?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { env, imageSizes } = Astro.locals as Locals;
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
background,
|
|
19
|
+
defaultClass = "absolute top-0 left-0 w-full h-full object-cover",
|
|
20
|
+
} = Astro.props;
|
|
21
|
+
|
|
22
|
+
// 安全地提取 mediaRef 和 posterRef(只有部分背景类型有这些属性)
|
|
23
|
+
const mediaRef =
|
|
24
|
+
background.type === "image" ||
|
|
25
|
+
background.type === "video" ||
|
|
26
|
+
background.type === "spline"
|
|
27
|
+
? background.mediaRef
|
|
28
|
+
: undefined;
|
|
29
|
+
|
|
30
|
+
const posterRef =
|
|
31
|
+
background.type === "video" ? background.posterRef : undefined;
|
|
32
|
+
|
|
33
|
+
const rx = Entify.getInstance(env, imageSizes);
|
|
34
|
+
|
|
35
|
+
// 获取媒体数据
|
|
36
|
+
const media = rx ? await rx.getMedia(mediaRef) : undefined;
|
|
37
|
+
const poster = rx ? await rx.getMedia(posterRef) : undefined;
|
|
38
|
+
|
|
39
|
+
// 构建 className
|
|
40
|
+
const className = [defaultClass, background.className]
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.join(" ");
|
|
43
|
+
|
|
44
|
+
// 预计算视频相关数据
|
|
45
|
+
const videoUrl =
|
|
46
|
+
background.type === "video" ? media?.file?.original : undefined;
|
|
47
|
+
const posterUrl =
|
|
48
|
+
background.type === "video" ? poster?.file?.original : undefined;
|
|
49
|
+
const isHls =
|
|
50
|
+
background.type === "video" &&
|
|
51
|
+
(media?.storageType === "cloudflare_stream" ||
|
|
52
|
+
videoUrl?.endsWith(".m3u8") ||
|
|
53
|
+
videoUrl?.includes("cloudflarestream.com"));
|
|
54
|
+
|
|
55
|
+
// 预计算图片 URL
|
|
56
|
+
const imageUrl =
|
|
57
|
+
background.type === "image" ? media?.file?.original : undefined;
|
|
58
|
+
|
|
59
|
+
// 预计算 Spline URL
|
|
60
|
+
const splineUrl =
|
|
61
|
+
background.type === "spline"
|
|
62
|
+
? background.url ||
|
|
63
|
+
(background.mediaRef ? `/media/${background.mediaRef}` : "")
|
|
64
|
+
: undefined;
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
{background.type === "color" && <div class={className} />}
|
|
68
|
+
|
|
69
|
+
{background.type === "blur" && <div class={className} />}
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
background.type === "image" && (
|
|
73
|
+
<img class={className} src={imageUrl} alt="Background Image" />
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
background.type === "svg" && background.code && (
|
|
79
|
+
<div class={className} set:html={background.code} />
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
background.type === "video" &&
|
|
85
|
+
(isHls ? (
|
|
86
|
+
<BackgroundHlsVideoPlayer
|
|
87
|
+
className={className}
|
|
88
|
+
src={videoUrl}
|
|
89
|
+
poster={posterUrl}
|
|
90
|
+
client:load
|
|
91
|
+
/>
|
|
92
|
+
) : (
|
|
93
|
+
<BackgroundVideoPlayer
|
|
94
|
+
className={className}
|
|
95
|
+
src={videoUrl}
|
|
96
|
+
poster={posterUrl}
|
|
97
|
+
client:load
|
|
98
|
+
/>
|
|
99
|
+
))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
{
|
|
103
|
+
background.type === "spline" && (
|
|
104
|
+
<iframe class={className} src={splineUrl} title="Spline 3D Scene" />
|
|
105
|
+
)
|
|
106
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { BackgroundConfig } from "@rxdrag/website-lib-core";
|
|
3
|
+
import Background from "./Background.astro";
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
backgrounds?: BackgroundConfig[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { backgrounds } = Astro.props;
|
|
10
|
+
|
|
11
|
+
const defaultClass =
|
|
12
|
+
"absolute w-full h-full inset-0 object-cover";
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<Fragment>
|
|
16
|
+
{
|
|
17
|
+
backgrounds?.map((background) => (
|
|
18
|
+
<Background background={background} defaultClass={defaultClass} />
|
|
19
|
+
))
|
|
20
|
+
}
|
|
21
|
+
</Fragment>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type {
|
|
3
|
+
AnimationConfig,
|
|
4
|
+
BackgroundConfig,
|
|
5
|
+
} from "@rxdrag/website-lib-core";
|
|
6
|
+
import BackgroundGroup from "./BackgroundGroup.astro";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
class?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
backgrounds?: BackgroundConfig[];
|
|
12
|
+
//动效
|
|
13
|
+
animation?: AnimationConfig;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { className, class: originalClass, backgrounds, ...rest } = Astro.props;
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<div
|
|
20
|
+
class:list={["w-full, h-full flex flex-col", className, originalClass]}
|
|
21
|
+
{...rest}
|
|
22
|
+
>
|
|
23
|
+
<BackgroundGroup backgrounds={backgrounds} />
|
|
24
|
+
<slot />
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
triggerClass?: string;
|
|
5
|
+
panelClass?: string;
|
|
6
|
+
initialOpen?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
class: className,
|
|
11
|
+
triggerClass,
|
|
12
|
+
panelClass,
|
|
13
|
+
initialOpen = false,
|
|
14
|
+
} = Astro.props;
|
|
15
|
+
|
|
16
|
+
const collapseId = crypto.randomUUID();
|
|
17
|
+
const panelId = `collapse-panel-${collapseId}`;
|
|
18
|
+
const rootId = `collapse-${collapseId}`;
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
<div
|
|
22
|
+
class:list={["n-collapse", className]}
|
|
23
|
+
id={rootId}
|
|
24
|
+
data-open={initialOpen ? "true" : "false"}
|
|
25
|
+
>
|
|
26
|
+
<button
|
|
27
|
+
type="button"
|
|
28
|
+
class:list={["n-collapse__trigger", triggerClass]}
|
|
29
|
+
aria-expanded={initialOpen ? "true" : "false"}
|
|
30
|
+
aria-controls={panelId}
|
|
31
|
+
>
|
|
32
|
+
<slot name="trigger" />
|
|
33
|
+
</button>
|
|
34
|
+
|
|
35
|
+
<div
|
|
36
|
+
id={panelId}
|
|
37
|
+
class:list={["n-collapse__panel", panelClass]}
|
|
38
|
+
style={`height: ${initialOpen ? "auto" : "0px"};`}
|
|
39
|
+
aria-hidden={initialOpen ? "false" : "true"}
|
|
40
|
+
>
|
|
41
|
+
<slot />
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<style>
|
|
46
|
+
.n-collapse__panel {
|
|
47
|
+
transition: height 0.35s ease;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.n-collapse__indicator {
|
|
51
|
+
transition: transform 0.25s ease;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.n-collapse[data-open="true"] .n-collapse__indicator {
|
|
55
|
+
transform: rotate(180deg);
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
58
|
+
|
|
59
|
+
<script is:inline>
|
|
60
|
+
// This component can appear multiple times per page.
|
|
61
|
+
// We install a single global initializer so it keeps working after Astro SPA navigation.
|
|
62
|
+
if (!window.__nCollapse) {
|
|
63
|
+
window.__nCollapse = {
|
|
64
|
+
initCollapseRoot(root) {
|
|
65
|
+
if (!root || root.dataset.nCollapseBound === "true") return;
|
|
66
|
+
root.dataset.nCollapseBound = "true";
|
|
67
|
+
|
|
68
|
+
const trigger = root.querySelector(":scope > .n-collapse__trigger");
|
|
69
|
+
const panel = root.querySelector(":scope > .n-collapse__panel");
|
|
70
|
+
if (!trigger || !panel) {
|
|
71
|
+
console.log("Collapse: trigger/panel not found", root);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let open = root.dataset.open === "true";
|
|
76
|
+
if (open) {
|
|
77
|
+
panel.style.height = "auto";
|
|
78
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
79
|
+
panel.setAttribute("aria-hidden", "false");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const setOpen = (next) => {
|
|
83
|
+
open = next;
|
|
84
|
+
root.dataset.open = open ? "true" : "false";
|
|
85
|
+
trigger.setAttribute("aria-expanded", open ? "true" : "false");
|
|
86
|
+
panel.setAttribute("aria-hidden", open ? "false" : "true");
|
|
87
|
+
|
|
88
|
+
if (open) {
|
|
89
|
+
panel.style.height = "auto";
|
|
90
|
+
const h = panel.scrollHeight;
|
|
91
|
+
panel.style.height = "0px";
|
|
92
|
+
panel.offsetHeight;
|
|
93
|
+
panel.style.height = h + "px";
|
|
94
|
+
} else {
|
|
95
|
+
const h = panel.scrollHeight;
|
|
96
|
+
panel.style.height = h + "px";
|
|
97
|
+
panel.offsetHeight;
|
|
98
|
+
panel.style.height = "0px";
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const onTransitionEnd = (e) => {
|
|
103
|
+
if (e.target !== panel || e.propertyName !== "height") return;
|
|
104
|
+
if (open) panel.style.height = "auto";
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
trigger.addEventListener("click", () => setOpen(!open));
|
|
108
|
+
panel.addEventListener("transitionend", onTransitionEnd);
|
|
109
|
+
},
|
|
110
|
+
initAll() {
|
|
111
|
+
document.querySelectorAll(".n-collapse").forEach((el) => window.__nCollapse.initCollapseRoot(el));
|
|
112
|
+
},
|
|
113
|
+
listenersBound: false,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Bind listeners once to support ClientRouter/ViewTransitions.
|
|
118
|
+
if (!window.__nCollapse.listenersBound) {
|
|
119
|
+
window.__nCollapse.listenersBound = true;
|
|
120
|
+
document.addEventListener("astro:page-load", () => window.__nCollapse.initAll());
|
|
121
|
+
document.addEventListener("astro:after-swap", () => window.__nCollapse.initAll());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
window.__nCollapse.initAll();
|
|
125
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { class: className } = Astro.props;
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<span class:list={["n-collapse__indicator", "h-5", "w-5", "flex-none", "text-foreground", className]} aria-hidden="true">
|
|
10
|
+
<svg
|
|
11
|
+
aria-hidden="true"
|
|
12
|
+
fill="currentColor"
|
|
13
|
+
focusable="false"
|
|
14
|
+
height="1.25rem"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
width="1.25rem"
|
|
17
|
+
>
|
|
18
|
+
<path d="M7.41 8.59 12 13.17l4.59-4.58L18 10l-6 6-6-6z"></path>
|
|
19
|
+
</svg>
|
|
20
|
+
</span>
|