sibujs 1.0.0-beta.4 → 1.0.0-beta.5
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 +18 -20
- package/dist/browser.cjs +6 -3
- package/dist/browser.js +17 -440
- package/dist/build.cjs +51 -10
- package/dist/build.js +10 -8
- package/dist/cdn.global.js +4 -4
- package/dist/chunk-2X5NDXNG.js +877 -0
- package/dist/chunk-353KB3DI.js +271 -0
- package/dist/chunk-6BCDNGIH.js +1839 -0
- package/dist/chunk-6BDUQJ7K.js +949 -0
- package/dist/chunk-6DJQF4Z7.js +33 -0
- package/dist/chunk-BS5EYKCJ.js +26 -0
- package/dist/chunk-CHJ27IGK.js +26 -0
- package/dist/chunk-DKXVN442.js +90 -0
- package/dist/chunk-DZZMIMGL.js +725 -0
- package/dist/chunk-E6BNBVMK.js +457 -0
- package/dist/chunk-GVDEIJ3G.js +291 -0
- package/dist/chunk-HGKEBAW3.js +63 -0
- package/dist/chunk-HJNW3HLI.js +255 -0
- package/dist/chunk-JLOASJXU.js +654 -0
- package/dist/chunk-K5ZUMYVS.js +89 -0
- package/dist/chunk-K7JUDY3C.js +364 -0
- package/dist/chunk-MWE3PK5S.js +551 -0
- package/dist/chunk-MXR7LXGC.js +1084 -0
- package/dist/chunk-QI6ZDDUR.js +35 -0
- package/dist/chunk-UKDBQVM3.js +346 -0
- package/dist/chunk-USPT25TC.js +365 -0
- package/dist/chunk-WGCQNOEQ.js +712 -0
- package/dist/chunk-XFW7B23S.js +282 -0
- package/dist/data.cjs +11 -3
- package/dist/data.js +26 -920
- package/dist/devtools.js +36 -1046
- package/dist/ecosystem.cjs +6 -3
- package/dist/ecosystem.d.cts +1 -14
- package/dist/ecosystem.d.ts +1 -14
- package/dist/ecosystem.js +16 -356
- package/dist/extras.cjs +1102 -998
- package/dist/extras.d.cts +15 -2356
- package/dist/extras.d.ts +15 -2356
- package/dist/extras.js +337 -4925
- package/dist/index.cjs +51 -10
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +14 -10
- package/dist/motion.js +21 -323
- package/dist/patterns.cjs +16 -5
- package/dist/patterns.d.cts +8 -0
- package/dist/patterns.d.ts +8 -0
- package/dist/patterns.js +15 -251
- package/dist/performance.js +36 -616
- package/dist/plugin-Bek4RhJY.d.cts +43 -0
- package/dist/plugin-Bek4RhJY.d.ts +43 -0
- package/dist/plugins.cjs +914 -36
- package/dist/plugins.d.cts +6 -2
- package/dist/plugins.d.ts +6 -2
- package/dist/plugins.js +106 -36
- package/dist/ssr-NFAIHWJJ.js +35 -0
- package/dist/ssr.cjs +17 -10
- package/dist/ssr.d.cts +209 -209
- package/dist/ssr.d.ts +209 -209
- package/dist/ssr.js +32 -685
- package/dist/startup-0Qv6aosO.d.cts +291 -0
- package/dist/startup-0Qv6aosO.d.ts +291 -0
- package/dist/ui.cjs +26 -13
- package/dist/ui.js +43 -826
- package/dist/widgets.cjs +42 -5
- package/dist/widgets.js +14 -531
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -671,7 +671,7 @@ function App() {
|
|
|
671
671
|
${RouterLink({ to: "/", nodes: "Home" })}
|
|
672
672
|
${RouterLink({ to: "/about", nodes: "About" })}
|
|
673
673
|
</nav>
|
|
674
|
-
${
|
|
674
|
+
${Route()}
|
|
675
675
|
</div>`;
|
|
676
676
|
}
|
|
677
677
|
|
|
@@ -751,22 +751,20 @@ can("RETRY"); // false (not in error state)
|
|
|
751
751
|
```ts
|
|
752
752
|
import { form, required, email, minLength } from "sibujs/ui";
|
|
753
753
|
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
email: { initial: "", validators: [required(), email()] },
|
|
758
|
-
},
|
|
759
|
-
onSubmit: (values) => api.register(values),
|
|
754
|
+
const myForm = form({
|
|
755
|
+
username: { initial: "", validators: [required(), minLength(3)] },
|
|
756
|
+
email: { initial: "", validators: [required(), email()] },
|
|
760
757
|
});
|
|
761
758
|
|
|
762
759
|
// Reactive getters
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
760
|
+
myForm.fields.username.value();
|
|
761
|
+
myForm.fields.username.error();
|
|
762
|
+
myForm.isValid();
|
|
763
|
+
myForm.isDirty();
|
|
767
764
|
|
|
768
|
-
// Handle submission
|
|
769
|
-
|
|
765
|
+
// Handle submission (pass callback to handleSubmit)
|
|
766
|
+
const onSubmit = myForm.handleSubmit((values) => api.register(values));
|
|
767
|
+
// Attach to form: on: { submit: onSubmit }
|
|
770
768
|
```
|
|
771
769
|
|
|
772
770
|
### Global Store
|
|
@@ -780,7 +778,7 @@ const store = globalStore({
|
|
|
780
778
|
increment: (state) => ({ ...state, count: state.count + 1 }),
|
|
781
779
|
setUser: (state, user) => ({ ...state, user }),
|
|
782
780
|
},
|
|
783
|
-
middleware: [(action,
|
|
781
|
+
middleware: [(state, action, payload, next) => { console.log(action, state); next(); }],
|
|
784
782
|
});
|
|
785
783
|
|
|
786
784
|
store.dispatch("increment");
|
|
@@ -1418,7 +1416,7 @@ import {
|
|
|
1418
1416
|
startTransition,
|
|
1419
1417
|
deferredValue,
|
|
1420
1418
|
transitionState,
|
|
1421
|
-
|
|
1419
|
+
uniqueId,
|
|
1422
1420
|
scheduleUpdate,
|
|
1423
1421
|
yieldToMain,
|
|
1424
1422
|
processInChunks,
|
|
@@ -1437,7 +1435,7 @@ const deferredQuery = deferredValue(() => query());
|
|
|
1437
1435
|
const [isPending, startTransition] = transitionState();
|
|
1438
1436
|
|
|
1439
1437
|
// Unique IDs (SSR-safe)
|
|
1440
|
-
const
|
|
1438
|
+
const myId = uniqueId(); // "sibu-0"
|
|
1441
1439
|
const labelId = uniqueId("label"); // "sibu-1-label"
|
|
1442
1440
|
|
|
1443
1441
|
// Priority-based scheduling
|
|
@@ -1461,7 +1459,7 @@ await processInChunks(bigArray, (item) => processItem(item), 50);
|
|
|
1461
1459
|
import {
|
|
1462
1460
|
enableDebug,
|
|
1463
1461
|
debugLog,
|
|
1464
|
-
|
|
1462
|
+
perfTracker,
|
|
1465
1463
|
measureRender,
|
|
1466
1464
|
getPerformanceReport,
|
|
1467
1465
|
checkLeaks,
|
|
@@ -1474,7 +1472,7 @@ debugLog("Counter", "increment", { value: 5 });
|
|
|
1474
1472
|
const MeasuredList = measureRender("ItemList", ItemList);
|
|
1475
1473
|
|
|
1476
1474
|
// Manual performance tracking
|
|
1477
|
-
const perf =
|
|
1475
|
+
const perf = perfTracker("search");
|
|
1478
1476
|
perf.startMeasure();
|
|
1479
1477
|
// ... expensive operation
|
|
1480
1478
|
perf.endMeasure();
|
|
@@ -1557,7 +1555,7 @@ const theme = createTheme({ colors: { primary: "#007bff" } });
|
|
|
1557
1555
|
|
|
1558
1556
|
---
|
|
1559
1557
|
|
|
1560
|
-
## Build (`
|
|
1558
|
+
## Build (`sibujs/build`)
|
|
1561
1559
|
|
|
1562
1560
|
Bundler plugins and deployment utilities.
|
|
1563
1561
|
|
|
@@ -1575,7 +1573,7 @@ Additional build utilities: CDN deployment, type declaration generation, bundle
|
|
|
1575
1573
|
|
|
1576
1574
|
---
|
|
1577
1575
|
|
|
1578
|
-
## Testing (`
|
|
1576
|
+
## Testing (`sibujs/testing`)
|
|
1579
1577
|
|
|
1580
1578
|
Component testing utilities, accessibility testing, E2E helpers, snapshot testing, and visual regression support. Works with Vitest, Jest, and Playwright.
|
|
1581
1579
|
|
package/dist/browser.cjs
CHANGED
|
@@ -58,9 +58,12 @@ function track(effectFn, subscriber) {
|
|
|
58
58
|
}
|
|
59
59
|
subscriberStack[stackTop] = subscriber;
|
|
60
60
|
currentSubscriber = subscriber;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
try {
|
|
62
|
+
effectFn();
|
|
63
|
+
} finally {
|
|
64
|
+
stackTop--;
|
|
65
|
+
currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
|
|
66
|
+
}
|
|
64
67
|
return () => cleanup(subscriber);
|
|
65
68
|
}
|
|
66
69
|
function suspendTracking() {
|
package/dist/browser.js
CHANGED
|
@@ -1,445 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
battery,
|
|
3
|
+
clipboard,
|
|
4
|
+
colorScheme,
|
|
5
|
+
draggable,
|
|
6
|
+
dropZone,
|
|
7
|
+
geo,
|
|
8
|
+
idle,
|
|
9
|
+
media,
|
|
10
|
+
online,
|
|
11
|
+
permissions,
|
|
12
|
+
resize,
|
|
13
|
+
scroll,
|
|
14
|
+
title
|
|
15
|
+
} from "./chunk-E6BNBVMK.js";
|
|
16
|
+
import "./chunk-6DJQF4Z7.js";
|
|
17
|
+
import "./chunk-CHJ27IGK.js";
|
|
18
|
+
import "./chunk-K7JUDY3C.js";
|
|
8
19
|
import "./chunk-MLKGABMK.js";
|
|
9
|
-
|
|
10
|
-
// src/browser/media.ts
|
|
11
|
-
function media(query) {
|
|
12
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
13
|
-
const [matches2] = signal(false);
|
|
14
|
-
return { matches: matches2, dispose: () => {
|
|
15
|
-
} };
|
|
16
|
-
}
|
|
17
|
-
const mql = window.matchMedia(query);
|
|
18
|
-
const [matches, setMatches] = signal(mql.matches);
|
|
19
|
-
const handler = (event) => {
|
|
20
|
-
setMatches(event.matches);
|
|
21
|
-
};
|
|
22
|
-
mql.addEventListener("change", handler);
|
|
23
|
-
function dispose() {
|
|
24
|
-
mql.removeEventListener("change", handler);
|
|
25
|
-
}
|
|
26
|
-
return { matches, dispose };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// src/browser/resize.ts
|
|
30
|
-
function resize(target) {
|
|
31
|
-
const [width, setWidth] = signal(0);
|
|
32
|
-
const [height, setHeight] = signal(0);
|
|
33
|
-
let observer = null;
|
|
34
|
-
if (typeof window === "undefined" || typeof ResizeObserver === "undefined") {
|
|
35
|
-
return { width, height, dispose: () => {
|
|
36
|
-
} };
|
|
37
|
-
}
|
|
38
|
-
const cleanup = effect(() => {
|
|
39
|
-
const el = target();
|
|
40
|
-
if (observer) {
|
|
41
|
-
observer.disconnect();
|
|
42
|
-
observer = null;
|
|
43
|
-
}
|
|
44
|
-
if (!el) return;
|
|
45
|
-
observer = new ResizeObserver((entries) => {
|
|
46
|
-
const entry = entries[0];
|
|
47
|
-
if (entry) {
|
|
48
|
-
batch(() => {
|
|
49
|
-
setWidth(entry.contentRect.width);
|
|
50
|
-
setHeight(entry.contentRect.height);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
observer.observe(el);
|
|
55
|
-
});
|
|
56
|
-
function dispose() {
|
|
57
|
-
cleanup();
|
|
58
|
-
if (observer) {
|
|
59
|
-
observer.disconnect();
|
|
60
|
-
observer = null;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return { width, height, dispose };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/browser/scroll.ts
|
|
67
|
-
function scroll(target) {
|
|
68
|
-
const [x, setX] = signal(0);
|
|
69
|
-
const [y, setY] = signal(0);
|
|
70
|
-
const [isScrolling, setIsScrolling] = signal(false);
|
|
71
|
-
let scrollTimer = null;
|
|
72
|
-
if (typeof window === "undefined") {
|
|
73
|
-
return { x, y, isScrolling, dispose: () => {
|
|
74
|
-
} };
|
|
75
|
-
}
|
|
76
|
-
const handler = () => {
|
|
77
|
-
const el = target ? target() : null;
|
|
78
|
-
batch(() => {
|
|
79
|
-
if (el) {
|
|
80
|
-
setX(el.scrollLeft);
|
|
81
|
-
setY(el.scrollTop);
|
|
82
|
-
} else {
|
|
83
|
-
setX(window.scrollX ?? window.pageXOffset ?? 0);
|
|
84
|
-
setY(window.scrollY ?? window.pageYOffset ?? 0);
|
|
85
|
-
}
|
|
86
|
-
setIsScrolling(true);
|
|
87
|
-
});
|
|
88
|
-
if (scrollTimer !== null) clearTimeout(scrollTimer);
|
|
89
|
-
scrollTimer = setTimeout(() => {
|
|
90
|
-
setIsScrolling(false);
|
|
91
|
-
scrollTimer = null;
|
|
92
|
-
}, 150);
|
|
93
|
-
};
|
|
94
|
-
const scrollTarget = target ? target() : null;
|
|
95
|
-
const eventTarget = scrollTarget || window;
|
|
96
|
-
eventTarget.addEventListener("scroll", handler, { passive: true });
|
|
97
|
-
function dispose() {
|
|
98
|
-
eventTarget.removeEventListener("scroll", handler);
|
|
99
|
-
if (scrollTimer !== null) {
|
|
100
|
-
clearTimeout(scrollTimer);
|
|
101
|
-
scrollTimer = null;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return { x, y, isScrolling, dispose };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// src/browser/online.ts
|
|
108
|
-
function online() {
|
|
109
|
-
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
110
|
-
const [online3] = signal(true);
|
|
111
|
-
return { online: online3, dispose: () => {
|
|
112
|
-
} };
|
|
113
|
-
}
|
|
114
|
-
const [online2, setOnline] = signal(navigator.onLine);
|
|
115
|
-
const onOnline = () => setOnline(true);
|
|
116
|
-
const onOffline = () => setOnline(false);
|
|
117
|
-
window.addEventListener("online", onOnline);
|
|
118
|
-
window.addEventListener("offline", onOffline);
|
|
119
|
-
function dispose() {
|
|
120
|
-
window.removeEventListener("online", onOnline);
|
|
121
|
-
window.removeEventListener("offline", onOffline);
|
|
122
|
-
}
|
|
123
|
-
return { online: online2, dispose };
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// src/browser/geo.ts
|
|
127
|
-
function geo(options) {
|
|
128
|
-
const [latitude, setLatitude] = signal(null);
|
|
129
|
-
const [longitude, setLongitude] = signal(null);
|
|
130
|
-
const [accuracy, setAccuracy] = signal(null);
|
|
131
|
-
const [error, setError] = signal(null);
|
|
132
|
-
let watchId = null;
|
|
133
|
-
if (typeof navigator !== "undefined" && navigator.geolocation) {
|
|
134
|
-
watchId = navigator.geolocation.watchPosition(
|
|
135
|
-
(position) => {
|
|
136
|
-
batch(() => {
|
|
137
|
-
setLatitude(position.coords.latitude);
|
|
138
|
-
setLongitude(position.coords.longitude);
|
|
139
|
-
setAccuracy(position.coords.accuracy);
|
|
140
|
-
setError(null);
|
|
141
|
-
});
|
|
142
|
-
},
|
|
143
|
-
(err) => {
|
|
144
|
-
setError(err);
|
|
145
|
-
},
|
|
146
|
-
options
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
function dispose() {
|
|
150
|
-
if (watchId !== null && typeof navigator !== "undefined" && navigator.geolocation) {
|
|
151
|
-
navigator.geolocation.clearWatch(watchId);
|
|
152
|
-
watchId = null;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return { latitude, longitude, accuracy, error, dispose };
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// src/browser/battery.ts
|
|
159
|
-
function battery() {
|
|
160
|
-
const [level, setLevel] = signal(null);
|
|
161
|
-
const [charging, setCharging] = signal(null);
|
|
162
|
-
const [chargingTime, setChargingTime] = signal(null);
|
|
163
|
-
const [dischargingTime, setDischargingTime] = signal(null);
|
|
164
|
-
const [supported, setSupported] = signal(false);
|
|
165
|
-
let battery2 = null;
|
|
166
|
-
let onLevelChange = null;
|
|
167
|
-
let onChargingChange = null;
|
|
168
|
-
let onChargingTimeChange = null;
|
|
169
|
-
let onDischargingTimeChange = null;
|
|
170
|
-
let disposed = false;
|
|
171
|
-
if (typeof navigator !== "undefined" && "getBattery" in navigator) {
|
|
172
|
-
setSupported(true);
|
|
173
|
-
navigator.getBattery().then((bm) => {
|
|
174
|
-
if (disposed) return;
|
|
175
|
-
battery2 = bm;
|
|
176
|
-
batch(() => {
|
|
177
|
-
setLevel(bm.level);
|
|
178
|
-
setCharging(bm.charging);
|
|
179
|
-
setChargingTime(bm.chargingTime);
|
|
180
|
-
setDischargingTime(bm.dischargingTime);
|
|
181
|
-
});
|
|
182
|
-
onLevelChange = () => setLevel(bm.level);
|
|
183
|
-
onChargingChange = () => setCharging(bm.charging);
|
|
184
|
-
onChargingTimeChange = () => setChargingTime(bm.chargingTime);
|
|
185
|
-
onDischargingTimeChange = () => setDischargingTime(bm.dischargingTime);
|
|
186
|
-
bm.addEventListener("levelchange", onLevelChange);
|
|
187
|
-
bm.addEventListener("chargingchange", onChargingChange);
|
|
188
|
-
bm.addEventListener("chargingtimechange", onChargingTimeChange);
|
|
189
|
-
bm.addEventListener("dischargingtimechange", onDischargingTimeChange);
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
function dispose() {
|
|
193
|
-
disposed = true;
|
|
194
|
-
if (battery2) {
|
|
195
|
-
if (onLevelChange) battery2.removeEventListener("levelchange", onLevelChange);
|
|
196
|
-
if (onChargingChange) battery2.removeEventListener("chargingchange", onChargingChange);
|
|
197
|
-
if (onChargingTimeChange) battery2.removeEventListener("chargingtimechange", onChargingTimeChange);
|
|
198
|
-
if (onDischargingTimeChange) battery2.removeEventListener("dischargingtimechange", onDischargingTimeChange);
|
|
199
|
-
battery2 = null;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return { level, charging, chargingTime, dischargingTime, supported, dispose };
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// src/browser/idle.ts
|
|
206
|
-
var ACTIVITY_EVENTS = ["mousemove", "mousedown", "keydown", "touchstart", "scroll"];
|
|
207
|
-
function idle(timeout = 6e4) {
|
|
208
|
-
const [idle2, setIdle] = signal(false);
|
|
209
|
-
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
210
|
-
return { idle: idle2, dispose: () => {
|
|
211
|
-
} };
|
|
212
|
-
}
|
|
213
|
-
let timer = null;
|
|
214
|
-
function resetTimer() {
|
|
215
|
-
setIdle(false);
|
|
216
|
-
if (timer !== null) clearTimeout(timer);
|
|
217
|
-
timer = setTimeout(() => {
|
|
218
|
-
setIdle(true);
|
|
219
|
-
}, timeout);
|
|
220
|
-
}
|
|
221
|
-
for (const event of ACTIVITY_EVENTS) {
|
|
222
|
-
document.addEventListener(event, resetTimer, { passive: true });
|
|
223
|
-
}
|
|
224
|
-
resetTimer();
|
|
225
|
-
function dispose() {
|
|
226
|
-
if (timer !== null) {
|
|
227
|
-
clearTimeout(timer);
|
|
228
|
-
timer = null;
|
|
229
|
-
}
|
|
230
|
-
for (const event of ACTIVITY_EVENTS) {
|
|
231
|
-
document.removeEventListener(event, resetTimer);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return { idle: idle2, dispose };
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// src/browser/permissions.ts
|
|
238
|
-
function permissions(name) {
|
|
239
|
-
const [state, setState] = signal("prompt");
|
|
240
|
-
let permissionStatus = null;
|
|
241
|
-
let onChange = null;
|
|
242
|
-
let disposed = false;
|
|
243
|
-
if (typeof navigator === "undefined" || !navigator.permissions) {
|
|
244
|
-
setState("unsupported");
|
|
245
|
-
return { state, dispose: () => {
|
|
246
|
-
} };
|
|
247
|
-
}
|
|
248
|
-
navigator.permissions.query({ name }).then((status) => {
|
|
249
|
-
if (disposed) return;
|
|
250
|
-
permissionStatus = status;
|
|
251
|
-
setState(status.state);
|
|
252
|
-
onChange = () => {
|
|
253
|
-
setState(status.state);
|
|
254
|
-
};
|
|
255
|
-
status.addEventListener("change", onChange);
|
|
256
|
-
}).catch(() => {
|
|
257
|
-
setState("unsupported");
|
|
258
|
-
});
|
|
259
|
-
function dispose() {
|
|
260
|
-
disposed = true;
|
|
261
|
-
if (permissionStatus && onChange) {
|
|
262
|
-
permissionStatus.removeEventListener("change", onChange);
|
|
263
|
-
permissionStatus = null;
|
|
264
|
-
onChange = null;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return { state, dispose };
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// src/browser/clipboard.ts
|
|
271
|
-
function clipboard() {
|
|
272
|
-
const [text, setText] = signal("");
|
|
273
|
-
const [copied, setCopied] = signal(false);
|
|
274
|
-
let copiedTimer = null;
|
|
275
|
-
async function copy(value) {
|
|
276
|
-
if (typeof navigator === "undefined" || !navigator.clipboard) {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
await navigator.clipboard.writeText(value);
|
|
280
|
-
setText(value);
|
|
281
|
-
setCopied(true);
|
|
282
|
-
if (copiedTimer !== null) clearTimeout(copiedTimer);
|
|
283
|
-
copiedTimer = setTimeout(() => {
|
|
284
|
-
setCopied(false);
|
|
285
|
-
copiedTimer = null;
|
|
286
|
-
}, 2e3);
|
|
287
|
-
}
|
|
288
|
-
function dispose() {
|
|
289
|
-
if (copiedTimer !== null) {
|
|
290
|
-
clearTimeout(copiedTimer);
|
|
291
|
-
copiedTimer = null;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
return { text, copy, copied, dispose };
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// src/browser/dragDrop.ts
|
|
298
|
-
function draggable(element, data) {
|
|
299
|
-
const [isDragging, setIsDragging] = signal(false);
|
|
300
|
-
if (typeof window === "undefined") {
|
|
301
|
-
return { isDragging, dispose: () => {
|
|
302
|
-
} };
|
|
303
|
-
}
|
|
304
|
-
let currentEl = null;
|
|
305
|
-
let onDragStart = null;
|
|
306
|
-
let onDragEnd = null;
|
|
307
|
-
const cleanup = effect(() => {
|
|
308
|
-
if (currentEl && onDragStart && onDragEnd) {
|
|
309
|
-
currentEl.removeEventListener("dragstart", onDragStart);
|
|
310
|
-
currentEl.removeEventListener("dragend", onDragEnd);
|
|
311
|
-
}
|
|
312
|
-
const el = element();
|
|
313
|
-
currentEl = el;
|
|
314
|
-
if (!el) return;
|
|
315
|
-
el.draggable = true;
|
|
316
|
-
onDragStart = (e) => {
|
|
317
|
-
setIsDragging(true);
|
|
318
|
-
if (e.dataTransfer && data !== void 0) {
|
|
319
|
-
e.dataTransfer.setData("application/json", JSON.stringify(data));
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
onDragEnd = () => {
|
|
323
|
-
setIsDragging(false);
|
|
324
|
-
};
|
|
325
|
-
el.addEventListener("dragstart", onDragStart);
|
|
326
|
-
el.addEventListener("dragend", onDragEnd);
|
|
327
|
-
});
|
|
328
|
-
function dispose() {
|
|
329
|
-
cleanup();
|
|
330
|
-
if (currentEl && onDragStart && onDragEnd) {
|
|
331
|
-
currentEl.removeEventListener("dragstart", onDragStart);
|
|
332
|
-
currentEl.removeEventListener("dragend", onDragEnd);
|
|
333
|
-
currentEl = null;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return { isDragging, dispose };
|
|
337
|
-
}
|
|
338
|
-
function dropZone(element, options) {
|
|
339
|
-
const [isOver, setIsOver] = signal(false);
|
|
340
|
-
if (typeof window === "undefined") {
|
|
341
|
-
return { isOver, dispose: () => {
|
|
342
|
-
} };
|
|
343
|
-
}
|
|
344
|
-
let currentEl = null;
|
|
345
|
-
let onDragOver = null;
|
|
346
|
-
let onDragEnter = null;
|
|
347
|
-
let onDragLeave = null;
|
|
348
|
-
let onDrop = null;
|
|
349
|
-
const cleanup = effect(() => {
|
|
350
|
-
if (currentEl && onDragOver && onDragEnter && onDragLeave && onDrop) {
|
|
351
|
-
currentEl.removeEventListener("dragover", onDragOver);
|
|
352
|
-
currentEl.removeEventListener("dragenter", onDragEnter);
|
|
353
|
-
currentEl.removeEventListener("dragleave", onDragLeave);
|
|
354
|
-
currentEl.removeEventListener("drop", onDrop);
|
|
355
|
-
}
|
|
356
|
-
const el = element();
|
|
357
|
-
currentEl = el;
|
|
358
|
-
if (!el) return;
|
|
359
|
-
onDragOver = (e) => {
|
|
360
|
-
e.preventDefault();
|
|
361
|
-
};
|
|
362
|
-
onDragEnter = (e) => {
|
|
363
|
-
e.preventDefault();
|
|
364
|
-
setIsOver(true);
|
|
365
|
-
};
|
|
366
|
-
onDragLeave = () => {
|
|
367
|
-
setIsOver(false);
|
|
368
|
-
};
|
|
369
|
-
onDrop = (e) => {
|
|
370
|
-
e.preventDefault();
|
|
371
|
-
setIsOver(false);
|
|
372
|
-
let transferData = null;
|
|
373
|
-
if (e.dataTransfer) {
|
|
374
|
-
const raw = e.dataTransfer.getData("application/json");
|
|
375
|
-
if (raw) {
|
|
376
|
-
try {
|
|
377
|
-
transferData = JSON.parse(raw);
|
|
378
|
-
} catch {
|
|
379
|
-
transferData = raw;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
options.onDrop(transferData, e);
|
|
384
|
-
};
|
|
385
|
-
el.addEventListener("dragover", onDragOver);
|
|
386
|
-
el.addEventListener("dragenter", onDragEnter);
|
|
387
|
-
el.addEventListener("dragleave", onDragLeave);
|
|
388
|
-
el.addEventListener("drop", onDrop);
|
|
389
|
-
});
|
|
390
|
-
function dispose() {
|
|
391
|
-
cleanup();
|
|
392
|
-
if (currentEl && onDragOver && onDragEnter && onDragLeave && onDrop) {
|
|
393
|
-
currentEl.removeEventListener("dragover", onDragOver);
|
|
394
|
-
currentEl.removeEventListener("dragenter", onDragEnter);
|
|
395
|
-
currentEl.removeEventListener("dragleave", onDragLeave);
|
|
396
|
-
currentEl.removeEventListener("drop", onDrop);
|
|
397
|
-
currentEl = null;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return { isOver, dispose };
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// src/browser/title.ts
|
|
404
|
-
function title(value) {
|
|
405
|
-
if (typeof document === "undefined") {
|
|
406
|
-
return () => {
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
const previousTitle = document.title;
|
|
410
|
-
if (typeof value === "function") {
|
|
411
|
-
const cleanup = effect(() => {
|
|
412
|
-
document.title = value();
|
|
413
|
-
});
|
|
414
|
-
return () => {
|
|
415
|
-
cleanup();
|
|
416
|
-
document.title = previousTitle;
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
document.title = value;
|
|
420
|
-
return () => {
|
|
421
|
-
document.title = previousTitle;
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// src/browser/colorScheme.ts
|
|
426
|
-
function colorScheme() {
|
|
427
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
428
|
-
const [scheme2] = signal("light");
|
|
429
|
-
return { scheme: scheme2, dispose: () => {
|
|
430
|
-
} };
|
|
431
|
-
}
|
|
432
|
-
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
433
|
-
const [scheme, setScheme] = signal(mql.matches ? "dark" : "light");
|
|
434
|
-
const handler = (event) => {
|
|
435
|
-
setScheme(event.matches ? "dark" : "light");
|
|
436
|
-
};
|
|
437
|
-
mql.addEventListener("change", handler);
|
|
438
|
-
function dispose() {
|
|
439
|
-
mql.removeEventListener("change", handler);
|
|
440
|
-
}
|
|
441
|
-
return { scheme, dispose };
|
|
442
|
-
}
|
|
443
20
|
export {
|
|
444
21
|
battery,
|
|
445
22
|
clipboard,
|