@swiftbrowser/react 0.18.1 → 0.18.3
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 +137 -5
- package/dist/appleSignIn.d.ts +53 -0
- package/dist/appleSignIn.d.ts.map +1 -0
- package/dist/components/controls.d.ts +6 -1
- package/dist/components/controls.d.ts.map +1 -1
- package/dist/components/geometry.d.ts +6 -1
- package/dist/components/geometry.d.ts.map +1 -1
- package/dist/components/menus.d.ts.map +1 -1
- package/dist/components/text.d.ts.map +1 -1
- package/dist/environment.d.ts +16 -2
- package/dist/environment.d.ts.map +1 -1
- package/dist/fileExporter.d.ts +31 -0
- package/dist/fileExporter.d.ts.map +1 -0
- package/dist/fileManager.d.ts +17 -2
- package/dist/fileManager.d.ts.map +1 -1
- package/dist/fileStorage.d.ts +25 -0
- package/dist/fileStorage.d.ts.map +1 -0
- package/dist/geolocation.d.ts +44 -0
- package/dist/geolocation.d.ts.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +742 -309
- package/dist/index.js.map +1 -1
- package/dist/modifiers.d.ts +19 -1
- package/dist/modifiers.d.ts.map +1 -1
- package/dist/mount.d.ts +2 -1
- package/dist/mount.d.ts.map +1 -1
- package/dist/speech.d.ts +52 -0
- package/dist/speech.d.ts.map +1 -0
- package/dist/wakeLock.d.ts +11 -0
- package/dist/wakeLock.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4,10 +4,12 @@ import Reconciler from "react-reconciler";
|
|
|
4
4
|
import { horizontalSizeClassFor } from "@swiftbrowser/web/src/protocol";
|
|
5
5
|
import { BrowserHistory } from "@swiftbrowser/web/src/browserHistory";
|
|
6
6
|
import { watchKeyboard } from "@swiftbrowser/web/src/deviceMode";
|
|
7
|
-
import { browserEnvironment, loadableURL, performHostRequest } from "@swiftbrowser/web/src/hostRequests";
|
|
7
|
+
import { browserEnvironment, exportFiles, loadableURL, performHostRequest } from "@swiftbrowser/web/src/hostRequests";
|
|
8
8
|
import { Renderer } from "@swiftbrowser/web/src/renderer";
|
|
9
|
+
import { currentScenePhase, watchScenePhase } from "@swiftbrowser/web/src/scenePhase";
|
|
9
10
|
import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
|
|
10
11
|
import { applyTypeSizeVariables } from "@swiftbrowser/web/src/typography";
|
|
12
|
+
import { configureSignInWithApple } from "@swiftbrowser/web/src/appleSignIn";
|
|
11
13
|
import { fileURL } from "@swiftbrowser/web/src/files";
|
|
12
14
|
import { registerHostContent, notifyHostContentChange, unregisterHostContent } from "@swiftbrowser/web/src/hostContent";
|
|
13
15
|
import { createRoot } from "react-dom/client";
|
|
@@ -28,7 +30,8 @@ function EnvironmentExtender({ values, children }) {
|
|
|
28
30
|
const EnvironmentContext = createContext({
|
|
29
31
|
colorScheme: "light",
|
|
30
32
|
dynamicTypeSize: "large",
|
|
31
|
-
horizontalSizeClass: "compact"
|
|
33
|
+
horizontalSizeClass: "compact",
|
|
34
|
+
scenePhase: "active"
|
|
32
35
|
});
|
|
33
36
|
function EnvironmentProvider({ value, children }) {
|
|
34
37
|
return createElement(EnvironmentContext.Provider, { value }, children);
|
|
@@ -48,6 +51,9 @@ function useDismiss() {
|
|
|
48
51
|
function useHorizontalSizeClass() {
|
|
49
52
|
return useContext(EnvironmentContext).horizontalSizeClass;
|
|
50
53
|
}
|
|
54
|
+
function useScenePhase() {
|
|
55
|
+
return useContext(EnvironmentContext).scenePhase;
|
|
56
|
+
}
|
|
51
57
|
function useRedacted() {
|
|
52
58
|
return useContext(ViewEnvironmentContext).redacted === true;
|
|
53
59
|
}
|
|
@@ -392,7 +398,7 @@ function deepEqual(a, b) {
|
|
|
392
398
|
if (keys.length !== Object.keys(right).length) return false;
|
|
393
399
|
return keys.every((key) => key in right && deepEqual(left[key], right[key]));
|
|
394
400
|
}
|
|
395
|
-
const DEFAULT_ENVIRONMENT = { colorScheme: "light", dynamicTypeSize: "large", horizontalSizeClass: "compact" };
|
|
401
|
+
const DEFAULT_ENVIRONMENT = { colorScheme: "light", dynamicTypeSize: "large", horizontalSizeClass: "compact", scenePhase: "active" };
|
|
396
402
|
const roots = /* @__PURE__ */ new Set();
|
|
397
403
|
function createSwiftUIRoot(sink) {
|
|
398
404
|
const tree = new HostTree(sink);
|
|
@@ -647,7 +653,8 @@ function mount(screen, element, options = {}) {
|
|
|
647
653
|
const environment = {
|
|
648
654
|
colorScheme: pageScheme,
|
|
649
655
|
dynamicTypeSize: options.dynamicTypeSize ?? "large",
|
|
650
|
-
horizontalSizeClass: horizontalSizeClassFor(screen.clientWidth || 393)
|
|
656
|
+
horizontalSizeClass: horizontalSizeClassFor(screen.clientWidth || 393),
|
|
657
|
+
scenePhase: typeof document !== "undefined" ? currentScenePhase() : "active"
|
|
651
658
|
};
|
|
652
659
|
renderer.contentHeight = options.contentHeight ?? false;
|
|
653
660
|
if (options.assets) renderer.setAssetCatalog(options.assets);
|
|
@@ -679,6 +686,7 @@ function mount(screen, element, options = {}) {
|
|
|
679
686
|
root.setEnvironment({ horizontalSizeClass: next });
|
|
680
687
|
}) : null;
|
|
681
688
|
observer?.observe(screen);
|
|
689
|
+
const stopScenePhase = typeof document !== "undefined" ? watchScenePhase((scenePhase) => root.setEnvironment({ scenePhase })) : null;
|
|
682
690
|
root.render(element);
|
|
683
691
|
const mounted = {
|
|
684
692
|
root,
|
|
@@ -691,6 +699,7 @@ function mount(screen, element, options = {}) {
|
|
|
691
699
|
},
|
|
692
700
|
unmount() {
|
|
693
701
|
observer?.disconnect();
|
|
702
|
+
stopScenePhase?.();
|
|
694
703
|
stopKeyboard?.();
|
|
695
704
|
browserHistory?.dispose();
|
|
696
705
|
screen.removeEventListener("sb:color-scheme", onPreferredScheme);
|
|
@@ -1112,6 +1121,61 @@ function FileImporterPresenter(spec) {
|
|
|
1112
1121
|
}, [presented, setPresented]);
|
|
1113
1122
|
return null;
|
|
1114
1123
|
}
|
|
1124
|
+
const EXTENSIONS = {
|
|
1125
|
+
"text/plain": "txt",
|
|
1126
|
+
"text/csv": "csv",
|
|
1127
|
+
"text/markdown": "md",
|
|
1128
|
+
"text/html": "html",
|
|
1129
|
+
"application/json": "json",
|
|
1130
|
+
"application/pdf": "pdf",
|
|
1131
|
+
"image/png": "png",
|
|
1132
|
+
"image/jpeg": "jpg",
|
|
1133
|
+
"image/svg+xml": "svg",
|
|
1134
|
+
"audio/mp4": "m4a",
|
|
1135
|
+
"video/mp4": "mp4"
|
|
1136
|
+
};
|
|
1137
|
+
function exportFile(document2, contentType, defaultFilename, index = 0) {
|
|
1138
|
+
const type = document2 instanceof Blob && document2.type || contentType || "application/octet-stream";
|
|
1139
|
+
let name = defaultFilename ?? (document2 instanceof File ? document2.name : index === 0 ? "Untitled" : `Untitled ${index + 1}`);
|
|
1140
|
+
name = name.replace(/[\\/:*?"<>|]+/g, "-").trim() || "Untitled";
|
|
1141
|
+
const extension = EXTENSIONS[type.split(";")[0].trim()];
|
|
1142
|
+
if (extension && !/\.[A-Za-z0-9]{1,8}$/.test(name)) name = `${name}.${extension}`;
|
|
1143
|
+
if (document2 instanceof File && document2.name === name && document2.type === type) return document2;
|
|
1144
|
+
const bytes = typeof document2 === "string" ? new TextEncoder().encode(document2) : document2;
|
|
1145
|
+
return new File([bytes], name, { type });
|
|
1146
|
+
}
|
|
1147
|
+
function FileExporterPresenter(spec) {
|
|
1148
|
+
const [presented, setPresented] = readBinding(spec.isPresented);
|
|
1149
|
+
const latest = useRef(spec);
|
|
1150
|
+
latest.current = spec;
|
|
1151
|
+
const exporting = useRef(false);
|
|
1152
|
+
useLayoutEffect(() => {
|
|
1153
|
+
if (!presented || exporting.current) return;
|
|
1154
|
+
const { document: document2, contentType, defaultFilename } = latest.current;
|
|
1155
|
+
const documents = document2 === null ? [] : Array.isArray(document2) ? document2 : [document2];
|
|
1156
|
+
if (documents.length === 0) {
|
|
1157
|
+
setPresented(false);
|
|
1158
|
+
latest.current.onCancellation?.();
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
exporting.current = true;
|
|
1162
|
+
const files = documents.map((item, index) => exportFile(item, contentType, defaultFilename, index));
|
|
1163
|
+
exportFiles(files).then(
|
|
1164
|
+
(result) => {
|
|
1165
|
+
exporting.current = false;
|
|
1166
|
+
setPresented(false);
|
|
1167
|
+
if (result.outcome === "cancelled") latest.current.onCancellation?.();
|
|
1168
|
+
else latest.current.onCompletion?.(result);
|
|
1169
|
+
},
|
|
1170
|
+
(error) => {
|
|
1171
|
+
exporting.current = false;
|
|
1172
|
+
setPresented(false);
|
|
1173
|
+
latest.current.onError?.(error);
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1176
|
+
}, [presented, setPresented]);
|
|
1177
|
+
return null;
|
|
1178
|
+
}
|
|
1115
1179
|
const isPoint = (value) => typeof value === "object" && value !== null && ("x" in value || "y" in value);
|
|
1116
1180
|
function command(request) {
|
|
1117
1181
|
return request.axes ? { anchor: request.anchor, serial: request.serial, axes: request.axes } : { anchor: request.anchor, serial: request.serial };
|
|
@@ -1653,7 +1717,7 @@ function Label(props) {
|
|
|
1653
1717
|
if (style === "titleOnly") return applyModifiers(title, modifiers);
|
|
1654
1718
|
return applyModifiers(
|
|
1655
1719
|
/* @__PURE__ */ jsxs(HStack, { spacing: 8, children: [
|
|
1656
|
-
styled({ labelIcon: true }, icon),
|
|
1720
|
+
style === "titleAndIcon" ? icon : styled({ labelIcon: true }, icon),
|
|
1657
1721
|
title
|
|
1658
1722
|
] }),
|
|
1659
1723
|
modifiers
|
|
@@ -2136,6 +2200,7 @@ const MODIFIER_KEYS = /* @__PURE__ */ new Set([
|
|
|
2136
2200
|
"magnifyGesture",
|
|
2137
2201
|
"rotateGesture",
|
|
2138
2202
|
"onLongPressGesture",
|
|
2203
|
+
"onTouches",
|
|
2139
2204
|
"simultaneousGesture",
|
|
2140
2205
|
"highPriorityGesture",
|
|
2141
2206
|
"contextMenu",
|
|
@@ -2188,6 +2253,7 @@ const MODIFIER_KEYS = /* @__PURE__ */ new Set([
|
|
|
2188
2253
|
"safeAreaInset",
|
|
2189
2254
|
"popover",
|
|
2190
2255
|
"fileImporter",
|
|
2256
|
+
"fileExporter",
|
|
2191
2257
|
"redacted",
|
|
2192
2258
|
"keyboardShortcut",
|
|
2193
2259
|
"onKeyPress",
|
|
@@ -2577,6 +2643,10 @@ function apply(key, value, node, sides) {
|
|
|
2577
2643
|
case "rotateGesture":
|
|
2578
2644
|
case "onLongPressGesture":
|
|
2579
2645
|
return gesture(key, value, node);
|
|
2646
|
+
case "onTouches": {
|
|
2647
|
+
const handler = value;
|
|
2648
|
+
return sb("touches", {}, { touches: (event) => handler(event.touches, event.phase) }, node);
|
|
2649
|
+
}
|
|
2580
2650
|
case "simultaneousGesture":
|
|
2581
2651
|
case "highPriorityGesture": {
|
|
2582
2652
|
const mode = key === "simultaneousGesture" ? "simultaneous" : "highPriority";
|
|
@@ -2747,6 +2817,9 @@ function apply(key, value, node, sides) {
|
|
|
2747
2817
|
case "fileImporter":
|
|
2748
2818
|
sides.push(createElement(FileImporterPresenter, value));
|
|
2749
2819
|
return node;
|
|
2820
|
+
case "fileExporter":
|
|
2821
|
+
sides.push(createElement(FileExporterPresenter, value));
|
|
2822
|
+
return node;
|
|
2750
2823
|
case "redacted":
|
|
2751
2824
|
return withEnvironment({ redacted: Boolean(value) }, node);
|
|
2752
2825
|
case "keyboardShortcut":
|
|
@@ -2880,10 +2953,10 @@ function GeometryChangeView({ handler, children }) {
|
|
|
2880
2953
|
});
|
|
2881
2954
|
const heard = reported !== NO_GEOMETRY;
|
|
2882
2955
|
const value = heard && typeof handler !== "function" ? handler.of(proxy) : void 0;
|
|
2883
|
-
|
|
2956
|
+
useLayoutEffect(() => {
|
|
2884
2957
|
if (readFrame && !needsFrame) setNeedsFrame(true);
|
|
2885
2958
|
});
|
|
2886
|
-
|
|
2959
|
+
useLayoutEffect(() => {
|
|
2887
2960
|
if (!heard) return;
|
|
2888
2961
|
if (typeof handler === "function") {
|
|
2889
2962
|
handler(proxy);
|
|
@@ -3501,175 +3574,53 @@ function useAudioRecorder(options = {}) {
|
|
|
3501
3574
|
);
|
|
3502
3575
|
return { available: host !== void 0, status, time, levels, error, record, pause, resume, stop, cancel, discard, trim };
|
|
3503
3576
|
}
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
if (!entries) {
|
|
3508
|
-
entries = /* @__PURE__ */ new Map();
|
|
3509
|
-
stores.set(store, entries);
|
|
3510
|
-
if (store === pageStorage) watchOtherTabs();
|
|
3511
|
-
}
|
|
3512
|
-
let entry = entries.get(key);
|
|
3513
|
-
if (!entry) {
|
|
3514
|
-
let raw = null;
|
|
3515
|
-
try {
|
|
3516
|
-
raw = store.getItem(key);
|
|
3517
|
-
} catch {
|
|
3518
|
-
}
|
|
3519
|
-
entry = { raw, value: void 0, decoded: false, decode: void 0, listeners: /* @__PURE__ */ new Set() };
|
|
3520
|
-
entries.set(key, entry);
|
|
3521
|
-
}
|
|
3522
|
-
return entry;
|
|
3523
|
-
}
|
|
3524
|
-
function valueOf(entry, absent) {
|
|
3525
|
-
if (entry.raw === null) return absent;
|
|
3526
|
-
if (!entry.decoded) {
|
|
3527
|
-
try {
|
|
3528
|
-
const parsed = JSON.parse(entry.raw);
|
|
3529
|
-
entry.value = entry.decode ? entry.decode(parsed) : parsed;
|
|
3530
|
-
} catch {
|
|
3531
|
-
entry.raw = null;
|
|
3532
|
-
return absent;
|
|
3533
|
-
}
|
|
3534
|
-
entry.decoded = true;
|
|
3535
|
-
}
|
|
3536
|
-
return entry.value;
|
|
3537
|
-
}
|
|
3538
|
-
function notify(entry) {
|
|
3539
|
-
for (const listener of [...entry.listeners]) listener();
|
|
3540
|
-
}
|
|
3541
|
-
function invalidate(entry, raw) {
|
|
3542
|
-
if (entry.raw === raw && entry.decoded) return;
|
|
3543
|
-
entry.raw = raw;
|
|
3544
|
-
entry.decoded = false;
|
|
3545
|
-
notify(entry);
|
|
3546
|
-
}
|
|
3547
|
-
function readPageStorage() {
|
|
3548
|
-
try {
|
|
3549
|
-
const storage = globalThis.localStorage;
|
|
3550
|
-
return storage && typeof storage.getItem === "function" ? storage : null;
|
|
3551
|
-
} catch {
|
|
3552
|
-
return null;
|
|
3553
|
-
}
|
|
3577
|
+
function wakeLockAPI() {
|
|
3578
|
+
const nav = globalThis.navigator;
|
|
3579
|
+
return nav?.wakeLock ?? null;
|
|
3554
3580
|
}
|
|
3555
|
-
|
|
3556
|
-
const
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
const appStorage = pageStorage ?? memoryStorage;
|
|
3563
|
-
let watching = false;
|
|
3564
|
-
function watchOtherTabs() {
|
|
3565
|
-
if (watching || !pageStorage) return;
|
|
3566
|
-
watching = true;
|
|
3567
|
-
const target = globalThis;
|
|
3568
|
-
if (typeof target.addEventListener !== "function") return;
|
|
3569
|
-
target.addEventListener("storage", (event) => {
|
|
3570
|
-
if (event.storageArea !== pageStorage) return;
|
|
3571
|
-
const entries = stores.get(pageStorage);
|
|
3572
|
-
if (!entries) return;
|
|
3573
|
-
if (event.key === null) {
|
|
3574
|
-
for (const entry of entries.values()) invalidate(entry, null);
|
|
3575
|
-
} else {
|
|
3576
|
-
const entry = entries.get(event.key);
|
|
3577
|
-
if (entry) invalidate(entry, event.newValue);
|
|
3581
|
+
function useWakeLock(active2 = true) {
|
|
3582
|
+
const [held, setHeld] = useState(false);
|
|
3583
|
+
useEffect(() => {
|
|
3584
|
+
const api = wakeLockAPI();
|
|
3585
|
+
if (!active2 || !api) {
|
|
3586
|
+
setHeld(false);
|
|
3587
|
+
return;
|
|
3578
3588
|
}
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
[store, key, fallback, onError]
|
|
3614
|
-
);
|
|
3615
|
-
return [value, set];
|
|
3616
|
-
}
|
|
3617
|
-
const NONE = {
|
|
3618
|
-
documents: "file:///data/Documents",
|
|
3619
|
-
applicationSupport: "file:///data/Library/Application%20Support",
|
|
3620
|
-
caches: "file:///data/Library/Caches",
|
|
3621
|
-
temporary: "file:///tmp"
|
|
3622
|
-
};
|
|
3623
|
-
async function bytesOf(contents) {
|
|
3624
|
-
if (typeof contents === "string") return new TextEncoder().encode(contents);
|
|
3625
|
-
if (contents instanceof Uint8Array) return contents;
|
|
3626
|
-
if (contents instanceof ArrayBuffer) return new Uint8Array(contents);
|
|
3627
|
-
const blob = contents;
|
|
3628
|
-
if (typeof blob.bytes === "function") return await blob.bytes();
|
|
3629
|
-
return new Uint8Array(await blob.arrayBuffer());
|
|
3630
|
-
}
|
|
3631
|
-
function createFileManager(host) {
|
|
3632
|
-
const required = () => {
|
|
3633
|
-
const files = host();
|
|
3634
|
-
if (!files) throw new Error("unsupported: this page keeps no files");
|
|
3635
|
-
return files;
|
|
3636
|
-
};
|
|
3637
|
-
const directories = () => host()?.directories ?? NONE;
|
|
3638
|
-
return {
|
|
3639
|
-
get available() {
|
|
3640
|
-
return host() !== void 0;
|
|
3641
|
-
},
|
|
3642
|
-
get documentsDirectory() {
|
|
3643
|
-
return directories().documents;
|
|
3644
|
-
},
|
|
3645
|
-
get applicationSupportDirectory() {
|
|
3646
|
-
return directories().applicationSupport;
|
|
3647
|
-
},
|
|
3648
|
-
get cachesDirectory() {
|
|
3649
|
-
return directories().caches;
|
|
3650
|
-
},
|
|
3651
|
-
get temporaryDirectory() {
|
|
3652
|
-
return directories().temporary;
|
|
3653
|
-
},
|
|
3654
|
-
url: (directory, path) => fileURL(directory, path),
|
|
3655
|
-
contents: async (url) => required().read(url),
|
|
3656
|
-
text: async (url) => new TextDecoder().decode(await required().read(url)),
|
|
3657
|
-
write: async (url, contents) => required().write(url, await bytesOf(contents)),
|
|
3658
|
-
contentsOfDirectory: async (url) => required().list(url),
|
|
3659
|
-
createDirectory: async (url) => required().createDirectory(url),
|
|
3660
|
-
fileExists: async (url) => await required().attributes(url) !== null,
|
|
3661
|
-
attributesOfItem: async (url) => {
|
|
3662
|
-
const attributes = await required().attributes(url);
|
|
3663
|
-
if (!attributes) throw new Error(`notFound: nothing at ${url}`);
|
|
3664
|
-
return attributes;
|
|
3665
|
-
},
|
|
3666
|
-
moveItem: async (from, to) => required().move(from, to),
|
|
3667
|
-
copyItem: async (from, to) => required().copy(from, to),
|
|
3668
|
-
removeItem: async (url) => required().remove(url),
|
|
3669
|
-
loadURL: async (url) => required().loadURL(url)
|
|
3670
|
-
};
|
|
3589
|
+
let sentinel = null;
|
|
3590
|
+
let stopped = false;
|
|
3591
|
+
const acquire = () => {
|
|
3592
|
+
if (stopped || sentinel && !sentinel.released) return;
|
|
3593
|
+
api.request("screen").then(
|
|
3594
|
+
(next) => {
|
|
3595
|
+
if (stopped) {
|
|
3596
|
+
void next.release();
|
|
3597
|
+
return;
|
|
3598
|
+
}
|
|
3599
|
+
sentinel = next;
|
|
3600
|
+
setHeld(true);
|
|
3601
|
+
next.addEventListener("release", () => {
|
|
3602
|
+
if (sentinel === next) setHeld(false);
|
|
3603
|
+
});
|
|
3604
|
+
},
|
|
3605
|
+
() => setHeld(false)
|
|
3606
|
+
);
|
|
3607
|
+
};
|
|
3608
|
+
const onVisible = () => {
|
|
3609
|
+
if (typeof document === "undefined" || document.visibilityState === "visible") acquire();
|
|
3610
|
+
};
|
|
3611
|
+
acquire();
|
|
3612
|
+
const doc = typeof document !== "undefined" ? document : null;
|
|
3613
|
+
doc?.addEventListener("visibilitychange", onVisible);
|
|
3614
|
+
return () => {
|
|
3615
|
+
stopped = true;
|
|
3616
|
+
doc?.removeEventListener("visibilitychange", onVisible);
|
|
3617
|
+
if (sentinel && !sentinel.released) void sentinel.release();
|
|
3618
|
+
sentinel = null;
|
|
3619
|
+
setHeld(false);
|
|
3620
|
+
};
|
|
3621
|
+
}, [active2]);
|
|
3622
|
+
return held;
|
|
3671
3623
|
}
|
|
3672
|
-
const fileManager = createFileManager(() => browserEnvironment.files);
|
|
3673
3624
|
function Button(props) {
|
|
3674
3625
|
const { own, modifiers } = splitProps(props);
|
|
3675
3626
|
const environment = useViewEnvironment();
|
|
@@ -3881,7 +3832,8 @@ function ProgressView(props) {
|
|
|
3881
3832
|
}
|
|
3882
3833
|
function ToolbarItem(props) {
|
|
3883
3834
|
const hidden = props.sharedBackgroundVisibility === "hidden";
|
|
3884
|
-
|
|
3835
|
+
const items = withEnvironment({ labelStyle: "iconOnly" }, props.children);
|
|
3836
|
+
return sb("toolbar", hidden ? { placement: toolbarPlacement(props.placement), sharedBackground: "hidden" } : { placement: toolbarPlacement(props.placement) }, void 0, items);
|
|
3885
3837
|
}
|
|
3886
3838
|
const ToolbarItemGroup = ToolbarItem;
|
|
3887
3839
|
function ToolbarSpacer(props) {
|
|
@@ -3932,140 +3884,19 @@ function TextEditor(props) {
|
|
|
3932
3884
|
function buttonDisabled(modifiers) {
|
|
3933
3885
|
return modifiers.some(([key, value]) => key === "disabled" && value === true);
|
|
3934
3886
|
}
|
|
3935
|
-
const
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
const
|
|
3939
|
-
const
|
|
3940
|
-
const
|
|
3941
|
-
if (
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
if (
|
|
3947
|
-
|
|
3948
|
-
if (value instanceof Set) listProps["multiSelect"] = true;
|
|
3949
|
-
selected = value instanceof Set ? value.size > 0 : value !== null && value !== void 0;
|
|
3950
|
-
clearSelection = () => setValue(value instanceof Set ? /* @__PURE__ */ new Set() : null);
|
|
3951
|
-
selection = {
|
|
3952
|
-
editing,
|
|
3953
|
-
isSelected: (tag) => value instanceof Set ? value.has(tag) : value !== null && Object.is(value, tag),
|
|
3954
|
-
select: (tag) => {
|
|
3955
|
-
if (value instanceof Set) {
|
|
3956
|
-
const next = new Set(value);
|
|
3957
|
-
if (next.has(tag)) next.delete(tag);
|
|
3958
|
-
else next.add(tag);
|
|
3959
|
-
setValue(next);
|
|
3960
|
-
} else {
|
|
3961
|
-
setValue(editing && Object.is(value, tag) ? null : tag);
|
|
3962
|
-
}
|
|
3963
|
-
}
|
|
3964
|
-
};
|
|
3965
|
-
}
|
|
3966
|
-
useReportSplitSelection(split, selected, clearSelection, own.selection !== void 0);
|
|
3967
|
-
const refresh = useRefreshable(takeModifier(modifiers, "refreshable"));
|
|
3968
|
-
Object.assign(listProps, refresh.props);
|
|
3969
|
-
const ownSettings = takeScrollSettings(modifiers);
|
|
3970
|
-
const edgeEffect = edgeEffectProp(useScrollSettings(ownSettings));
|
|
3971
|
-
if (edgeEffect) listProps["edgeEffect"] = edgeEffect;
|
|
3972
|
-
const element = /* @__PURE__ */ jsx(LazyContext.Provider, { value: "vertical", children: sb("list", listProps, refresh.handlers, providingScrollSettings(ownSettings, wrapRows(own.children))) });
|
|
3973
|
-
return applyModifiers(
|
|
3974
|
-
selection ? /* @__PURE__ */ jsx(ListSelectionContext.Provider, { value: selection, children: element }) : element,
|
|
3975
|
-
modifiers
|
|
3976
|
-
);
|
|
3977
|
-
}
|
|
3978
|
-
function Form(props) {
|
|
3979
|
-
return /* @__PURE__ */ jsx(List, { ...props });
|
|
3980
|
-
}
|
|
3981
|
-
function Section(props) {
|
|
3982
|
-
const { own, modifiers } = splitProps(props);
|
|
3983
|
-
const pinned = useContext(PinnedContext);
|
|
3984
|
-
let header = supplement(own.header);
|
|
3985
|
-
let footer = supplement(own.footer);
|
|
3986
|
-
if (pinned?.includes("sectionHeaders") && header.text !== null && !header.view) header = { text: null, view: /* @__PURE__ */ jsx(Text, { children: header.text }) };
|
|
3987
|
-
if (pinned?.includes("sectionFooters") && footer.text !== null && !footer.view) footer = { text: null, view: /* @__PURE__ */ jsx(Text, { children: footer.text }) };
|
|
3988
|
-
const children = [];
|
|
3989
|
-
if (header.view) children.push(sb("sectionheader", {}, void 0, header.view));
|
|
3990
|
-
if (own.children !== void 0) children.push(wrapRows(own.children));
|
|
3991
|
-
if (footer.view) children.push(sb("sectionfooter", {}, void 0, footer.view));
|
|
3992
|
-
return applyModifiers(sb("section", { header: header.text, footer: footer.text }, void 0, children), modifiers);
|
|
3993
|
-
}
|
|
3994
|
-
function wrapRows(children) {
|
|
3995
|
-
let offset = 0;
|
|
3996
|
-
return flattenChildren(children, { keepLazy: true }).map((element, index) => {
|
|
3997
|
-
const at = index + offset;
|
|
3998
|
-
if (element.type === LazyGroup) {
|
|
3999
|
-
const group = element.props;
|
|
4000
|
-
offset += group.rows.length - 1;
|
|
4001
|
-
return { ...withKey(element, index), props: { ...group, start: at, wrap: wrapRow } };
|
|
4002
|
-
}
|
|
4003
|
-
return wrapRow(withKey(element, index), at);
|
|
4004
|
-
});
|
|
4005
|
-
}
|
|
4006
|
-
function wrapRow(row, containerIndex) {
|
|
4007
|
-
const inner = row.type === Fragment ? flattenChildren(row) : null;
|
|
4008
|
-
const element = inner?.length === 1 ? { ...inner[0], key: row.key } : row;
|
|
4009
|
-
if (element.type === Section) return element;
|
|
4010
|
-
if (element.type === Row) return { ...element, props: { ...element.props, containerIndex } };
|
|
4011
|
-
const props = element.props;
|
|
4012
|
-
const tag = props.tag !== void 0 ? props.tag : element.type === NavigationLink ? props.value : void 0;
|
|
4013
|
-
if (tag === void 0) return element;
|
|
4014
|
-
return /* @__PURE__ */ jsx(Row, { tag, containerIndex, children: element }, element.key ?? containerIndex);
|
|
4015
|
-
}
|
|
4016
|
-
function withKey(element, index) {
|
|
4017
|
-
return element.key !== null ? element : { ...element, key: String(index) };
|
|
4018
|
-
}
|
|
4019
|
-
function supplement(node) {
|
|
4020
|
-
if (node === void 0 || node === null || node === false) return { text: null, view: null };
|
|
4021
|
-
if (typeof node === "string" || typeof node === "number") return { text: String(node), view: null };
|
|
4022
|
-
if (isValidElement(node) && node.type === Text) {
|
|
4023
|
-
const props = node.props;
|
|
4024
|
-
const only = Object.keys(props).every((key) => key === "children");
|
|
4025
|
-
if (only) return { text: plainText(node), view: null };
|
|
4026
|
-
}
|
|
4027
|
-
return { text: null, view: isValidElement(node) ? node : null };
|
|
4028
|
-
}
|
|
4029
|
-
function TabView(props) {
|
|
4030
|
-
const { own, modifiers } = splitProps(props);
|
|
4031
|
-
const tabs = flattenChildren(own.children);
|
|
4032
|
-
const tags = tabs.map((tab, index) => {
|
|
4033
|
-
const tag = tab.props.tag;
|
|
4034
|
-
return tag !== void 0 ? tag : index;
|
|
4035
|
-
});
|
|
4036
|
-
const [internal, setInternal] = useState(tags[0]);
|
|
4037
|
-
const [selection, setSelection] = own.selection !== void 0 ? readBinding(own.selection, own.onChange) : [internal, setInternal];
|
|
4038
|
-
const selected = Math.max(
|
|
4039
|
-
0,
|
|
4040
|
-
tags.findIndex((tag) => Object.is(tag, selection))
|
|
4041
|
-
);
|
|
4042
|
-
return applyModifiers(
|
|
4043
|
-
sb("tabview", { selected }, { select: (event) => tags[event.value] !== void 0 && setSelection(tags[event.value]) }, tabs),
|
|
4044
|
-
modifiers
|
|
4045
|
-
);
|
|
4046
|
-
}
|
|
4047
|
-
function Tab(props) {
|
|
4048
|
-
const { own, modifiers } = splitProps(props);
|
|
4049
|
-
const badge = takeModifier(modifiers, "badge");
|
|
4050
|
-
const tabProps = { title: own.title, systemImage: own.systemImage ?? null };
|
|
4051
|
-
if (badge !== void 0 && badge !== null) tabProps["badge"] = String(badge);
|
|
4052
|
-
if (own.role) tabProps["role"] = own.role;
|
|
4053
|
-
if (own.image && !own.systemImage) tabProps["image"] = own.image;
|
|
4054
|
-
return applyModifiers(sb("tab", tabProps, void 0, own.children), modifiers);
|
|
4055
|
-
}
|
|
4056
|
-
const STYLE_KEYS = ["r", "name", "named", "hierarchical", "linearGradient", "radialGradient", "angularGradient", "colorGradient", "material"];
|
|
4057
|
-
function strokeOf(value, inset) {
|
|
4058
|
-
if (value === void 0) return null;
|
|
4059
|
-
const isSpec = typeof value === "object" && value !== null && !STYLE_KEYS.some((key) => key in value);
|
|
4060
|
-
const spec = isSpec ? value : { style: value };
|
|
4061
|
-
const stroke = { color: shapeStyle(spec.style ?? "primary"), lineWidth: spec.lineWidth ?? 1 };
|
|
4062
|
-
if (inset) stroke.inset = true;
|
|
4063
|
-
if (spec.dash) stroke.dash = spec.dash;
|
|
4064
|
-
if (spec.dashPhase !== void 0) stroke.dashPhase = spec.dashPhase;
|
|
4065
|
-
if (spec.lineCap) stroke.lineCap = spec.lineCap;
|
|
4066
|
-
if (spec.lineJoin) stroke.lineJoin = spec.lineJoin;
|
|
4067
|
-
if (spec.miterLimit !== void 0) stroke.miterLimit = spec.miterLimit;
|
|
4068
|
-
return stroke;
|
|
3887
|
+
const STYLE_KEYS = ["r", "name", "named", "hierarchical", "linearGradient", "radialGradient", "angularGradient", "colorGradient", "material"];
|
|
3888
|
+
function strokeOf(value, inset) {
|
|
3889
|
+
if (value === void 0) return null;
|
|
3890
|
+
const isSpec = typeof value === "object" && value !== null && !STYLE_KEYS.some((key) => key in value);
|
|
3891
|
+
const spec = isSpec ? value : { style: value };
|
|
3892
|
+
const stroke = { color: shapeStyle(spec.style ?? "primary"), lineWidth: spec.lineWidth ?? 1 };
|
|
3893
|
+
if (inset) stroke.inset = true;
|
|
3894
|
+
if (spec.dash) stroke.dash = spec.dash;
|
|
3895
|
+
if (spec.dashPhase !== void 0) stroke.dashPhase = spec.dashPhase;
|
|
3896
|
+
if (spec.lineCap) stroke.lineCap = spec.lineCap;
|
|
3897
|
+
if (spec.lineJoin) stroke.lineJoin = spec.lineJoin;
|
|
3898
|
+
if (spec.miterLimit !== void 0) stroke.miterLimit = spec.miterLimit;
|
|
3899
|
+
return stroke;
|
|
4069
3900
|
}
|
|
4070
3901
|
function shape(kind, cornerRadius, props) {
|
|
4071
3902
|
const { own, modifiers } = splitProps(props);
|
|
@@ -4154,6 +3985,595 @@ function ColorView(props) {
|
|
|
4154
3985
|
return applyModifiers(sb("color", { color: color(own.color) }), modifiers);
|
|
4155
3986
|
}
|
|
4156
3987
|
const Color = Object.assign(ColorView, ColorValues);
|
|
3988
|
+
function canSignInWithApple() {
|
|
3989
|
+
return browserEnvironment.appleSignIn !== void 0;
|
|
3990
|
+
}
|
|
3991
|
+
async function signInWithApple(options = {}) {
|
|
3992
|
+
const host = browserEnvironment.appleSignIn;
|
|
3993
|
+
if (!host) throw new Error("unsupported: Sign in with Apple is not available here (configureSignInWithApple on a page)");
|
|
3994
|
+
return host.signIn({ scopes: options.scopes ?? ["fullName", "email"], ...options.nonce ? { nonce: options.nonce } : {}, ...options.state ? { state: options.state } : {} });
|
|
3995
|
+
}
|
|
3996
|
+
async function appleCredentialState(user) {
|
|
3997
|
+
const host = browserEnvironment.appleSignIn;
|
|
3998
|
+
if (!host) return "unknown";
|
|
3999
|
+
return host.credentialState(user);
|
|
4000
|
+
}
|
|
4001
|
+
const LABELS = { signIn: "Sign in with Apple", signUp: "Sign up with Apple", continue: "Continue with Apple" };
|
|
4002
|
+
function SignInWithAppleButton(props) {
|
|
4003
|
+
const { own, modifiers } = splitProps(props);
|
|
4004
|
+
const style = own.style ?? "black";
|
|
4005
|
+
const background = style === "black" ? "black" : "white";
|
|
4006
|
+
const foreground = style === "black" ? "white" : "black";
|
|
4007
|
+
const action = () => {
|
|
4008
|
+
signInWithApple({ ...own.scopes ? { scopes: own.scopes } : {}, ...own.nonce ? { nonce: own.nonce } : {}, ...own.state ? { state: own.state } : {} }).then(
|
|
4009
|
+
(credential) => own.onCompletion({ credential }),
|
|
4010
|
+
(error) => own.onCompletion({ error: error instanceof Error ? error : new Error(String(error)) })
|
|
4011
|
+
);
|
|
4012
|
+
};
|
|
4013
|
+
return /* @__PURE__ */ jsx(
|
|
4014
|
+
Button,
|
|
4015
|
+
{
|
|
4016
|
+
action,
|
|
4017
|
+
buttonStyle: "plain",
|
|
4018
|
+
foregroundStyle: foreground,
|
|
4019
|
+
background: /* @__PURE__ */ jsx(RoundedRectangle, { cornerRadius: 8, fill: background }),
|
|
4020
|
+
...style === "whiteOutline" ? { overlay: /* @__PURE__ */ jsx(RoundedRectangle, { cornerRadius: 8, strokeBorder: { style: "black", lineWidth: 1 } }) } : {},
|
|
4021
|
+
...Object.fromEntries(modifiers),
|
|
4022
|
+
children: /* @__PURE__ */ jsxs(HStack, { spacing: 6, frame: { maxWidth: Infinity, height: 50 }, font: system(19, "medium"), children: [
|
|
4023
|
+
/* @__PURE__ */ jsx(Image$1, { systemName: "apple.logo" }),
|
|
4024
|
+
/* @__PURE__ */ jsx(Text, { children: LABELS[own.label ?? "signIn"] })
|
|
4025
|
+
] })
|
|
4026
|
+
}
|
|
4027
|
+
);
|
|
4028
|
+
}
|
|
4029
|
+
function geolocationAPI() {
|
|
4030
|
+
const nav = globalThis.navigator;
|
|
4031
|
+
return nav?.geolocation ?? null;
|
|
4032
|
+
}
|
|
4033
|
+
function useGeolocation(options = {}) {
|
|
4034
|
+
const { watch = false, immediate = false, enableHighAccuracy = false, timeout, maximumAge } = options;
|
|
4035
|
+
const api = geolocationAPI();
|
|
4036
|
+
const [status, setStatus] = useState("idle");
|
|
4037
|
+
const [position, setPosition] = useState(null);
|
|
4038
|
+
const [error, setError] = useState(null);
|
|
4039
|
+
const watching2 = useRef(null);
|
|
4040
|
+
const mounted = useRef(true);
|
|
4041
|
+
const stop = useCallback(() => {
|
|
4042
|
+
if (watching2.current !== null) {
|
|
4043
|
+
geolocationAPI()?.clearWatch(watching2.current);
|
|
4044
|
+
watching2.current = null;
|
|
4045
|
+
}
|
|
4046
|
+
}, []);
|
|
4047
|
+
const request = useCallback(() => {
|
|
4048
|
+
const geo = geolocationAPI();
|
|
4049
|
+
if (!geo) {
|
|
4050
|
+
setStatus("failed");
|
|
4051
|
+
setError("geolocation: not available");
|
|
4052
|
+
return;
|
|
4053
|
+
}
|
|
4054
|
+
stop();
|
|
4055
|
+
setStatus("locating");
|
|
4056
|
+
setError(null);
|
|
4057
|
+
const positionOptions = { enableHighAccuracy, ...timeout !== void 0 ? { timeout } : {}, ...maximumAge !== void 0 ? { maximumAge } : {} };
|
|
4058
|
+
const onFix = (p) => {
|
|
4059
|
+
if (!mounted.current) return;
|
|
4060
|
+
setPosition({
|
|
4061
|
+
latitude: p.coords.latitude,
|
|
4062
|
+
longitude: p.coords.longitude,
|
|
4063
|
+
accuracy: p.coords.accuracy,
|
|
4064
|
+
altitude: p.coords.altitude ?? null,
|
|
4065
|
+
heading: p.coords.heading ?? null,
|
|
4066
|
+
speed: p.coords.speed ?? null,
|
|
4067
|
+
timestamp: p.timestamp
|
|
4068
|
+
});
|
|
4069
|
+
setStatus("located");
|
|
4070
|
+
setError(null);
|
|
4071
|
+
};
|
|
4072
|
+
const onError = (e) => {
|
|
4073
|
+
if (!mounted.current) return;
|
|
4074
|
+
setStatus(e.code === 1 ? "denied" : "failed");
|
|
4075
|
+
setError(e.message);
|
|
4076
|
+
if (e.code === 1) stop();
|
|
4077
|
+
};
|
|
4078
|
+
if (watch) watching2.current = geo.watchPosition(onFix, onError, positionOptions);
|
|
4079
|
+
else geo.getCurrentPosition(onFix, onError, positionOptions);
|
|
4080
|
+
}, [watch, enableHighAccuracy, timeout, maximumAge, stop]);
|
|
4081
|
+
useEffect(() => {
|
|
4082
|
+
mounted.current = true;
|
|
4083
|
+
if (immediate) request();
|
|
4084
|
+
return () => {
|
|
4085
|
+
mounted.current = false;
|
|
4086
|
+
stop();
|
|
4087
|
+
};
|
|
4088
|
+
}, [immediate, request, stop]);
|
|
4089
|
+
return { available: api !== null, status, position, error, request, stop };
|
|
4090
|
+
}
|
|
4091
|
+
function synthesisAPI() {
|
|
4092
|
+
const g = globalThis;
|
|
4093
|
+
return g.speechSynthesis && g.SpeechSynthesisUtterance ? { synthesis: g.speechSynthesis, Utterance: g.SpeechSynthesisUtterance } : null;
|
|
4094
|
+
}
|
|
4095
|
+
function useSpeechSynthesis() {
|
|
4096
|
+
const api = synthesisAPI();
|
|
4097
|
+
const [speaking, setSpeaking] = useState(false);
|
|
4098
|
+
const [paused, setPaused] = useState(false);
|
|
4099
|
+
const mounted = useRef(true);
|
|
4100
|
+
const queued = useRef(0);
|
|
4101
|
+
useEffect(() => {
|
|
4102
|
+
mounted.current = true;
|
|
4103
|
+
return () => {
|
|
4104
|
+
mounted.current = false;
|
|
4105
|
+
if (queued.current > 0) synthesisAPI()?.synthesis.cancel();
|
|
4106
|
+
};
|
|
4107
|
+
}, []);
|
|
4108
|
+
const speak = useCallback((text, options = {}) => {
|
|
4109
|
+
const current = synthesisAPI();
|
|
4110
|
+
if (!current) return;
|
|
4111
|
+
const utterance = new current.Utterance(text);
|
|
4112
|
+
if (options.lang) utterance.lang = options.lang;
|
|
4113
|
+
if (options.rate !== void 0) utterance.rate = options.rate;
|
|
4114
|
+
if (options.pitch !== void 0) utterance.pitch = options.pitch;
|
|
4115
|
+
if (options.volume !== void 0) utterance.volume = options.volume;
|
|
4116
|
+
queued.current++;
|
|
4117
|
+
const done = () => {
|
|
4118
|
+
queued.current = Math.max(0, queued.current - 1);
|
|
4119
|
+
if (!mounted.current) return;
|
|
4120
|
+
if (queued.current === 0) {
|
|
4121
|
+
setSpeaking(false);
|
|
4122
|
+
setPaused(false);
|
|
4123
|
+
}
|
|
4124
|
+
};
|
|
4125
|
+
utterance.onstart = () => {
|
|
4126
|
+
if (!mounted.current) return;
|
|
4127
|
+
setSpeaking(true);
|
|
4128
|
+
setPaused(false);
|
|
4129
|
+
};
|
|
4130
|
+
utterance.onpause = () => mounted.current && setPaused(true);
|
|
4131
|
+
utterance.onresume = () => mounted.current && setPaused(false);
|
|
4132
|
+
utterance.onend = done;
|
|
4133
|
+
utterance.onerror = done;
|
|
4134
|
+
current.synthesis.speak(utterance);
|
|
4135
|
+
}, []);
|
|
4136
|
+
const cancel = useCallback(() => {
|
|
4137
|
+
synthesisAPI()?.synthesis.cancel();
|
|
4138
|
+
}, []);
|
|
4139
|
+
const pause = useCallback(() => synthesisAPI()?.synthesis.pause(), []);
|
|
4140
|
+
const resume = useCallback(() => synthesisAPI()?.synthesis.resume(), []);
|
|
4141
|
+
return { available: api !== null, speaking, paused, speak, cancel, pause, resume };
|
|
4142
|
+
}
|
|
4143
|
+
function recognitionAPI() {
|
|
4144
|
+
const g = globalThis;
|
|
4145
|
+
return g.SpeechRecognition ?? g.webkitSpeechRecognition ?? null;
|
|
4146
|
+
}
|
|
4147
|
+
function useSpeechRecognition(options = {}) {
|
|
4148
|
+
const { lang, continuous = false, interimResults = true } = options;
|
|
4149
|
+
const api = recognitionAPI();
|
|
4150
|
+
const [listening, setListening] = useState(false);
|
|
4151
|
+
const [transcript, setTranscript] = useState("");
|
|
4152
|
+
const [interim, setInterim] = useState("");
|
|
4153
|
+
const [error, setError] = useState(null);
|
|
4154
|
+
const current = useRef(null);
|
|
4155
|
+
const mounted = useRef(true);
|
|
4156
|
+
useEffect(() => {
|
|
4157
|
+
mounted.current = true;
|
|
4158
|
+
return () => {
|
|
4159
|
+
mounted.current = false;
|
|
4160
|
+
current.current?.abort();
|
|
4161
|
+
current.current = null;
|
|
4162
|
+
};
|
|
4163
|
+
}, []);
|
|
4164
|
+
const start = useCallback(() => {
|
|
4165
|
+
const Recognition = recognitionAPI();
|
|
4166
|
+
if (!Recognition) {
|
|
4167
|
+
setError("not-allowed");
|
|
4168
|
+
return;
|
|
4169
|
+
}
|
|
4170
|
+
if (current.current) return;
|
|
4171
|
+
const recognition = new Recognition();
|
|
4172
|
+
if (lang) recognition.lang = lang;
|
|
4173
|
+
recognition.continuous = continuous;
|
|
4174
|
+
recognition.interimResults = interimResults;
|
|
4175
|
+
setTranscript("");
|
|
4176
|
+
setInterim("");
|
|
4177
|
+
setError(null);
|
|
4178
|
+
recognition.onstart = () => mounted.current && setListening(true);
|
|
4179
|
+
recognition.onresult = (e) => {
|
|
4180
|
+
if (!mounted.current) return;
|
|
4181
|
+
const finals = [];
|
|
4182
|
+
let heard = "";
|
|
4183
|
+
for (let i = 0; i < e.results.length; i++) {
|
|
4184
|
+
const result = e.results[i];
|
|
4185
|
+
if (result.isFinal) finals.push(result[0].transcript.trim());
|
|
4186
|
+
else heard = result[0].transcript;
|
|
4187
|
+
}
|
|
4188
|
+
setTranscript(finals.filter(Boolean).join(" "));
|
|
4189
|
+
setInterim(heard);
|
|
4190
|
+
};
|
|
4191
|
+
recognition.onerror = (e) => mounted.current && setError(e.error);
|
|
4192
|
+
recognition.onend = () => {
|
|
4193
|
+
if (current.current === recognition) current.current = null;
|
|
4194
|
+
if (!mounted.current) return;
|
|
4195
|
+
setListening(false);
|
|
4196
|
+
setInterim("");
|
|
4197
|
+
};
|
|
4198
|
+
current.current = recognition;
|
|
4199
|
+
recognition.start();
|
|
4200
|
+
}, [lang, continuous, interimResults]);
|
|
4201
|
+
const stop = useCallback(() => current.current?.stop(), []);
|
|
4202
|
+
const abort = useCallback(() => current.current?.abort(), []);
|
|
4203
|
+
return { available: api !== null, listening, transcript, interim, error, start, stop, abort };
|
|
4204
|
+
}
|
|
4205
|
+
const stores = /* @__PURE__ */ new WeakMap();
|
|
4206
|
+
function entryFor(store, key) {
|
|
4207
|
+
let entries = stores.get(store);
|
|
4208
|
+
if (!entries) {
|
|
4209
|
+
entries = /* @__PURE__ */ new Map();
|
|
4210
|
+
stores.set(store, entries);
|
|
4211
|
+
if (store === pageStorage) watchOtherTabs();
|
|
4212
|
+
}
|
|
4213
|
+
let entry = entries.get(key);
|
|
4214
|
+
if (!entry) {
|
|
4215
|
+
let raw = null;
|
|
4216
|
+
try {
|
|
4217
|
+
raw = store.getItem(key);
|
|
4218
|
+
} catch {
|
|
4219
|
+
}
|
|
4220
|
+
entry = { raw, value: void 0, decoded: false, decode: void 0, listeners: /* @__PURE__ */ new Set() };
|
|
4221
|
+
entries.set(key, entry);
|
|
4222
|
+
}
|
|
4223
|
+
return entry;
|
|
4224
|
+
}
|
|
4225
|
+
function valueOf(entry, absent) {
|
|
4226
|
+
if (entry.raw === null) return absent;
|
|
4227
|
+
if (!entry.decoded) {
|
|
4228
|
+
try {
|
|
4229
|
+
const parsed = JSON.parse(entry.raw);
|
|
4230
|
+
entry.value = entry.decode ? entry.decode(parsed) : parsed;
|
|
4231
|
+
} catch {
|
|
4232
|
+
entry.raw = null;
|
|
4233
|
+
return absent;
|
|
4234
|
+
}
|
|
4235
|
+
entry.decoded = true;
|
|
4236
|
+
}
|
|
4237
|
+
return entry.value;
|
|
4238
|
+
}
|
|
4239
|
+
function notify(entry) {
|
|
4240
|
+
for (const listener of [...entry.listeners]) listener();
|
|
4241
|
+
}
|
|
4242
|
+
function invalidate(entry, raw) {
|
|
4243
|
+
if (entry.raw === raw && entry.decoded) return;
|
|
4244
|
+
entry.raw = raw;
|
|
4245
|
+
entry.decoded = false;
|
|
4246
|
+
notify(entry);
|
|
4247
|
+
}
|
|
4248
|
+
function readPageStorage() {
|
|
4249
|
+
try {
|
|
4250
|
+
const storage = globalThis.localStorage;
|
|
4251
|
+
return storage && typeof storage.getItem === "function" ? storage : null;
|
|
4252
|
+
} catch {
|
|
4253
|
+
return null;
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
const memory = /* @__PURE__ */ new Map();
|
|
4257
|
+
const memoryStorage = {
|
|
4258
|
+
getItem: (key) => memory.get(key) ?? null,
|
|
4259
|
+
setItem: (key, value) => void memory.set(key, value),
|
|
4260
|
+
removeItem: (key) => void memory.delete(key)
|
|
4261
|
+
};
|
|
4262
|
+
const pageStorage = readPageStorage();
|
|
4263
|
+
const appStorage = pageStorage ?? memoryStorage;
|
|
4264
|
+
let watching = false;
|
|
4265
|
+
function watchOtherTabs() {
|
|
4266
|
+
if (watching || !pageStorage) return;
|
|
4267
|
+
watching = true;
|
|
4268
|
+
const target = globalThis;
|
|
4269
|
+
if (typeof target.addEventListener !== "function") return;
|
|
4270
|
+
target.addEventListener("storage", (event) => {
|
|
4271
|
+
if (event.storageArea !== pageStorage) return;
|
|
4272
|
+
const entries = stores.get(pageStorage);
|
|
4273
|
+
if (!entries) return;
|
|
4274
|
+
if (event.key === null) {
|
|
4275
|
+
for (const entry of entries.values()) invalidate(entry, null);
|
|
4276
|
+
} else {
|
|
4277
|
+
const entry = entries.get(event.key);
|
|
4278
|
+
if (entry) invalidate(entry, event.newValue);
|
|
4279
|
+
}
|
|
4280
|
+
});
|
|
4281
|
+
}
|
|
4282
|
+
function useAppStorage(key, defaultValue, options = {}) {
|
|
4283
|
+
const { store = appStorage, decode, onError } = options;
|
|
4284
|
+
const [fallback] = useState(defaultValue);
|
|
4285
|
+
const entry = entryFor(store, key);
|
|
4286
|
+
entry.decode = decode;
|
|
4287
|
+
const subscribe = useCallback(
|
|
4288
|
+
(listener) => {
|
|
4289
|
+
const subscribed = entryFor(store, key);
|
|
4290
|
+
subscribed.listeners.add(listener);
|
|
4291
|
+
return () => void subscribed.listeners.delete(listener);
|
|
4292
|
+
},
|
|
4293
|
+
[store, key]
|
|
4294
|
+
);
|
|
4295
|
+
const read = useCallback(() => valueOf(entryFor(store, key), fallback), [store, key, fallback]);
|
|
4296
|
+
const value = useSyncExternalStore(subscribe, read, read);
|
|
4297
|
+
const set = useCallback(
|
|
4298
|
+
(next) => {
|
|
4299
|
+
const target = entryFor(store, key);
|
|
4300
|
+
const current = valueOf(target, fallback);
|
|
4301
|
+
const value2 = typeof next === "function" ? next(current) : next;
|
|
4302
|
+
const raw = value2 === void 0 ? null : JSON.stringify(value2);
|
|
4303
|
+
try {
|
|
4304
|
+
if (raw === null) store.removeItem(key);
|
|
4305
|
+
else store.setItem(key, raw);
|
|
4306
|
+
} catch (error) {
|
|
4307
|
+
onError?.(error);
|
|
4308
|
+
}
|
|
4309
|
+
target.raw = raw;
|
|
4310
|
+
target.value = value2;
|
|
4311
|
+
target.decoded = raw !== null;
|
|
4312
|
+
notify(target);
|
|
4313
|
+
},
|
|
4314
|
+
[store, key, fallback, onError]
|
|
4315
|
+
);
|
|
4316
|
+
return [value, set];
|
|
4317
|
+
}
|
|
4318
|
+
const NONE = {
|
|
4319
|
+
documents: "file:///data/Documents",
|
|
4320
|
+
applicationSupport: "file:///data/Library/Application%20Support",
|
|
4321
|
+
caches: "file:///data/Library/Caches",
|
|
4322
|
+
temporary: "file:///tmp"
|
|
4323
|
+
};
|
|
4324
|
+
async function bytesOf(contents) {
|
|
4325
|
+
if (typeof contents === "string") return new TextEncoder().encode(contents);
|
|
4326
|
+
if (contents instanceof Uint8Array) return contents;
|
|
4327
|
+
if (contents instanceof ArrayBuffer) return new Uint8Array(contents);
|
|
4328
|
+
const blob = contents;
|
|
4329
|
+
if (typeof blob.bytes === "function") return await blob.bytes();
|
|
4330
|
+
return new Uint8Array(await blob.arrayBuffer());
|
|
4331
|
+
}
|
|
4332
|
+
function createFileManager(host) {
|
|
4333
|
+
const required = () => {
|
|
4334
|
+
const files = host();
|
|
4335
|
+
if (!files) throw new Error("unsupported: this page keeps no files");
|
|
4336
|
+
return files;
|
|
4337
|
+
};
|
|
4338
|
+
const directories = () => host()?.directories ?? NONE;
|
|
4339
|
+
return {
|
|
4340
|
+
get available() {
|
|
4341
|
+
return host() !== void 0;
|
|
4342
|
+
},
|
|
4343
|
+
get documentsDirectory() {
|
|
4344
|
+
return directories().documents;
|
|
4345
|
+
},
|
|
4346
|
+
get applicationSupportDirectory() {
|
|
4347
|
+
return directories().applicationSupport;
|
|
4348
|
+
},
|
|
4349
|
+
get cachesDirectory() {
|
|
4350
|
+
return directories().caches;
|
|
4351
|
+
},
|
|
4352
|
+
get temporaryDirectory() {
|
|
4353
|
+
return directories().temporary;
|
|
4354
|
+
},
|
|
4355
|
+
url: (directory, path) => fileURL(directory, path),
|
|
4356
|
+
contents: async (url) => required().read(url),
|
|
4357
|
+
text: async (url) => new TextDecoder().decode(await required().read(url)),
|
|
4358
|
+
write: async (url, contents) => required().write(url, await bytesOf(contents)),
|
|
4359
|
+
contentsOfDirectory: async (url) => required().list(url),
|
|
4360
|
+
createDirectory: async (url) => required().createDirectory(url),
|
|
4361
|
+
fileExists: async (url) => await required().attributes(url) !== null,
|
|
4362
|
+
attributesOfItem: async (url) => {
|
|
4363
|
+
const attributes = await required().attributes(url);
|
|
4364
|
+
if (!attributes) throw new Error(`notFound: nothing at ${url}`);
|
|
4365
|
+
return attributes;
|
|
4366
|
+
},
|
|
4367
|
+
moveItem: async (from, to) => required().move(from, to),
|
|
4368
|
+
copyItem: async (from, to) => required().copy(from, to),
|
|
4369
|
+
removeItem: async (url) => required().remove(url),
|
|
4370
|
+
loadURL: async (url) => required().loadURL(url),
|
|
4371
|
+
iCloudDirectory: async () => await host()?.iCloud?.() ?? null,
|
|
4372
|
+
watch: (listener) => host()?.watch?.(listener) ?? (() => {
|
|
4373
|
+
})
|
|
4374
|
+
};
|
|
4375
|
+
}
|
|
4376
|
+
const fileManager = createFileManager(() => browserEnvironment.files);
|
|
4377
|
+
function useFileStorage(url, defaultValue, options = {}) {
|
|
4378
|
+
const manager = options.manager ?? fileManager;
|
|
4379
|
+
const [value, setValue] = useState(defaultValue);
|
|
4380
|
+
const [status, setStatus] = useState(url === null ? "ready" : "loading");
|
|
4381
|
+
const latest = useRef({ value, options, url, defaultValue });
|
|
4382
|
+
latest.current = { value, options, url, defaultValue };
|
|
4383
|
+
const shown = useRef(url);
|
|
4384
|
+
const known = useRef(null);
|
|
4385
|
+
const writing = useRef(Promise.resolve());
|
|
4386
|
+
const load = useCallback(
|
|
4387
|
+
async (target) => {
|
|
4388
|
+
let text;
|
|
4389
|
+
try {
|
|
4390
|
+
text = await manager.text(target);
|
|
4391
|
+
} catch (error) {
|
|
4392
|
+
if (latest.current.url !== target) return;
|
|
4393
|
+
if (error instanceof Error && error.message.startsWith("notFound:")) {
|
|
4394
|
+
known.current = null;
|
|
4395
|
+
setStatus("ready");
|
|
4396
|
+
return;
|
|
4397
|
+
}
|
|
4398
|
+
latest.current.options.onError?.(error);
|
|
4399
|
+
setStatus("error");
|
|
4400
|
+
return;
|
|
4401
|
+
}
|
|
4402
|
+
if (latest.current.url !== target) return;
|
|
4403
|
+
if (text !== known.current) {
|
|
4404
|
+
known.current = text;
|
|
4405
|
+
try {
|
|
4406
|
+
const stored = JSON.parse(text);
|
|
4407
|
+
setValue(latest.current.options.decode ? latest.current.options.decode(stored) : stored);
|
|
4408
|
+
} catch (error) {
|
|
4409
|
+
latest.current.options.onError?.(error);
|
|
4410
|
+
}
|
|
4411
|
+
}
|
|
4412
|
+
setStatus("ready");
|
|
4413
|
+
},
|
|
4414
|
+
[manager]
|
|
4415
|
+
);
|
|
4416
|
+
useEffect(() => {
|
|
4417
|
+
known.current = null;
|
|
4418
|
+
if (shown.current !== url) {
|
|
4419
|
+
shown.current = url;
|
|
4420
|
+
const fresh = latest.current.defaultValue;
|
|
4421
|
+
const value2 = typeof fresh === "function" ? fresh() : fresh;
|
|
4422
|
+
latest.current.value = value2;
|
|
4423
|
+
setValue(value2);
|
|
4424
|
+
}
|
|
4425
|
+
if (url === null) {
|
|
4426
|
+
setStatus("ready");
|
|
4427
|
+
return;
|
|
4428
|
+
}
|
|
4429
|
+
setStatus("loading");
|
|
4430
|
+
void load(url);
|
|
4431
|
+
return manager.watch((urls) => {
|
|
4432
|
+
if (urls.includes(url)) void load(url);
|
|
4433
|
+
});
|
|
4434
|
+
}, [url, load, manager]);
|
|
4435
|
+
const set = useCallback(
|
|
4436
|
+
(next) => {
|
|
4437
|
+
const resolved = typeof next === "function" ? next(latest.current.value) : next;
|
|
4438
|
+
latest.current.value = resolved;
|
|
4439
|
+
setValue(resolved);
|
|
4440
|
+
const target = latest.current.url;
|
|
4441
|
+
if (target === null) return;
|
|
4442
|
+
const text = JSON.stringify(resolved);
|
|
4443
|
+
known.current = text;
|
|
4444
|
+
writing.current = writing.current.then(async () => {
|
|
4445
|
+
try {
|
|
4446
|
+
await manager.write(target, text);
|
|
4447
|
+
} catch (error) {
|
|
4448
|
+
latest.current.options.onError?.(error);
|
|
4449
|
+
}
|
|
4450
|
+
});
|
|
4451
|
+
},
|
|
4452
|
+
[manager]
|
|
4453
|
+
);
|
|
4454
|
+
return [value, set, status];
|
|
4455
|
+
}
|
|
4456
|
+
const NO_CLEAR = () => {
|
|
4457
|
+
};
|
|
4458
|
+
function List(props) {
|
|
4459
|
+
const { own, modifiers } = splitProps(props);
|
|
4460
|
+
const [editing] = own.editing !== void 0 ? readBinding(own.editing) : [false];
|
|
4461
|
+
const listProps = { style: own.listStyle ?? "insetGrouped" };
|
|
4462
|
+
if (editing) listProps["editing"] = true;
|
|
4463
|
+
let selection = null;
|
|
4464
|
+
const split = useContext(SplitSelectionContext);
|
|
4465
|
+
let selected = false;
|
|
4466
|
+
let clearSelection = NO_CLEAR;
|
|
4467
|
+
if (own.selection !== void 0) {
|
|
4468
|
+
const [value, setValue] = readBinding(own.selection, own.onSelectionChange);
|
|
4469
|
+
if (value instanceof Set) listProps["multiSelect"] = true;
|
|
4470
|
+
selected = value instanceof Set ? value.size > 0 : value !== null && value !== void 0;
|
|
4471
|
+
clearSelection = () => setValue(value instanceof Set ? /* @__PURE__ */ new Set() : null);
|
|
4472
|
+
selection = {
|
|
4473
|
+
editing,
|
|
4474
|
+
isSelected: (tag) => value instanceof Set ? value.has(tag) : value !== null && Object.is(value, tag),
|
|
4475
|
+
select: (tag) => {
|
|
4476
|
+
if (value instanceof Set) {
|
|
4477
|
+
const next = new Set(value);
|
|
4478
|
+
if (next.has(tag)) next.delete(tag);
|
|
4479
|
+
else next.add(tag);
|
|
4480
|
+
setValue(next);
|
|
4481
|
+
} else {
|
|
4482
|
+
setValue(editing && Object.is(value, tag) ? null : tag);
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
};
|
|
4486
|
+
}
|
|
4487
|
+
useReportSplitSelection(split, selected, clearSelection, own.selection !== void 0);
|
|
4488
|
+
const refresh = useRefreshable(takeModifier(modifiers, "refreshable"));
|
|
4489
|
+
Object.assign(listProps, refresh.props);
|
|
4490
|
+
const ownSettings = takeScrollSettings(modifiers);
|
|
4491
|
+
const edgeEffect = edgeEffectProp(useScrollSettings(ownSettings));
|
|
4492
|
+
if (edgeEffect) listProps["edgeEffect"] = edgeEffect;
|
|
4493
|
+
const element = /* @__PURE__ */ jsx(LazyContext.Provider, { value: "vertical", children: sb("list", listProps, refresh.handlers, providingScrollSettings(ownSettings, wrapRows(own.children))) });
|
|
4494
|
+
return applyModifiers(
|
|
4495
|
+
selection ? /* @__PURE__ */ jsx(ListSelectionContext.Provider, { value: selection, children: element }) : element,
|
|
4496
|
+
modifiers
|
|
4497
|
+
);
|
|
4498
|
+
}
|
|
4499
|
+
function Form(props) {
|
|
4500
|
+
return /* @__PURE__ */ jsx(List, { ...props });
|
|
4501
|
+
}
|
|
4502
|
+
function Section(props) {
|
|
4503
|
+
const { own, modifiers } = splitProps(props);
|
|
4504
|
+
const pinned = useContext(PinnedContext);
|
|
4505
|
+
let header = supplement(own.header);
|
|
4506
|
+
let footer = supplement(own.footer);
|
|
4507
|
+
if (pinned?.includes("sectionHeaders") && header.text !== null && !header.view) header = { text: null, view: /* @__PURE__ */ jsx(Text, { children: header.text }) };
|
|
4508
|
+
if (pinned?.includes("sectionFooters") && footer.text !== null && !footer.view) footer = { text: null, view: /* @__PURE__ */ jsx(Text, { children: footer.text }) };
|
|
4509
|
+
const children = [];
|
|
4510
|
+
if (header.view) children.push(sb("sectionheader", {}, void 0, header.view));
|
|
4511
|
+
if (own.children !== void 0) children.push(wrapRows(own.children));
|
|
4512
|
+
if (footer.view) children.push(sb("sectionfooter", {}, void 0, footer.view));
|
|
4513
|
+
return applyModifiers(sb("section", { header: header.text, footer: footer.text }, void 0, children), modifiers);
|
|
4514
|
+
}
|
|
4515
|
+
function wrapRows(children) {
|
|
4516
|
+
let offset = 0;
|
|
4517
|
+
return flattenChildren(children, { keepLazy: true }).map((element, index) => {
|
|
4518
|
+
const at = index + offset;
|
|
4519
|
+
if (element.type === LazyGroup) {
|
|
4520
|
+
const group = element.props;
|
|
4521
|
+
offset += group.rows.length - 1;
|
|
4522
|
+
return { ...withKey(element, index), props: { ...group, start: at, wrap: wrapRow } };
|
|
4523
|
+
}
|
|
4524
|
+
return wrapRow(withKey(element, index), at);
|
|
4525
|
+
});
|
|
4526
|
+
}
|
|
4527
|
+
function wrapRow(row, containerIndex) {
|
|
4528
|
+
const inner = row.type === Fragment ? flattenChildren(row) : null;
|
|
4529
|
+
const element = inner?.length === 1 ? { ...inner[0], key: row.key } : row;
|
|
4530
|
+
if (element.type === Section) return element;
|
|
4531
|
+
if (element.type === Row) return { ...element, props: { ...element.props, containerIndex } };
|
|
4532
|
+
const props = element.props;
|
|
4533
|
+
const tag = props.tag !== void 0 ? props.tag : element.type === NavigationLink ? props.value : void 0;
|
|
4534
|
+
if (tag === void 0) return element;
|
|
4535
|
+
return /* @__PURE__ */ jsx(Row, { tag, containerIndex, children: element }, element.key ?? containerIndex);
|
|
4536
|
+
}
|
|
4537
|
+
function withKey(element, index) {
|
|
4538
|
+
return element.key !== null ? element : { ...element, key: String(index) };
|
|
4539
|
+
}
|
|
4540
|
+
function supplement(node) {
|
|
4541
|
+
if (node === void 0 || node === null || node === false) return { text: null, view: null };
|
|
4542
|
+
if (typeof node === "string" || typeof node === "number") return { text: String(node), view: null };
|
|
4543
|
+
if (isValidElement(node) && node.type === Text) {
|
|
4544
|
+
const props = node.props;
|
|
4545
|
+
const only = Object.keys(props).every((key) => key === "children");
|
|
4546
|
+
if (only) return { text: plainText(node), view: null };
|
|
4547
|
+
}
|
|
4548
|
+
return { text: null, view: isValidElement(node) ? node : null };
|
|
4549
|
+
}
|
|
4550
|
+
function TabView(props) {
|
|
4551
|
+
const { own, modifiers } = splitProps(props);
|
|
4552
|
+
const tabs = flattenChildren(own.children);
|
|
4553
|
+
const tags = tabs.map((tab, index) => {
|
|
4554
|
+
const tag = tab.props.tag;
|
|
4555
|
+
return tag !== void 0 ? tag : index;
|
|
4556
|
+
});
|
|
4557
|
+
const [internal, setInternal] = useState(tags[0]);
|
|
4558
|
+
const [selection, setSelection] = own.selection !== void 0 ? readBinding(own.selection, own.onChange) : [internal, setInternal];
|
|
4559
|
+
const selected = Math.max(
|
|
4560
|
+
0,
|
|
4561
|
+
tags.findIndex((tag) => Object.is(tag, selection))
|
|
4562
|
+
);
|
|
4563
|
+
return applyModifiers(
|
|
4564
|
+
sb("tabview", { selected }, { select: (event) => tags[event.value] !== void 0 && setSelection(tags[event.value]) }, tabs),
|
|
4565
|
+
modifiers
|
|
4566
|
+
);
|
|
4567
|
+
}
|
|
4568
|
+
function Tab(props) {
|
|
4569
|
+
const { own, modifiers } = splitProps(props);
|
|
4570
|
+
const badge = takeModifier(modifiers, "badge");
|
|
4571
|
+
const tabProps = { title: own.title, systemImage: own.systemImage ?? null };
|
|
4572
|
+
if (badge !== void 0 && badge !== null) tabProps["badge"] = String(badge);
|
|
4573
|
+
if (own.role) tabProps["role"] = own.role;
|
|
4574
|
+
if (own.image && !own.systemImage) tabProps["image"] = own.image;
|
|
4575
|
+
return applyModifiers(sb("tab", tabProps, void 0, own.children), modifiers);
|
|
4576
|
+
}
|
|
4157
4577
|
function Host(props) {
|
|
4158
4578
|
const { own, modifiers } = splitProps(props);
|
|
4159
4579
|
const key = useId();
|
|
@@ -4201,10 +4621,11 @@ function Host(props) {
|
|
|
4201
4621
|
function Menu(props) {
|
|
4202
4622
|
const { own, modifiers } = splitProps(props);
|
|
4203
4623
|
const label = own.title !== void 0 ? /* @__PURE__ */ jsx(Text, { children: own.title }) : own.label;
|
|
4624
|
+
const items = withEnvironment({ labelStyle: "automatic" }, own.children);
|
|
4204
4625
|
return applyModifiers(
|
|
4205
4626
|
sb("menu", {}, void 0, [
|
|
4206
4627
|
/* @__PURE__ */ jsx(Fragment, { children: sb("zstack", { alignment: "center" }, void 0, label) }, "label"),
|
|
4207
|
-
/* @__PURE__ */ jsx(Fragment, { children:
|
|
4628
|
+
/* @__PURE__ */ jsx(Fragment, { children: items }, "items")
|
|
4208
4629
|
]),
|
|
4209
4630
|
modifiers
|
|
4210
4631
|
);
|
|
@@ -5579,6 +6000,7 @@ export {
|
|
|
5579
6000
|
SecureField,
|
|
5580
6001
|
Shape,
|
|
5581
6002
|
ShareLink,
|
|
6003
|
+
SignInWithAppleButton,
|
|
5582
6004
|
Slider,
|
|
5583
6005
|
Spacer,
|
|
5584
6006
|
SplitSelectionContext,
|
|
@@ -5605,10 +6027,14 @@ export {
|
|
|
5605
6027
|
ZStack,
|
|
5606
6028
|
answerLayout,
|
|
5607
6029
|
appStorage,
|
|
6030
|
+
appleCredentialState,
|
|
5608
6031
|
canMeasureText,
|
|
6032
|
+
canSignInWithApple,
|
|
5609
6033
|
color,
|
|
6034
|
+
configureSignInWithApple,
|
|
5610
6035
|
createFileManager,
|
|
5611
6036
|
createSwiftUIRoot,
|
|
6037
|
+
exportFile,
|
|
5612
6038
|
fileManager,
|
|
5613
6039
|
flattenChildren,
|
|
5614
6040
|
focusBinding,
|
|
@@ -5636,6 +6062,7 @@ export {
|
|
|
5636
6062
|
rgb,
|
|
5637
6063
|
scrollGeometryOf,
|
|
5638
6064
|
shapeStyle,
|
|
6065
|
+
signInWithApple,
|
|
5639
6066
|
system,
|
|
5640
6067
|
takeScrollSettings,
|
|
5641
6068
|
timeTicks,
|
|
@@ -5648,14 +6075,20 @@ export {
|
|
|
5648
6075
|
useCoordinateSpaces,
|
|
5649
6076
|
useDismiss,
|
|
5650
6077
|
useDynamicTypeSize,
|
|
6078
|
+
useFileStorage,
|
|
6079
|
+
useGeolocation,
|
|
5651
6080
|
useHorizontalSizeClass,
|
|
5652
6081
|
useNamespace,
|
|
5653
6082
|
useNavigation,
|
|
5654
6083
|
useRedacted,
|
|
5655
6084
|
useRefreshable,
|
|
5656
6085
|
useReportSplitSelection,
|
|
6086
|
+
useScenePhase,
|
|
6087
|
+
useSpeechRecognition,
|
|
6088
|
+
useSpeechSynthesis,
|
|
5657
6089
|
useUndoManager,
|
|
5658
6090
|
useViewEnvironment,
|
|
6091
|
+
useWakeLock,
|
|
5659
6092
|
weighted,
|
|
5660
6093
|
withAnimation
|
|
5661
6094
|
};
|