@rxdrag/website-lib 0.0.151 → 0.0.153
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/README.md +2 -2
- package/components/AnimationNumber.astro +217 -217
- package/components/Background.astro +140 -114
- package/components/BackgroundGroup.astro +20 -26
- package/components/BaseFooter.astro +24 -39
- package/components/BaseHeader.astro +22 -25
- package/components/Box.astro +20 -22
- package/components/Button.astro +80 -0
- package/components/Carousel.astro +456 -315
- package/components/CarouselPagination.astro +97 -76
- package/components/CarouselSlide.astro +10 -16
- package/components/Collapse.astro +125 -125
- package/components/CollapseIndicator.astro +20 -20
- package/components/Container.astro +27 -32
- package/components/Content.astro +20 -0
- package/components/CookieConsent.astro +47 -47
- package/components/CookieConsent.css +52 -52
- package/components/CookieConsentConfig.ts +208 -208
- package/components/Dialog.astro +342 -338
- package/components/DialogTrigger.astro +32 -32
- package/components/Document.astro +240 -225
- package/components/Frame.astro +32 -0
- package/components/GlassBorder.astro +104 -0
- package/components/GlassRefraction.astro +85 -0
- package/components/GradientBorder.astro +80 -0
- package/components/Grid.astro +32 -34
- package/components/GridCell.astro +28 -32
- package/components/Heading.astro +24 -24
- package/components/Icon.astro +29 -29
- package/components/Image.astro +100 -100
- package/components/Image.md +14 -14
- package/components/Link.astro +89 -99
- package/components/Main.astro +17 -17
- package/components/Meta.astro +65 -65
- package/components/Popover.astro +189 -189
- package/components/RichTextView.astro +28 -28
- package/components/Section.astro +26 -44
- package/components/TabButton.astro +32 -16
- package/components/TabPanel.astro +20 -19
- package/components/Tabs.astro +220 -147
- package/components/Video.astro +6 -4
- package/components/YearsSince.astro +20 -20
- package/components//344/270/211/345/261/202/346/250/241/345/236/213.md +5 -5
- package/components//344/270/273/351/242/230Token.md +198 -198
- package/components//345/216/237/345/255/220/345/206/273/347/273/223/346/270/205/345/215/225.md +270 -260
- package/components//347/211/251/346/226/231/346/270/205/345/215/225.md +599 -567
- package/index.ts +5 -5
- package/package.json +7 -7
- package/components/BaseBlock.astro +0 -34
- package/components/Motion.astro +0 -77
- package/components/Stack.astro +0 -31
package/components/Tabs.astro
CHANGED
|
@@ -1,147 +1,220 @@
|
|
|
1
|
-
---
|
|
2
|
-
const rootId = crypto.randomUUID();
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
class?: string;
|
|
6
|
-
className?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const { class: className, className: className2, ...props } = Astro.props;
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
<div data-tabs-root id={rootId} class:list={[className, className2]} {...props}>
|
|
13
|
-
<slot />
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<script is:inline define:vars={{ rootId }}>
|
|
17
|
-
const defaultIndex = 0;
|
|
18
|
-
const activeBtnClassName = "active";
|
|
19
|
-
const inactiveBtnClassName = "";
|
|
20
|
-
const showPanelClassName = "block";
|
|
21
|
-
const hidePanelClassName = "hidden";
|
|
22
|
-
|
|
23
|
-
const getState = () => {
|
|
24
|
-
const w = window;
|
|
25
|
-
const all = (w.__tabs__ ||= {});
|
|
26
|
-
return (all[rootId] ||= { cleanup: null });
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const
|
|
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
|
-
if (
|
|
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
|
-
|
|
1
|
+
---
|
|
2
|
+
const rootId = crypto.randomUUID();
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
class?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { class: className, className: className2, ...props } = Astro.props;
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<div data-tabs-root id={rootId} class:list={[className, className2]} {...props}>
|
|
13
|
+
<slot />
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<script is:inline define:vars={{ rootId }}>
|
|
17
|
+
const defaultIndex = 0;
|
|
18
|
+
const activeBtnClassName = "active";
|
|
19
|
+
const inactiveBtnClassName = "";
|
|
20
|
+
const showPanelClassName = "block";
|
|
21
|
+
const hidePanelClassName = "hidden";
|
|
22
|
+
|
|
23
|
+
const getState = () => {
|
|
24
|
+
const w = window;
|
|
25
|
+
const all = (w.__tabs__ ||= {});
|
|
26
|
+
return (all[rootId] ||= { cleanup: null, activeKey: "" });
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const isAutoKey = (value) => {
|
|
30
|
+
const v = String(value || "").trim();
|
|
31
|
+
return !v || v === "true" || v === "auto";
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const toArray = (nodes) => Array.from(nodes || []);
|
|
35
|
+
|
|
36
|
+
const initTabs = (state) => {
|
|
37
|
+
const root = document.getElementById(rootId);
|
|
38
|
+
if (!root) return () => {};
|
|
39
|
+
|
|
40
|
+
const toClassList = (className) =>
|
|
41
|
+
String(className || "")
|
|
42
|
+
.trim()
|
|
43
|
+
.split(/\s+/)
|
|
44
|
+
.filter(Boolean);
|
|
45
|
+
|
|
46
|
+
const activeBtnClasses = toClassList(activeBtnClassName);
|
|
47
|
+
const inactiveBtnClasses = toClassList(inactiveBtnClassName);
|
|
48
|
+
const showPanelClasses = toClassList(showPanelClassName);
|
|
49
|
+
const hidePanelClasses = toClassList(hidePanelClassName);
|
|
50
|
+
|
|
51
|
+
const getTabBtns = () => toArray(root.querySelectorAll("[data-tabs-btn]"));
|
|
52
|
+
const getTabPanels = () => toArray(root.querySelectorAll("[data-tabs-panel]"));
|
|
53
|
+
|
|
54
|
+
const syncBindings = () => {
|
|
55
|
+
const tabBtns = getTabBtns();
|
|
56
|
+
const tabPanels = getTabPanels();
|
|
57
|
+
const pairCount = Math.max(tabBtns.length, tabPanels.length);
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < pairCount; i++) {
|
|
60
|
+
const btn = tabBtns[i] || null;
|
|
61
|
+
const panel = tabPanels[i] || null;
|
|
62
|
+
const btnKeyRaw = btn ? btn.getAttribute("data-tabs-btn") : "";
|
|
63
|
+
const panelKeyRaw = panel ? panel.getAttribute("data-tabs-panel") : "";
|
|
64
|
+
const btnKey = isAutoKey(btnKeyRaw) ? "" : String(btnKeyRaw);
|
|
65
|
+
const panelKey = isAutoKey(panelKeyRaw) ? "" : String(panelKeyRaw);
|
|
66
|
+
const key = btnKey || panelKey || `${rootId}-${i}`;
|
|
67
|
+
|
|
68
|
+
if (btn) {
|
|
69
|
+
if (btn.getAttribute("data-tabs-btn") !== key) {
|
|
70
|
+
btn.setAttribute("data-tabs-btn", key);
|
|
71
|
+
}
|
|
72
|
+
if (!btn.getAttribute("data-tabs-role")) {
|
|
73
|
+
btn.setAttribute("data-tabs-role", "button");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (panel) {
|
|
77
|
+
if (panel.getAttribute("data-tabs-panel") !== key) {
|
|
78
|
+
panel.setAttribute("data-tabs-panel", key);
|
|
79
|
+
}
|
|
80
|
+
if (!panel.getAttribute("data-tabs-role")) {
|
|
81
|
+
panel.setAttribute("data-tabs-role", "panel");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const ac = new AbortController();
|
|
88
|
+
const { signal } = ac;
|
|
89
|
+
|
|
90
|
+
const setActiveBtnA11y = (btn, active) => {
|
|
91
|
+
btn.setAttribute("role", "tab");
|
|
92
|
+
btn.setAttribute("aria-selected", active ? "true" : "false");
|
|
93
|
+
btn.tabIndex = active ? 0 : -1;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const setActivePanelA11y = (panel, active) => {
|
|
97
|
+
panel.setAttribute("role", "tabpanel");
|
|
98
|
+
panel.setAttribute("aria-hidden", active ? "false" : "true");
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const activate = (btn) => {
|
|
102
|
+
const tabBtns = getTabBtns();
|
|
103
|
+
const tabPanels = getTabPanels();
|
|
104
|
+
const targetId = btn.getAttribute("data-tabs-btn");
|
|
105
|
+
if (!targetId) return;
|
|
106
|
+
state.activeKey = targetId;
|
|
107
|
+
|
|
108
|
+
tabBtns.forEach((b) => {
|
|
109
|
+
if (inactiveBtnClasses.length) b.classList.add(...inactiveBtnClasses);
|
|
110
|
+
if (activeBtnClasses.length) b.classList.remove(...activeBtnClasses);
|
|
111
|
+
setActiveBtnA11y(b, false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
tabPanels.forEach((p) => {
|
|
115
|
+
if (showPanelClasses.length) p.classList.remove(...showPanelClasses);
|
|
116
|
+
if (hidePanelClasses.length) p.classList.add(...hidePanelClasses);
|
|
117
|
+
setActivePanelA11y(p, false);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (inactiveBtnClasses.length)
|
|
121
|
+
btn.classList.remove(...inactiveBtnClasses);
|
|
122
|
+
if (activeBtnClasses.length) btn.classList.add(...activeBtnClasses);
|
|
123
|
+
setActiveBtnA11y(btn, true);
|
|
124
|
+
|
|
125
|
+
let panel = root.querySelector(
|
|
126
|
+
`[data-tabs-panel="${CSS.escape(targetId)}"]`
|
|
127
|
+
);
|
|
128
|
+
if (!panel) {
|
|
129
|
+
const index = Array.from(tabBtns).indexOf(btn);
|
|
130
|
+
panel = tabPanels[index] || null;
|
|
131
|
+
}
|
|
132
|
+
if (panel) {
|
|
133
|
+
if (hidePanelClasses.length)
|
|
134
|
+
panel.classList.remove(...hidePanelClasses);
|
|
135
|
+
if (showPanelClasses.length) panel.classList.add(...showPanelClasses);
|
|
136
|
+
setActivePanelA11y(panel, true);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const activateByKey = (key) => {
|
|
141
|
+
if (!key) return false;
|
|
142
|
+
const tabBtns = getTabBtns();
|
|
143
|
+
const btn = tabBtns.find((b) => b.getAttribute("data-tabs-btn") === key);
|
|
144
|
+
if (!btn) return false;
|
|
145
|
+
activate(btn);
|
|
146
|
+
return true;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const activateDefault = () => {
|
|
150
|
+
const tabBtns = getTabBtns();
|
|
151
|
+
if (tabBtns.length === 0) return;
|
|
152
|
+
const presetActive = tabBtns.find((b) => b.classList.contains("active"));
|
|
153
|
+
const initBtn = presetActive || tabBtns[defaultIndex] || tabBtns[0];
|
|
154
|
+
if (initBtn) activate(initBtn);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const syncAndActivate = () => {
|
|
158
|
+
syncBindings();
|
|
159
|
+
if (!activateByKey(state.activeKey || "")) {
|
|
160
|
+
activateDefault();
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
root.addEventListener(
|
|
165
|
+
"click",
|
|
166
|
+
(event) => {
|
|
167
|
+
const el = event.target;
|
|
168
|
+
const btn = el?.closest?.("[data-tabs-btn]");
|
|
169
|
+
if (!btn) return;
|
|
170
|
+
if (!root.contains(btn)) return;
|
|
171
|
+
activate(btn);
|
|
172
|
+
},
|
|
173
|
+
{ signal }
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
let rafId = null;
|
|
177
|
+
const observer = new MutationObserver(() => {
|
|
178
|
+
if (rafId != null) return;
|
|
179
|
+
rafId = (window.requestAnimationFrame || ((cb) => setTimeout(cb, 16)))(() => {
|
|
180
|
+
rafId = null;
|
|
181
|
+
syncAndActivate();
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
observer.observe(root, {
|
|
185
|
+
childList: true,
|
|
186
|
+
subtree: true,
|
|
187
|
+
attributes: true,
|
|
188
|
+
attributeFilter: ["data-tabs-btn", "data-tabs-panel"],
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
syncAndActivate();
|
|
192
|
+
|
|
193
|
+
return () => {
|
|
194
|
+
ac.abort();
|
|
195
|
+
observer.disconnect();
|
|
196
|
+
if (typeof rafId === "number") {
|
|
197
|
+
if (typeof window.cancelAnimationFrame === "function") {
|
|
198
|
+
window.cancelAnimationFrame(rafId);
|
|
199
|
+
}
|
|
200
|
+
clearTimeout(rafId);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const boot = () => {
|
|
206
|
+
const state = getState();
|
|
207
|
+
state.cleanup?.();
|
|
208
|
+
state.cleanup = initTabs(state);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
if (document.readyState === "loading") {
|
|
212
|
+
document.addEventListener("DOMContentLoaded", boot, { once: true });
|
|
213
|
+
} else {
|
|
214
|
+
boot();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
document.addEventListener("astro:page-load", boot);
|
|
218
|
+
document.addEventListener("astro:after-swap", boot);
|
|
219
|
+
window.addEventListener("astro:before-swap", () => getState().cleanup?.());
|
|
220
|
+
</script>
|
package/components/Video.astro
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
ReactVideoPlayer,
|
|
5
5
|
type Locals,
|
|
6
6
|
} from "@rxdrag/website-lib-core";
|
|
7
|
-
import { getImage } from "astro:assets";
|
|
8
7
|
|
|
9
8
|
const { env, imageSizes } = Astro.locals as Locals;
|
|
10
9
|
|
|
@@ -15,6 +14,7 @@ interface Props {
|
|
|
15
14
|
eagerLoad?: boolean;
|
|
16
15
|
classNames?: {
|
|
17
16
|
container?: string;
|
|
17
|
+
aspect?: string;
|
|
18
18
|
video?: string;
|
|
19
19
|
playButton?: string;
|
|
20
20
|
playButtonOuter?: string;
|
|
@@ -53,7 +53,7 @@ if (poster) {
|
|
|
53
53
|
---
|
|
54
54
|
|
|
55
55
|
{
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
<ReactVideoPlayer
|
|
58
58
|
client:load
|
|
59
59
|
media={media}
|
|
@@ -61,6 +61,8 @@ if (poster) {
|
|
|
61
61
|
posterUrl={posterUrl}
|
|
62
62
|
eagerLoad={eagerLoad}
|
|
63
63
|
classNames={classNames}
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
>
|
|
65
|
+
<slot />
|
|
66
|
+
</ReactVideoPlayer>
|
|
67
|
+
|
|
66
68
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
---
|
|
2
|
-
interface Props {
|
|
3
|
-
startYear?: number;
|
|
4
|
-
minYears?: number;
|
|
5
|
-
offset?: number;
|
|
6
|
-
suffix?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
startYear = 2006,
|
|
11
|
-
minYears = 20,
|
|
12
|
-
offset = 0,
|
|
13
|
-
suffix = "+",
|
|
14
|
-
} = Astro.props;
|
|
15
|
-
|
|
16
|
-
const currentYear = new Date().getFullYear();
|
|
17
|
-
const years = Math.max(minYears, currentYear - startYear + offset);
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
{years}{suffix}
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
startYear?: number;
|
|
4
|
+
minYears?: number;
|
|
5
|
+
offset?: number;
|
|
6
|
+
suffix?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
startYear = 2006,
|
|
11
|
+
minYears = 20,
|
|
12
|
+
offset = 0,
|
|
13
|
+
suffix = "+",
|
|
14
|
+
} = Astro.props;
|
|
15
|
+
|
|
16
|
+
const currentYear = new Date().getFullYear();
|
|
17
|
+
const years = Math.max(minYears, currentYear - startYear + offset);
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
{years}{suffix}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
| 层级 | 是否冻结 | 负责什么 | AI 能不能改 |
|
|
2
|
-
| ----------------------- | --------- | -------------------------- | ------- |
|
|
3
|
-
| **结构层(Structure)** | ✅ 冻结 | Grid / Flex / DOM 层级 | ❌ 不允许 |
|
|
4
|
-
| **语义层(Semantic)** | ✅ 冻结 | Hero / Feature / CTA 含义 | ❌ 不允许 |
|
|
5
|
-
| **装饰层(Decoration)** | ❌ 不冻结 | 颜色 / 阴影 / 动画 / 圆角 | ✅ 受控允许 |
|
|
1
|
+
| 层级 | 是否冻结 | 负责什么 | AI 能不能改 |
|
|
2
|
+
| ----------------------- | --------- | -------------------------- | ------- |
|
|
3
|
+
| **结构层(Structure)** | ✅ 冻结 | Grid / Flex / DOM 层级 | ❌ 不允许 |
|
|
4
|
+
| **语义层(Semantic)** | ✅ 冻结 | Hero / Feature / CTA 含义 | ❌ 不允许 |
|
|
5
|
+
| **装饰层(Decoration)** | ❌ 不冻结 | 颜色 / 阴影 / 动画 / 圆角 | ✅ 受控允许 |
|