@rxdrag/website-lib 0.0.103 → 0.0.105

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/index.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  // Do not write code directly here, instead use the `src` folder!
2
2
  // Then, use this file to export everything you want your user to access.
3
3
 
4
- export * from './src/index';
4
+ export {};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@rxdrag/website-lib",
3
- "version": "0.0.103",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.ts",
7
- "./components/*": "./src/components/*.astro"
7
+ "./components/*": "./components/*.astro"
8
8
  },
9
9
  "files": [
10
10
  "src",
@@ -26,19 +26,19 @@
26
26
  "eslint": "^7.32.0",
27
27
  "gsap": "^3.12.7",
28
28
  "typescript": "^5",
29
- "@rxdrag/rxcms-models": "0.3.96",
30
29
  "@rxdrag/entify-hooks": "0.2.77",
31
- "@rxdrag/eslint-config-custom": "0.2.12",
32
30
  "@rxdrag/slate-preview": "1.2.63",
33
- "@rxdrag/tsconfig": "0.2.0"
31
+ "@rxdrag/rxcms-models": "0.3.96",
32
+ "@rxdrag/tsconfig": "0.2.0",
33
+ "@rxdrag/eslint-config-custom": "0.2.12"
34
34
  },
35
35
  "dependencies": {
36
36
  "aos": "3.0.0-beta.6",
37
37
  "clsx": "^2.1.0",
38
38
  "react": "^19.1.0",
39
39
  "react-dom": "^19.1.0",
40
- "@rxdrag/website-lib-core": "0.0.104",
41
- "@rxdrag/rxcms-models": "0.3.96"
40
+ "@rxdrag/rxcms-models": "0.3.96",
41
+ "@rxdrag/website-lib-core": "0.0.104"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "astro": "^4.0.0 || ^5.0.0"
@@ -1,218 +0,0 @@
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>
@@ -1,106 +0,0 @@
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
- }
@@ -1,21 +0,0 @@
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>
@@ -1,25 +0,0 @@
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>
@@ -1,125 +0,0 @@
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>
@@ -1,20 +0,0 @@
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>
@@ -1,13 +0,0 @@
1
- ---
2
- interface Props {
3
- //布局
4
- className?: string;
5
- class?: string;
6
- }
7
-
8
- const { className, class: classAttr, ...rest } = Astro.props;
9
- ---
10
-
11
- <div class:list={["section-container", className, classAttr]} {...rest}>
12
- <slot />
13
- </div>