@swiftbrowser/react 0.4.0 → 0.5.0
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 +64 -9
- package/dist/components/geometry.d.ts +32 -2
- package/dist/components/geometry.d.ts.map +1 -1
- package/dist/components/host.d.ts.map +1 -1
- package/dist/components/lists.d.ts.map +1 -1
- package/dist/components/stacks.d.ts +22 -1
- package/dist/components/stacks.d.ts.map +1 -1
- package/dist/host/root.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1113 -772
- package/dist/index.js.map +1 -1
- package/dist/modifiers.d.ts +49 -0
- package/dist/modifiers.d.ts.map +1 -1
- package/dist/scrollEnvironment.d.ts +50 -0
- package/dist/scrollEnvironment.d.ts.map +1 -0
- package/dist/visualEffect.d.ts +120 -0
- package/dist/visualEffect.d.ts.map +1 -0
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useContext, createElement, useRef, useLayoutEffect, useEffect,
|
|
1
|
+
import { createContext, useContext, createElement, useRef, useLayoutEffect, useState, useEffect, Children, useId, Fragment as Fragment$1, isValidElement, cloneElement, useSyncExternalStore } from "react";
|
|
2
2
|
import { DefaultEventPriority, ConcurrentRoot } from "react-reconciler/constants";
|
|
3
3
|
import Reconciler from "react-reconciler";
|
|
4
4
|
import { horizontalSizeClassFor } from "@swiftbrowser/web/src/protocol";
|
|
@@ -534,6 +534,185 @@ function readBinding(value, onChange) {
|
|
|
534
534
|
return [value, onChange ?? (() => {
|
|
535
535
|
})];
|
|
536
536
|
}
|
|
537
|
+
function sb(kind, props, on, children, target) {
|
|
538
|
+
const hostProps = { kind };
|
|
539
|
+
if (props) hostProps.props = props;
|
|
540
|
+
if (on) hostProps.on = on;
|
|
541
|
+
if (target) hostProps.target = target;
|
|
542
|
+
return children === void 0 ? createElement("sb", hostProps) : createElement("sb", hostProps, children);
|
|
543
|
+
}
|
|
544
|
+
const CoordinateSpacesContext = createContext({});
|
|
545
|
+
function useCoordinateSpaces() {
|
|
546
|
+
return useContext(CoordinateSpacesContext);
|
|
547
|
+
}
|
|
548
|
+
function CoordinateSpace({ name, children }) {
|
|
549
|
+
const spaces = useContext(CoordinateSpacesContext);
|
|
550
|
+
const [frame2, setFrame] = useState(null);
|
|
551
|
+
return /* @__PURE__ */ jsx(CoordinateSpacesContext.Provider, { value: { ...spaces, [name]: frame2 }, children: sb(
|
|
552
|
+
"zstack",
|
|
553
|
+
{ alignment: "center", reportsSize: true, reportsFrame: true },
|
|
554
|
+
{
|
|
555
|
+
geometry: (event) => {
|
|
556
|
+
const next = { x: event.x ?? 0, y: event.y ?? 0, width: event.width, height: event.height };
|
|
557
|
+
if (!frame2 || frame2.x !== next.x || frame2.y !== next.y || frame2.width !== next.width || frame2.height !== next.height) setFrame(next);
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
children
|
|
561
|
+
) });
|
|
562
|
+
}
|
|
563
|
+
let active = null;
|
|
564
|
+
function Draggable({ payload, children }) {
|
|
565
|
+
return sb(
|
|
566
|
+
"draggable",
|
|
567
|
+
{},
|
|
568
|
+
{
|
|
569
|
+
dragstart: (event) => {
|
|
570
|
+
active = { id: event.id, payload };
|
|
571
|
+
},
|
|
572
|
+
dragend: (event) => {
|
|
573
|
+
if (active?.id === event.id) active = null;
|
|
574
|
+
}
|
|
575
|
+
},
|
|
576
|
+
children
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
function itemValue(item) {
|
|
580
|
+
if (item.text !== void 0) {
|
|
581
|
+
if (item.type === "text/uri-list") {
|
|
582
|
+
try {
|
|
583
|
+
return new URL(item.text.split(/\r?\n/)[0].trim());
|
|
584
|
+
} catch {
|
|
585
|
+
return item.text;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return item.text;
|
|
589
|
+
}
|
|
590
|
+
const binary = atob(item.data ?? "");
|
|
591
|
+
const bytes = new Uint8Array(binary.length);
|
|
592
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
593
|
+
return typeof File !== "undefined" ? new File([bytes], item.name ?? "file", { type: item.type }) : bytes;
|
|
594
|
+
}
|
|
595
|
+
function DropDestination({ action, isTargeted, accepts, children }) {
|
|
596
|
+
return sb(
|
|
597
|
+
"dropdestination",
|
|
598
|
+
{ accepts: accepts ?? [] },
|
|
599
|
+
{
|
|
600
|
+
drop: (event) => {
|
|
601
|
+
if (event.phase === "entered") {
|
|
602
|
+
isTargeted?.(true);
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
isTargeted?.(false);
|
|
606
|
+
if (event.phase !== "performed") return;
|
|
607
|
+
let items;
|
|
608
|
+
if (event.source !== void 0) items = active && active.id === event.source ? [active.payload] : [];
|
|
609
|
+
else items = (event.items ?? []).map(itemValue);
|
|
610
|
+
if (items.length > 0) action(items, { x: event.x, y: event.y });
|
|
611
|
+
}
|
|
612
|
+
},
|
|
613
|
+
children
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
function SheetPresenter({ isPresented, onDismiss, content, fullScreen }) {
|
|
617
|
+
const [presented, setPresented] = readBinding(isPresented);
|
|
618
|
+
if (!presented) return null;
|
|
619
|
+
const dismiss = () => {
|
|
620
|
+
setPresented(false);
|
|
621
|
+
onDismiss?.();
|
|
622
|
+
};
|
|
623
|
+
const detents = fullScreen ? ["full"] : ["large"];
|
|
624
|
+
return sb(
|
|
625
|
+
HOIST_KIND,
|
|
626
|
+
void 0,
|
|
627
|
+
void 0,
|
|
628
|
+
sb(
|
|
629
|
+
"sheet",
|
|
630
|
+
{ detents },
|
|
631
|
+
{ tap: dismiss },
|
|
632
|
+
/* @__PURE__ */ jsx(NavigationContext.Provider, { value: null, children: /* @__PURE__ */ jsx(DismissContext.Provider, { value: dismiss, children: content }) })
|
|
633
|
+
),
|
|
634
|
+
"root"
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
function presentationDetents(detents) {
|
|
638
|
+
const encoded = detents.map(
|
|
639
|
+
(detent) => typeof detent === "string" ? detent : "height" in detent ? `height:${detent.height}` : `fraction:${detent.fraction}`
|
|
640
|
+
);
|
|
641
|
+
return sb(PREF_KIND, { detents: encoded }, void 0, void 0, "sheet");
|
|
642
|
+
}
|
|
643
|
+
function AlertPresenter({ title, isPresented, message, actions, style }) {
|
|
644
|
+
const [presented, setPresented] = readBinding(isPresented);
|
|
645
|
+
if (!presented) return null;
|
|
646
|
+
const dismiss = () => setPresented(false);
|
|
647
|
+
return sb(
|
|
648
|
+
HOIST_KIND,
|
|
649
|
+
void 0,
|
|
650
|
+
void 0,
|
|
651
|
+
sb(
|
|
652
|
+
"alert",
|
|
653
|
+
{ title, message: message ?? null, style: style ?? "alert" },
|
|
654
|
+
{ tap: dismiss },
|
|
655
|
+
withEnvironment({ dismissAlert: dismiss }, actions)
|
|
656
|
+
),
|
|
657
|
+
"root"
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
function Lifecycle({ onAppear, onDisappear }) {
|
|
661
|
+
useEffect(() => {
|
|
662
|
+
onAppear?.();
|
|
663
|
+
return () => onDisappear?.();
|
|
664
|
+
}, []);
|
|
665
|
+
return null;
|
|
666
|
+
}
|
|
667
|
+
function Inspector({ isPresented, content, columnWidth, children }) {
|
|
668
|
+
const sizeClass = useHorizontalSizeClass();
|
|
669
|
+
const [presented, setPresented] = readBinding(isPresented);
|
|
670
|
+
if (sizeClass === "compact") {
|
|
671
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
672
|
+
children,
|
|
673
|
+
/* @__PURE__ */ jsx(SheetPresenter, { isPresented: [presented, setPresented], content })
|
|
674
|
+
] });
|
|
675
|
+
}
|
|
676
|
+
const panelContent = columnWidth !== void 0 ? sb("styled", { style: { inspectorColumnWidth: columnWidth } }, void 0, content) : content;
|
|
677
|
+
return sb("inspector", { presented }, void 0, [
|
|
678
|
+
/* @__PURE__ */ jsx(InspectorPart, { children }, "content"),
|
|
679
|
+
/* @__PURE__ */ jsx(InspectorPart, { children: sb("inspectorpanel", {}, void 0, panelContent) }, "panel")
|
|
680
|
+
]);
|
|
681
|
+
}
|
|
682
|
+
function InspectorPart({ children }) {
|
|
683
|
+
return children;
|
|
684
|
+
}
|
|
685
|
+
function Task({ id, action }) {
|
|
686
|
+
const latest = useRef(action);
|
|
687
|
+
latest.current = action;
|
|
688
|
+
useEffect(() => {
|
|
689
|
+
const controller = new AbortController();
|
|
690
|
+
Promise.resolve().then(() => latest.current(controller.signal)).catch((error) => {
|
|
691
|
+
if (!controller.signal.aborted) console.error(error);
|
|
692
|
+
});
|
|
693
|
+
return () => controller.abort();
|
|
694
|
+
}, [id]);
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
function OnChange({
|
|
698
|
+
value,
|
|
699
|
+
action,
|
|
700
|
+
initial
|
|
701
|
+
}) {
|
|
702
|
+
const previous = useRef(null);
|
|
703
|
+
const latest = useRef(action);
|
|
704
|
+
latest.current = action;
|
|
705
|
+
useEffect(() => {
|
|
706
|
+
const last = previous.current;
|
|
707
|
+
previous.current = { value };
|
|
708
|
+
if (last === null) {
|
|
709
|
+
if (initial) latest.current(value, value);
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
if (!Object.is(last.value, value)) latest.current(last.value, value);
|
|
713
|
+
}, [value, initial]);
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
537
716
|
const HIERARCHY = { primary: 1, secondary: 2, tertiary: 3, quaternary: 4 };
|
|
538
717
|
function rgb(r2, g, b, a = 1) {
|
|
539
718
|
return { r: r2, g, b, a };
|
|
@@ -680,346 +859,102 @@ function insets(edges, amount) {
|
|
|
680
859
|
}
|
|
681
860
|
return result;
|
|
682
861
|
}
|
|
683
|
-
const
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
862
|
+
const ScrollRequestContext = createContext(null);
|
|
863
|
+
let nextSerial = 1;
|
|
864
|
+
function ScrollViewReader({ children }) {
|
|
865
|
+
const [request, setRequest] = useState(null);
|
|
866
|
+
const proxy = {
|
|
867
|
+
scrollTo: (id, anchor) => setRequest({ id, anchor: anchor === void 0 ? null : unitPoint(anchor), serial: nextSerial++ })
|
|
868
|
+
};
|
|
869
|
+
return /* @__PURE__ */ jsx(ScrollRequestContext.Provider, { value: request, children: children(proxy) });
|
|
870
|
+
}
|
|
871
|
+
function ScrollTarget({ id, children }) {
|
|
872
|
+
const request = useContext(ScrollRequestContext);
|
|
873
|
+
if (request && request.id === id) return styled({ scrollID: true, scrollTo: { anchor: request.anchor, serial: request.serial } }, children);
|
|
874
|
+
return styled({ scrollID: true }, children);
|
|
875
|
+
}
|
|
876
|
+
const ScrollSettingsContext = createContext({});
|
|
877
|
+
function edgesOf(edges) {
|
|
878
|
+
const list = Array.isArray(edges) ? edges : [edges];
|
|
879
|
+
const all = list.some((edge) => edge === "all" || edge === "vertical");
|
|
880
|
+
return { top: all || list.includes("top"), bottom: all || list.includes("bottom") };
|
|
881
|
+
}
|
|
882
|
+
function edgeStyleSettings(value) {
|
|
883
|
+
const [style, edges] = Array.isArray(value) ? value : [value, "all"];
|
|
884
|
+
const on = edgesOf(edges);
|
|
885
|
+
const name = style === "automatic" ? void 0 : style;
|
|
886
|
+
const result = {};
|
|
887
|
+
if (on.top) result.topStyle = name;
|
|
888
|
+
if (on.bottom) result.bottomStyle = name;
|
|
889
|
+
return result;
|
|
890
|
+
}
|
|
891
|
+
function edgeHiddenSettings(value) {
|
|
892
|
+
const [hidden, edges] = Array.isArray(value) ? value : [value, "all"];
|
|
893
|
+
const on = edgesOf(edges);
|
|
894
|
+
const result = {};
|
|
895
|
+
if (on.top) result.topHidden = hidden;
|
|
896
|
+
if (on.bottom) result.bottomHidden = hidden;
|
|
897
|
+
return result;
|
|
898
|
+
}
|
|
899
|
+
function marginSettings(value) {
|
|
900
|
+
return { margins: padding(value) };
|
|
901
|
+
}
|
|
902
|
+
function mergeScrollSettings(outer, inner) {
|
|
903
|
+
const result = { ...outer };
|
|
904
|
+
for (const key of ["topStyle", "bottomStyle", "topHidden", "bottomHidden"]) {
|
|
905
|
+
if (key in inner) result[key] = inner[key];
|
|
701
906
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
this.parts.push(`A${r(radius)} ${r(radius)} 0 0 ${flag} ${r(from.x)} ${r(from.y)}`);
|
|
754
|
-
this.current = from;
|
|
755
|
-
return this;
|
|
756
|
-
}
|
|
757
|
-
const to = point(startAngle + delta);
|
|
758
|
-
const large = Math.abs(delta) > 180 ? 1 : 0;
|
|
759
|
-
this.parts.push(`A${r(radius)} ${r(radius)} 0 ${large} ${sweepPositive ? 1 : 0} ${r(to.x)} ${r(to.y)}`);
|
|
760
|
-
this.current = to;
|
|
761
|
-
return this;
|
|
762
|
-
}
|
|
763
|
-
addRect(rect) {
|
|
764
|
-
this.move({ x: rect.x, y: rect.y });
|
|
765
|
-
this.addLine({ x: rect.x + rect.width, y: rect.y });
|
|
766
|
-
this.addLine({ x: rect.x + rect.width, y: rect.y + rect.height });
|
|
767
|
-
this.addLine({ x: rect.x, y: rect.y + rect.height });
|
|
768
|
-
return this.closeSubpath();
|
|
769
|
-
}
|
|
770
|
-
addRoundedRect(rect, cornerRadius) {
|
|
771
|
-
const c = Math.max(0, Math.min(cornerRadius, rect.width / 2, rect.height / 2));
|
|
772
|
-
if (c === 0) return this.addRect(rect);
|
|
773
|
-
const { x, y, width: w, height: h } = rect;
|
|
774
|
-
this.move({ x: x + c, y });
|
|
775
|
-
this.addLine({ x: x + w - c, y });
|
|
776
|
-
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x + w)} ${r(y + c)}`);
|
|
777
|
-
this.current = { x: x + w, y: y + c };
|
|
778
|
-
this.addLine({ x: x + w, y: y + h - c });
|
|
779
|
-
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x + w - c)} ${r(y + h)}`);
|
|
780
|
-
this.current = { x: x + w - c, y: y + h };
|
|
781
|
-
this.addLine({ x: x + c, y: y + h });
|
|
782
|
-
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x)} ${r(y + h - c)}`);
|
|
783
|
-
this.current = { x, y: y + h - c };
|
|
784
|
-
this.addLine({ x, y: y + c });
|
|
785
|
-
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x + c)} ${r(y)}`);
|
|
786
|
-
this.current = { x: x + c, y };
|
|
787
|
-
return this.closeSubpath();
|
|
788
|
-
}
|
|
789
|
-
addEllipse(rect) {
|
|
790
|
-
const rx = rect.width / 2;
|
|
791
|
-
const ry = rect.height / 2;
|
|
792
|
-
const cx = rect.x + rx;
|
|
793
|
-
const cy = rect.y + ry;
|
|
794
|
-
this.move({ x: cx + rx, y: cy });
|
|
795
|
-
this.parts.push(`A${r(rx)} ${r(ry)} 0 0 1 ${r(cx - rx)} ${r(cy)}`);
|
|
796
|
-
this.parts.push(`A${r(rx)} ${r(ry)} 0 0 1 ${r(cx + rx)} ${r(cy)}`);
|
|
797
|
-
this.current = { x: cx + rx, y: cy };
|
|
798
|
-
return this.closeSubpath();
|
|
799
|
-
}
|
|
800
|
-
addPath(path) {
|
|
801
|
-
this.parts.push(path.svg());
|
|
802
|
-
return this;
|
|
803
|
-
}
|
|
804
|
-
closeSubpath() {
|
|
805
|
-
this.parts.push("Z");
|
|
806
|
-
this.current = this.start;
|
|
807
|
-
return this;
|
|
808
|
-
}
|
|
809
|
-
get isEmpty() {
|
|
810
|
-
return this.parts.length === 0;
|
|
811
|
-
}
|
|
812
|
-
/** The SVG path data. */
|
|
813
|
-
svg() {
|
|
814
|
-
return this.parts.join("");
|
|
815
|
-
}
|
|
816
|
-
toString() {
|
|
817
|
-
return this.svg();
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
function sb(kind, props, on, children, target) {
|
|
821
|
-
const hostProps = { kind };
|
|
822
|
-
if (props) hostProps.props = props;
|
|
823
|
-
if (on) hostProps.on = on;
|
|
824
|
-
if (target) hostProps.target = target;
|
|
825
|
-
return children === void 0 ? createElement("sb", hostProps) : createElement("sb", hostProps, children);
|
|
826
|
-
}
|
|
827
|
-
let active = null;
|
|
828
|
-
function Draggable({ payload, children }) {
|
|
829
|
-
return sb(
|
|
830
|
-
"draggable",
|
|
831
|
-
{},
|
|
832
|
-
{
|
|
833
|
-
dragstart: (event) => {
|
|
834
|
-
active = { id: event.id, payload };
|
|
835
|
-
},
|
|
836
|
-
dragend: (event) => {
|
|
837
|
-
if (active?.id === event.id) active = null;
|
|
838
|
-
}
|
|
839
|
-
},
|
|
840
|
-
children
|
|
841
|
-
);
|
|
842
|
-
}
|
|
843
|
-
function itemValue(item) {
|
|
844
|
-
if (item.text !== void 0) {
|
|
845
|
-
if (item.type === "text/uri-list") {
|
|
846
|
-
try {
|
|
847
|
-
return new URL(item.text.split(/\r?\n/)[0].trim());
|
|
848
|
-
} catch {
|
|
849
|
-
return item.text;
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
return item.text;
|
|
853
|
-
}
|
|
854
|
-
const binary = atob(item.data ?? "");
|
|
855
|
-
const bytes = new Uint8Array(binary.length);
|
|
856
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
857
|
-
return typeof File !== "undefined" ? new File([bytes], item.name ?? "file", { type: item.type }) : bytes;
|
|
858
|
-
}
|
|
859
|
-
function DropDestination({ action, isTargeted, accepts, children }) {
|
|
860
|
-
return sb(
|
|
861
|
-
"dropdestination",
|
|
862
|
-
{ accepts: accepts ?? [] },
|
|
863
|
-
{
|
|
864
|
-
drop: (event) => {
|
|
865
|
-
if (event.phase === "entered") {
|
|
866
|
-
isTargeted?.(true);
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
isTargeted?.(false);
|
|
870
|
-
if (event.phase !== "performed") return;
|
|
871
|
-
let items;
|
|
872
|
-
if (event.source !== void 0) items = active && active.id === event.source ? [active.payload] : [];
|
|
873
|
-
else items = (event.items ?? []).map(itemValue);
|
|
874
|
-
if (items.length > 0) action(items, { x: event.x, y: event.y });
|
|
875
|
-
}
|
|
876
|
-
},
|
|
877
|
-
children
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
function SheetPresenter({ isPresented, onDismiss, content, fullScreen }) {
|
|
881
|
-
const [presented, setPresented] = readBinding(isPresented);
|
|
882
|
-
if (!presented) return null;
|
|
883
|
-
const dismiss = () => {
|
|
884
|
-
setPresented(false);
|
|
885
|
-
onDismiss?.();
|
|
886
|
-
};
|
|
887
|
-
const detents = fullScreen ? ["full"] : ["large"];
|
|
888
|
-
return sb(
|
|
889
|
-
HOIST_KIND,
|
|
890
|
-
void 0,
|
|
891
|
-
void 0,
|
|
892
|
-
sb(
|
|
893
|
-
"sheet",
|
|
894
|
-
{ detents },
|
|
895
|
-
{ tap: dismiss },
|
|
896
|
-
/* @__PURE__ */ jsx(NavigationContext.Provider, { value: null, children: /* @__PURE__ */ jsx(DismissContext.Provider, { value: dismiss, children: content }) })
|
|
897
|
-
),
|
|
898
|
-
"root"
|
|
899
|
-
);
|
|
900
|
-
}
|
|
901
|
-
function presentationDetents(detents) {
|
|
902
|
-
const encoded = detents.map(
|
|
903
|
-
(detent) => typeof detent === "string" ? detent : "height" in detent ? `height:${detent.height}` : `fraction:${detent.fraction}`
|
|
904
|
-
);
|
|
905
|
-
return sb(PREF_KIND, { detents: encoded }, void 0, void 0, "sheet");
|
|
906
|
-
}
|
|
907
|
-
function AlertPresenter({ title, isPresented, message, actions, style }) {
|
|
908
|
-
const [presented, setPresented] = readBinding(isPresented);
|
|
909
|
-
if (!presented) return null;
|
|
910
|
-
const dismiss = () => setPresented(false);
|
|
911
|
-
return sb(
|
|
912
|
-
HOIST_KIND,
|
|
913
|
-
void 0,
|
|
914
|
-
void 0,
|
|
915
|
-
sb(
|
|
916
|
-
"alert",
|
|
917
|
-
{ title, message: message ?? null, style: style ?? "alert" },
|
|
918
|
-
{ tap: dismiss },
|
|
919
|
-
withEnvironment({ dismissAlert: dismiss }, actions)
|
|
920
|
-
),
|
|
921
|
-
"root"
|
|
922
|
-
);
|
|
923
|
-
}
|
|
924
|
-
function Lifecycle({ onAppear, onDisappear }) {
|
|
925
|
-
useEffect(() => {
|
|
926
|
-
onAppear?.();
|
|
927
|
-
return () => onDisappear?.();
|
|
928
|
-
}, []);
|
|
929
|
-
return null;
|
|
930
|
-
}
|
|
931
|
-
function Inspector({ isPresented, content, columnWidth, children }) {
|
|
932
|
-
const sizeClass = useHorizontalSizeClass();
|
|
933
|
-
const [presented, setPresented] = readBinding(isPresented);
|
|
934
|
-
if (sizeClass === "compact") {
|
|
935
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
936
|
-
children,
|
|
937
|
-
/* @__PURE__ */ jsx(SheetPresenter, { isPresented: [presented, setPresented], content })
|
|
938
|
-
] });
|
|
939
|
-
}
|
|
940
|
-
const panelContent = columnWidth !== void 0 ? sb("styled", { style: { inspectorColumnWidth: columnWidth } }, void 0, content) : content;
|
|
941
|
-
return sb("inspector", { presented }, void 0, [
|
|
942
|
-
/* @__PURE__ */ jsx(InspectorPart, { children }, "content"),
|
|
943
|
-
/* @__PURE__ */ jsx(InspectorPart, { children: sb("inspectorpanel", {}, void 0, panelContent) }, "panel")
|
|
944
|
-
]);
|
|
945
|
-
}
|
|
946
|
-
function InspectorPart({ children }) {
|
|
947
|
-
return children;
|
|
948
|
-
}
|
|
949
|
-
function Task({ id, action }) {
|
|
950
|
-
const latest = useRef(action);
|
|
951
|
-
latest.current = action;
|
|
952
|
-
useEffect(() => {
|
|
953
|
-
const controller = new AbortController();
|
|
954
|
-
Promise.resolve().then(() => latest.current(controller.signal)).catch((error) => {
|
|
955
|
-
if (!controller.signal.aborted) console.error(error);
|
|
956
|
-
});
|
|
957
|
-
return () => controller.abort();
|
|
958
|
-
}, [id]);
|
|
959
|
-
return null;
|
|
960
|
-
}
|
|
961
|
-
function OnChange({
|
|
962
|
-
value,
|
|
963
|
-
action,
|
|
964
|
-
initial
|
|
965
|
-
}) {
|
|
966
|
-
const previous = useRef(null);
|
|
967
|
-
const latest = useRef(action);
|
|
968
|
-
latest.current = action;
|
|
969
|
-
useEffect(() => {
|
|
970
|
-
const last = previous.current;
|
|
971
|
-
previous.current = { value };
|
|
972
|
-
if (last === null) {
|
|
973
|
-
if (initial) latest.current(value, value);
|
|
974
|
-
return;
|
|
975
|
-
}
|
|
976
|
-
if (!Object.is(last.value, value)) latest.current(last.value, value);
|
|
977
|
-
}, [value, initial]);
|
|
978
|
-
return null;
|
|
979
|
-
}
|
|
980
|
-
const CoordinateSpacesContext = createContext({});
|
|
981
|
-
function useCoordinateSpaces() {
|
|
982
|
-
return useContext(CoordinateSpacesContext);
|
|
983
|
-
}
|
|
984
|
-
function CoordinateSpace({ name, children }) {
|
|
985
|
-
const spaces = useContext(CoordinateSpacesContext);
|
|
986
|
-
const [frame2, setFrame] = useState(null);
|
|
987
|
-
return /* @__PURE__ */ jsx(CoordinateSpacesContext.Provider, { value: { ...spaces, [name]: frame2 }, children: sb(
|
|
988
|
-
"zstack",
|
|
989
|
-
{ alignment: "center", reportsSize: true, reportsFrame: true },
|
|
990
|
-
{
|
|
991
|
-
geometry: (event) => {
|
|
992
|
-
const next = { x: event.x ?? 0, y: event.y ?? 0, width: event.width, height: event.height };
|
|
993
|
-
if (!frame2 || frame2.x !== next.x || frame2.y !== next.y || frame2.width !== next.width || frame2.height !== next.height) setFrame(next);
|
|
994
|
-
}
|
|
995
|
-
},
|
|
996
|
-
children
|
|
997
|
-
) });
|
|
998
|
-
}
|
|
999
|
-
function Hover({ action, children }) {
|
|
1000
|
-
return sb("styled", { style: { hover: true } }, { hover: (event) => action(event.value) }, children);
|
|
1001
|
-
}
|
|
1002
|
-
const CURSORS = {
|
|
1003
|
-
link: "pointer",
|
|
1004
|
-
automatic: "auto",
|
|
1005
|
-
default: "default",
|
|
1006
|
-
text: "text",
|
|
1007
|
-
verticalText: "vertical-text",
|
|
1008
|
-
grabIdle: "grab",
|
|
1009
|
-
grabActive: "grabbing",
|
|
1010
|
-
rectSelection: "crosshair",
|
|
1011
|
-
columnResize: "col-resize",
|
|
1012
|
-
rowResize: "row-resize"
|
|
1013
|
-
};
|
|
1014
|
-
function cursorFor(style) {
|
|
1015
|
-
return CURSORS[style] ?? style;
|
|
1016
|
-
}
|
|
1017
|
-
function SymbolEffect({ spec, children }) {
|
|
1018
|
-
const serial = useRef(null);
|
|
1019
|
-
const discrete = "value" in spec;
|
|
1020
|
-
if (discrete) {
|
|
1021
|
-
if (!serial.current) serial.current = { value: spec.value, count: 0 };
|
|
1022
|
-
else if (!Object.is(serial.current.value, spec.value)) serial.current = { value: spec.value, count: serial.current.count + 1 };
|
|
907
|
+
if (inner.margins) result.margins = { ...outer.margins, ...inner.margins };
|
|
908
|
+
return result;
|
|
909
|
+
}
|
|
910
|
+
function withScrollSettings(settings, children) {
|
|
911
|
+
return createElement(ScrollSettingsExtender, { settings }, children);
|
|
912
|
+
}
|
|
913
|
+
function ScrollSettingsExtender({ settings, children }) {
|
|
914
|
+
const outer = useContext(ScrollSettingsContext);
|
|
915
|
+
return createElement(ScrollSettingsContext.Provider, { value: mergeScrollSettings(outer, settings) }, children);
|
|
916
|
+
}
|
|
917
|
+
function useScrollSettings(own) {
|
|
918
|
+
return mergeScrollSettings(useContext(ScrollSettingsContext), own);
|
|
919
|
+
}
|
|
920
|
+
function edgeEffectProp(settings) {
|
|
921
|
+
const edges = {};
|
|
922
|
+
const top = settings.topHidden ? "hidden" : settings.topStyle;
|
|
923
|
+
const bottom = settings.bottomHidden ? "hidden" : settings.bottomStyle;
|
|
924
|
+
if (top) edges.top = top;
|
|
925
|
+
if (bottom) edges.bottom = bottom;
|
|
926
|
+
return top || bottom ? edges : void 0;
|
|
927
|
+
}
|
|
928
|
+
function marginedContent(children, margins, axis) {
|
|
929
|
+
if (!margins || Object.values(margins).every((value) => !value)) return children;
|
|
930
|
+
const list = Children.toArray(children);
|
|
931
|
+
const content = list.length === 1 ? list[0] : sb(axis === "horizontal" ? "hstack" : "vstack", { spacing: null, alignment: "center" }, void 0, children);
|
|
932
|
+
return sb("styled", { style: { padding: margins } }, void 0, content);
|
|
933
|
+
}
|
|
934
|
+
function Hover({ action, children }) {
|
|
935
|
+
return sb("styled", { style: { hover: true } }, { hover: (event) => action(event.value) }, children);
|
|
936
|
+
}
|
|
937
|
+
const CURSORS = {
|
|
938
|
+
link: "pointer",
|
|
939
|
+
automatic: "auto",
|
|
940
|
+
default: "default",
|
|
941
|
+
text: "text",
|
|
942
|
+
verticalText: "vertical-text",
|
|
943
|
+
grabIdle: "grab",
|
|
944
|
+
grabActive: "grabbing",
|
|
945
|
+
rectSelection: "crosshair",
|
|
946
|
+
columnResize: "col-resize",
|
|
947
|
+
rowResize: "row-resize"
|
|
948
|
+
};
|
|
949
|
+
function cursorFor(style) {
|
|
950
|
+
return CURSORS[style] ?? style;
|
|
951
|
+
}
|
|
952
|
+
function SymbolEffect({ spec, children }) {
|
|
953
|
+
const serial = useRef(null);
|
|
954
|
+
const discrete = "value" in spec;
|
|
955
|
+
if (discrete) {
|
|
956
|
+
if (!serial.current) serial.current = { value: spec.value, count: 0 };
|
|
957
|
+
else if (!Object.is(serial.current.value, spec.value)) serial.current = { value: spec.value, count: serial.current.count + 1 };
|
|
1023
958
|
}
|
|
1024
959
|
if (!discrete && spec.isActive === false) return children;
|
|
1025
960
|
const effect = { effect: spec.effect };
|
|
@@ -1132,6 +1067,25 @@ function toolbarPlacement(name) {
|
|
|
1132
1067
|
return "trailing";
|
|
1133
1068
|
}
|
|
1134
1069
|
}
|
|
1070
|
+
function containerRelativeFrame(value) {
|
|
1071
|
+
const spec = typeof value === "string" ? { axes: value } : value;
|
|
1072
|
+
const horizontal = spec.axes !== "vertical";
|
|
1073
|
+
const vertical = spec.axes !== "horizontal";
|
|
1074
|
+
let a = 1;
|
|
1075
|
+
let b = 0;
|
|
1076
|
+
if (spec.length) {
|
|
1077
|
+
const axis = horizontal ? "horizontal" : "vertical";
|
|
1078
|
+
b = spec.length(0, axis);
|
|
1079
|
+
a = (spec.length(1e3, axis) - b) / 1e3;
|
|
1080
|
+
} else if (spec.count !== void 0) {
|
|
1081
|
+
const n = Math.max(spec.count, 1);
|
|
1082
|
+
const span = Math.max(spec.span ?? 1, 1);
|
|
1083
|
+
const spacing = spec.spacing ?? 0;
|
|
1084
|
+
a = span / n;
|
|
1085
|
+
b = -spacing * (n - 1) * span / n + spacing * (span - 1);
|
|
1086
|
+
}
|
|
1087
|
+
return { ...horizontal ? { horizontal: true } : {}, ...vertical ? { vertical: true } : {}, a, b, alignment: spec.alignment ?? "center" };
|
|
1088
|
+
}
|
|
1135
1089
|
const MODIFIER_KEYS = /* @__PURE__ */ new Set([
|
|
1136
1090
|
"padding",
|
|
1137
1091
|
"font",
|
|
@@ -1230,7 +1184,13 @@ const MODIFIER_KEYS = /* @__PURE__ */ new Set([
|
|
|
1230
1184
|
"sensoryFeedback",
|
|
1231
1185
|
"textCase",
|
|
1232
1186
|
"coordinateSpace",
|
|
1233
|
-
"contentTransition"
|
|
1187
|
+
"contentTransition",
|
|
1188
|
+
"scrollEdgeEffectStyle",
|
|
1189
|
+
"scrollEdgeEffectHidden",
|
|
1190
|
+
"contentMargins",
|
|
1191
|
+
"containerRelativeFrame",
|
|
1192
|
+
"visualEffect",
|
|
1193
|
+
"scrollTransition"
|
|
1234
1194
|
]);
|
|
1235
1195
|
function splitProps(props) {
|
|
1236
1196
|
const own = {};
|
|
@@ -1535,7 +1495,7 @@ function apply(key, value, node, sides) {
|
|
|
1535
1495
|
const spec = value;
|
|
1536
1496
|
const at = (width, height) => spec.value({ width, height });
|
|
1537
1497
|
const a = at(0, 0);
|
|
1538
|
-
const
|
|
1498
|
+
const round2 = (n) => Math.round(n * 1e6) / 1e6;
|
|
1539
1499
|
const vertical = ["top", "bottom", "verticalCenter", "firstTextBaseline", "lastTextBaseline"].includes(spec.guide);
|
|
1540
1500
|
const name = spec.guide === "horizontalCenter" || spec.guide === "verticalCenter" ? "center" : spec.guide;
|
|
1541
1501
|
return styled(
|
|
@@ -1543,7 +1503,7 @@ function apply(key, value, node, sides) {
|
|
|
1543
1503
|
alignmentGuide: {
|
|
1544
1504
|
axis: vertical ? "vertical" : "horizontal",
|
|
1545
1505
|
name,
|
|
1546
|
-
value: [
|
|
1506
|
+
value: [round2(a), round2((at(100, 0) - a) / 100), round2((at(0, 100) - a) / 100)]
|
|
1547
1507
|
}
|
|
1548
1508
|
},
|
|
1549
1509
|
node
|
|
@@ -1586,291 +1546,809 @@ function apply(key, value, node, sides) {
|
|
|
1586
1546
|
const spec = value;
|
|
1587
1547
|
return styled({ matchedGeometry: `${spec.namespace ?? ""}:${spec.id}` }, node);
|
|
1588
1548
|
}
|
|
1589
|
-
case "layoutValue":
|
|
1590
|
-
return node;
|
|
1591
|
-
case "safeAreaInset": {
|
|
1592
|
-
const spec = value;
|
|
1593
|
-
const vertical = spec.edge === "top" || spec.edge === "bottom";
|
|
1594
|
-
const before = spec.edge === "top" || spec.edge === "leading";
|
|
1595
|
-
const children = before ? [createElement(Fragment$1, { key: "inset" }, spec.content), createElement(Fragment$1, { key: "content" }, node)] : [createElement(Fragment$1, { key: "content" }, node), createElement(Fragment$1, { key: "inset" }, spec.content)];
|
|
1596
|
-
return vertical ? sb("vstack", { spacing: spec.spacing ?? 0, alignment: spec.alignment ?? "center" }, void 0, children) : sb("hstack", { spacing: spec.spacing ?? 0, alignment: spec.alignment ?? "center" }, void 0, children);
|
|
1549
|
+
case "layoutValue":
|
|
1550
|
+
return node;
|
|
1551
|
+
case "safeAreaInset": {
|
|
1552
|
+
const spec = value;
|
|
1553
|
+
const vertical = spec.edge === "top" || spec.edge === "bottom";
|
|
1554
|
+
const before = spec.edge === "top" || spec.edge === "leading";
|
|
1555
|
+
const children = before ? [createElement(Fragment$1, { key: "inset" }, spec.content), createElement(Fragment$1, { key: "content" }, node)] : [createElement(Fragment$1, { key: "content" }, node), createElement(Fragment$1, { key: "inset" }, spec.content)];
|
|
1556
|
+
return vertical ? sb("vstack", { spacing: spec.spacing ?? 0, alignment: spec.alignment ?? "center" }, void 0, children) : sb("hstack", { spacing: spec.spacing ?? 0, alignment: spec.alignment ?? "center" }, void 0, children);
|
|
1557
|
+
}
|
|
1558
|
+
case "popover":
|
|
1559
|
+
sides.push(createElement(SheetPresenter, value));
|
|
1560
|
+
return node;
|
|
1561
|
+
case "redacted":
|
|
1562
|
+
return withEnvironment({ redacted: Boolean(value) }, node);
|
|
1563
|
+
case "keyboardShortcut":
|
|
1564
|
+
return node;
|
|
1565
|
+
case "onKeyPress":
|
|
1566
|
+
sides.push(createElement(KeyPressListener, { spec: value }));
|
|
1567
|
+
return node;
|
|
1568
|
+
case "sensoryFeedback": {
|
|
1569
|
+
const spec = value;
|
|
1570
|
+
sides.push(createElement(SensoryFeedbackPlayer, spec));
|
|
1571
|
+
return node;
|
|
1572
|
+
}
|
|
1573
|
+
case "textCase":
|
|
1574
|
+
return withEnvironment({ textCase: value }, node);
|
|
1575
|
+
case "coordinateSpace":
|
|
1576
|
+
return createElement(CoordinateSpace, { name: value }, node);
|
|
1577
|
+
case "scrollEdgeEffectStyle":
|
|
1578
|
+
return withScrollSettings(edgeStyleSettings(value), node);
|
|
1579
|
+
case "scrollEdgeEffectHidden":
|
|
1580
|
+
return withScrollSettings(edgeHiddenSettings(value), node);
|
|
1581
|
+
case "contentMargins":
|
|
1582
|
+
return withScrollSettings(marginSettings(value), node);
|
|
1583
|
+
case "containerRelativeFrame":
|
|
1584
|
+
return styled({ containerRelativeFrame: containerRelativeFrame(value) }, node);
|
|
1585
|
+
case "visualEffect":
|
|
1586
|
+
return createElement(VisualEffectView, { effect: value }, node);
|
|
1587
|
+
case "scrollTransition": {
|
|
1588
|
+
const spec = typeof value === "function" ? { transition: value } : value;
|
|
1589
|
+
return createElement(ScrollTransitionView, { spec }, node);
|
|
1590
|
+
}
|
|
1591
|
+
case "contentTransition": {
|
|
1592
|
+
if (value === "identity") return node;
|
|
1593
|
+
if (typeof value === "object") {
|
|
1594
|
+
const countsDown = value.numericText.countsDown;
|
|
1595
|
+
return styled({ contentTransition: { kind: "numericText", ...countsDown !== void 0 ? { countsDown } : {} } }, node);
|
|
1596
|
+
}
|
|
1597
|
+
return styled({ contentTransition: { kind: value } }, node);
|
|
1598
|
+
}
|
|
1599
|
+
case "modifiers": {
|
|
1600
|
+
let result = node;
|
|
1601
|
+
for (const extra of value) {
|
|
1602
|
+
result = wrap(result, Object.entries(extra), sides);
|
|
1603
|
+
}
|
|
1604
|
+
return result;
|
|
1605
|
+
}
|
|
1606
|
+
default: {
|
|
1607
|
+
const unknown = key;
|
|
1608
|
+
throw new Error(`Unknown modifier ${String(unknown)}`);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
const ListSelectionContext = createContext(null);
|
|
1613
|
+
function Row({ tag, onDelete, deletable, onMove, movable, index, containerIndex, children }) {
|
|
1614
|
+
const selection = useContext(ListSelectionContext);
|
|
1615
|
+
const selectable = selection !== null && tag !== void 0;
|
|
1616
|
+
const canDelete = onDelete !== void 0 && deletable !== false;
|
|
1617
|
+
const canMove = onMove !== void 0 && movable !== false;
|
|
1618
|
+
if (!selectable && !canDelete && !canMove) return children;
|
|
1619
|
+
const props = {};
|
|
1620
|
+
if (selectable) {
|
|
1621
|
+
props["selectable"] = true;
|
|
1622
|
+
props["selected"] = selection.isSelected(tag);
|
|
1623
|
+
}
|
|
1624
|
+
if (canDelete) props["deletable"] = true;
|
|
1625
|
+
if (canMove) props["movable"] = true;
|
|
1626
|
+
return sb(
|
|
1627
|
+
"listrow",
|
|
1628
|
+
props,
|
|
1629
|
+
{
|
|
1630
|
+
tap: () => selectable && selection.select(tag),
|
|
1631
|
+
delete: () => onDelete?.(),
|
|
1632
|
+
move: (event) => {
|
|
1633
|
+
const start = (containerIndex ?? index ?? 0) - (index ?? 0);
|
|
1634
|
+
onMove?.(Math.max(0, event.to - start));
|
|
1635
|
+
}
|
|
1636
|
+
},
|
|
1637
|
+
children
|
|
1638
|
+
);
|
|
1639
|
+
}
|
|
1640
|
+
const LAZY_BATCH = 12;
|
|
1641
|
+
const LazyContext = createContext(null);
|
|
1642
|
+
function LazyGroup({ rows, start = 0, wrap: wrap2 }) {
|
|
1643
|
+
const axis = useContext(LazyContext);
|
|
1644
|
+
const request = useContext(ScrollRequestContext);
|
|
1645
|
+
const [count, setCount] = useState(LAZY_BATCH);
|
|
1646
|
+
const target = request ? rows.findIndex((row) => rowMatches(row, request.id)) : -1;
|
|
1647
|
+
const needed = target >= 0 ? Math.ceil((target + 1) / LAZY_BATCH) * LAZY_BATCH : 0;
|
|
1648
|
+
useEffect(() => {
|
|
1649
|
+
if (needed > count) setCount(needed);
|
|
1650
|
+
}, [needed, count]);
|
|
1651
|
+
const visible = Math.max(count, needed);
|
|
1652
|
+
const shown = axis === null ? rows : rows.slice(0, visible);
|
|
1653
|
+
const built = shown.map((row, index) => wrap2 ? wrap2(row, start + index) : row);
|
|
1654
|
+
if (axis === null || shown.length >= rows.length) return built;
|
|
1655
|
+
return [
|
|
1656
|
+
...built,
|
|
1657
|
+
createElement(
|
|
1658
|
+
LazySpacer,
|
|
1659
|
+
{ key: `lazy-${visible}`, axis, remaining: rows.length - shown.length, more: () => setCount(visible + LAZY_BATCH) }
|
|
1660
|
+
)
|
|
1661
|
+
];
|
|
1662
|
+
}
|
|
1663
|
+
function LazySpacer({ axis, remaining, more }) {
|
|
1664
|
+
return sb("lazyspacer", { axis, remaining }, { lazy: more });
|
|
1665
|
+
}
|
|
1666
|
+
function rowMatches(row, id) {
|
|
1667
|
+
if (row.key !== null && row.key === String(id)) return true;
|
|
1668
|
+
let element = row;
|
|
1669
|
+
for (let depth = 0; element && depth < 3; depth++) {
|
|
1670
|
+
const props = element.props;
|
|
1671
|
+
if (props.scrollID === id) return true;
|
|
1672
|
+
element = isValidElement(props.children) ? props.children : null;
|
|
1673
|
+
}
|
|
1674
|
+
return false;
|
|
1675
|
+
}
|
|
1676
|
+
function VStack(props) {
|
|
1677
|
+
const { own, modifiers } = splitProps(props);
|
|
1678
|
+
const stack = { spacing: own.spacing ?? null, alignment: own.alignment ?? "center" };
|
|
1679
|
+
if (own.scrollTargetLayout) stack["scrollTarget"] = true;
|
|
1680
|
+
return applyModifiers(sb("vstack", stack, void 0, own.children), modifiers);
|
|
1681
|
+
}
|
|
1682
|
+
function HStack(props) {
|
|
1683
|
+
const { own, modifiers } = splitProps(props);
|
|
1684
|
+
const stack = { spacing: own.spacing ?? null, alignment: own.alignment ?? "center" };
|
|
1685
|
+
if (own.scrollTargetLayout) stack["scrollTarget"] = true;
|
|
1686
|
+
return applyModifiers(sb("hstack", stack, void 0, own.children), modifiers);
|
|
1687
|
+
}
|
|
1688
|
+
function ZStack(props) {
|
|
1689
|
+
const { own, modifiers } = splitProps(props);
|
|
1690
|
+
return applyModifiers(sb("zstack", { alignment: own.alignment ?? "center" }, void 0, own.children), modifiers);
|
|
1691
|
+
}
|
|
1692
|
+
function Spacer(props) {
|
|
1693
|
+
const { own, modifiers } = splitProps(props);
|
|
1694
|
+
return applyModifiers(sb("spacer", { minLength: own.minLength ?? null }), modifiers);
|
|
1695
|
+
}
|
|
1696
|
+
function Divider(props) {
|
|
1697
|
+
const { modifiers } = splitProps(props);
|
|
1698
|
+
return applyModifiers(sb("divider", {}), modifiers);
|
|
1699
|
+
}
|
|
1700
|
+
function ScrollView(props) {
|
|
1701
|
+
const { own, modifiers } = splitProps(props);
|
|
1702
|
+
const refresh = useRefreshable(takeModifier(modifiers, "refreshable"));
|
|
1703
|
+
const ownSettings = takeScrollSettings(modifiers);
|
|
1704
|
+
const settings = useScrollSettings(ownSettings);
|
|
1705
|
+
const axes = own.axes ?? "vertical";
|
|
1706
|
+
const scroll = { axes, ...refresh.props };
|
|
1707
|
+
if (own.scrollTargetBehavior) scroll["snap"] = own.scrollTargetBehavior;
|
|
1708
|
+
if (own.scrollDismissesKeyboard) scroll["dismissesKeyboard"] = true;
|
|
1709
|
+
const edgeEffect = edgeEffectProp(settings);
|
|
1710
|
+
if (edgeEffect) scroll["edgeEffect"] = edgeEffect;
|
|
1711
|
+
const content = marginedContent(own.children, settings.margins, axes === "horizontal" ? "horizontal" : "vertical");
|
|
1712
|
+
return applyModifiers(sb("scrollview", scroll, refresh.handlers, providingScrollSettings(ownSettings, content)), modifiers);
|
|
1713
|
+
}
|
|
1714
|
+
function takeScrollSettings(modifiers) {
|
|
1715
|
+
let settings = {};
|
|
1716
|
+
const own = [];
|
|
1717
|
+
for (const key of ["scrollEdgeEffectStyle", "scrollEdgeEffectHidden", "contentMargins"]) {
|
|
1718
|
+
const value = takeModifier(modifiers, key);
|
|
1719
|
+
if (value === void 0) continue;
|
|
1720
|
+
if (key === "scrollEdgeEffectStyle") own.push(edgeStyleSettings(value));
|
|
1721
|
+
else if (key === "scrollEdgeEffectHidden") own.push(edgeHiddenSettings(value));
|
|
1722
|
+
else own.push(marginSettings(value));
|
|
1723
|
+
}
|
|
1724
|
+
for (const each of own) settings = mergeScrollSettings(settings, each);
|
|
1725
|
+
return settings;
|
|
1726
|
+
}
|
|
1727
|
+
function providingScrollSettings(settings, children) {
|
|
1728
|
+
return Object.keys(settings).length > 0 ? withScrollSettings(settings, children) : children;
|
|
1729
|
+
}
|
|
1730
|
+
function useRefreshable(own) {
|
|
1731
|
+
const environment = useViewEnvironment();
|
|
1732
|
+
const refresh = own ?? environment.refresh;
|
|
1733
|
+
const [refreshing, setRefreshing] = useState(false);
|
|
1734
|
+
if (!refresh) return { props: {} };
|
|
1735
|
+
return {
|
|
1736
|
+
props: { refreshable: true, refreshing },
|
|
1737
|
+
handlers: {
|
|
1738
|
+
refresh: () => {
|
|
1739
|
+
if (refreshing) return;
|
|
1740
|
+
setRefreshing(true);
|
|
1741
|
+
Promise.resolve().then(refresh).catch((error) => console.error(error)).finally(() => setRefreshing(false));
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
function Group(props) {
|
|
1747
|
+
const { own, modifiers } = splitProps(props);
|
|
1748
|
+
if (modifiers.length === 0) return own.children;
|
|
1749
|
+
return Children.map(own.children, (child) => applyModifiers(child, modifiers));
|
|
1750
|
+
}
|
|
1751
|
+
function moveItems(items, offsets, to) {
|
|
1752
|
+
const moving = new Set(offsets);
|
|
1753
|
+
const picked = items.filter((_, index) => moving.has(index));
|
|
1754
|
+
const rest = items.filter((_, index) => !moving.has(index));
|
|
1755
|
+
const before = offsets.filter((offset) => offset < to).length;
|
|
1756
|
+
const at = to - before;
|
|
1757
|
+
return [...rest.slice(0, at), ...picked, ...rest.slice(at)];
|
|
1758
|
+
}
|
|
1759
|
+
function ForEach(props) {
|
|
1760
|
+
const { own, modifiers } = splitProps(props);
|
|
1761
|
+
const rows = own.data.map((element, index) => {
|
|
1762
|
+
const key = own.id ? own.id(element, index) : keyOf(element, index);
|
|
1763
|
+
const content = applyModifiers(own.children(element, index), modifiers);
|
|
1764
|
+
if (!own.onDelete && !own.onMove) return createElement(Fragment$1, { key }, content);
|
|
1765
|
+
const { onDelete, onMove } = own;
|
|
1766
|
+
const row = { tag: key, index };
|
|
1767
|
+
if (onDelete) {
|
|
1768
|
+
row.onDelete = () => onDelete([index]);
|
|
1769
|
+
row.deletable = !own.deleteDisabled?.(element, index);
|
|
1770
|
+
}
|
|
1771
|
+
if (onMove) {
|
|
1772
|
+
row.onMove = (to) => onMove([index], to);
|
|
1773
|
+
row.movable = !own.moveDisabled?.(element, index);
|
|
1774
|
+
}
|
|
1775
|
+
return createElement(Row, { key, ...row }, content);
|
|
1776
|
+
});
|
|
1777
|
+
return rows.length > LAZY_BATCH ? createElement(LazyGroup, { rows }) : rows;
|
|
1778
|
+
}
|
|
1779
|
+
function keyOf(element, index) {
|
|
1780
|
+
if (typeof element === "string" || typeof element === "number") return element;
|
|
1781
|
+
if (typeof element === "object" && element !== null && "id" in element) {
|
|
1782
|
+
const id = element.id;
|
|
1783
|
+
if (typeof id === "string" || typeof id === "number") return id;
|
|
1784
|
+
}
|
|
1785
|
+
return index;
|
|
1786
|
+
}
|
|
1787
|
+
function flattenChildren(children, options = {}) {
|
|
1788
|
+
const result = [];
|
|
1789
|
+
const visit = (node) => {
|
|
1790
|
+
if (node === null || node === void 0 || typeof node === "boolean") return;
|
|
1791
|
+
if (Array.isArray(node)) {
|
|
1792
|
+
node.forEach(visit);
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
if (!isValidElement(node)) return;
|
|
1796
|
+
const element = node;
|
|
1797
|
+
if (element.type === Fragment$1) {
|
|
1798
|
+
const inner = element.props["children"];
|
|
1799
|
+
if (element.key !== null && isValidElement(inner) && inner.key === null && inner.type !== Fragment$1) {
|
|
1800
|
+
visit({ ...inner, key: element.key });
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1803
|
+
visit(inner);
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
if (element.type === ForEach) {
|
|
1807
|
+
visit(ForEach(element.props));
|
|
1808
|
+
return;
|
|
1597
1809
|
}
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
return
|
|
1601
|
-
case "redacted":
|
|
1602
|
-
return withEnvironment({ redacted: Boolean(value) }, node);
|
|
1603
|
-
case "keyboardShortcut":
|
|
1604
|
-
return node;
|
|
1605
|
-
case "onKeyPress":
|
|
1606
|
-
sides.push(createElement(KeyPressListener, { spec: value }));
|
|
1607
|
-
return node;
|
|
1608
|
-
case "sensoryFeedback": {
|
|
1609
|
-
const spec = value;
|
|
1610
|
-
sides.push(createElement(SensoryFeedbackPlayer, spec));
|
|
1611
|
-
return node;
|
|
1810
|
+
if (element.type === LazyGroup && !options.keepLazy) {
|
|
1811
|
+
visit(element.props.rows);
|
|
1812
|
+
return;
|
|
1612
1813
|
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1814
|
+
result.push(element);
|
|
1815
|
+
};
|
|
1816
|
+
visit(children);
|
|
1817
|
+
return result;
|
|
1818
|
+
}
|
|
1819
|
+
function GridItem(spec = {}) {
|
|
1820
|
+
const dimension = (n) => n === void 0 || n === Infinity ? "infinity" : n;
|
|
1821
|
+
let size;
|
|
1822
|
+
if (spec.size && "fixed" in spec.size) size = { kind: "fixed", value: spec.size.fixed };
|
|
1823
|
+
else if (spec.size && "adaptive" in spec.size) {
|
|
1824
|
+
size = { kind: "adaptive", minimum: spec.size.adaptive.minimum, maximum: dimension(spec.size.adaptive.maximum) };
|
|
1825
|
+
} else {
|
|
1826
|
+
const flexible = spec.size && "flexible" in spec.size ? spec.size.flexible : {};
|
|
1827
|
+
size = { kind: "flexible", minimum: flexible.minimum ?? 10, maximum: dimension(flexible.maximum) };
|
|
1828
|
+
}
|
|
1829
|
+
return { size, spacing: spec.spacing ?? null, alignment: spec.alignment ?? null };
|
|
1830
|
+
}
|
|
1831
|
+
GridItem.flexible = (options = {}) => GridItem({ size: { flexible: options }, spacing: options.spacing, alignment: options.alignment });
|
|
1832
|
+
GridItem.fixed = (value, options = {}) => GridItem({ size: { fixed: value }, spacing: options.spacing, alignment: options.alignment });
|
|
1833
|
+
GridItem.adaptive = (options) => GridItem({ size: { adaptive: options }, spacing: options.spacing, alignment: options.alignment });
|
|
1834
|
+
function LazyVGrid(props) {
|
|
1835
|
+
const { own, modifiers } = splitProps(props);
|
|
1836
|
+
return applyModifiers(
|
|
1837
|
+
sb("lazyvgrid", { columns: own.columns, spacing: own.spacing ?? null, alignment: own.alignment ?? "center" }, void 0, own.children),
|
|
1838
|
+
modifiers
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
function LazyHGrid(props) {
|
|
1842
|
+
const { own, modifiers } = splitProps(props);
|
|
1843
|
+
return applyModifiers(
|
|
1844
|
+
sb("lazyhgrid", { rows: own.rows, spacing: own.spacing ?? null, alignment: own.alignment ?? "center" }, void 0, own.children),
|
|
1845
|
+
modifiers
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
function Grid(props) {
|
|
1849
|
+
const { own, modifiers } = splitProps(props);
|
|
1850
|
+
return applyModifiers(
|
|
1851
|
+
sb(
|
|
1852
|
+
"grid",
|
|
1853
|
+
{ horizontalSpacing: own.horizontalSpacing ?? null, verticalSpacing: own.verticalSpacing ?? null, alignment: own.alignment ?? "center" },
|
|
1854
|
+
void 0,
|
|
1855
|
+
own.children
|
|
1856
|
+
),
|
|
1857
|
+
modifiers
|
|
1858
|
+
);
|
|
1859
|
+
}
|
|
1860
|
+
function GridRow(props) {
|
|
1861
|
+
const { own, modifiers } = splitProps(props);
|
|
1862
|
+
return applyModifiers(sb("gridrow", { alignment: own.alignment ?? null }, void 0, own.children), modifiers);
|
|
1863
|
+
}
|
|
1864
|
+
const NO_INSETS = { top: 0, leading: 0, bottom: 0, trailing: 0 };
|
|
1865
|
+
const NO_GEOMETRY = { size: { width: 0, height: 0 }, origin: null, safeArea: NO_INSETS, scrollView: null };
|
|
1866
|
+
function nextGeometry(event, reported) {
|
|
1867
|
+
const hasOrigin = event.x !== void 0 && event.y !== void 0;
|
|
1868
|
+
return {
|
|
1869
|
+
size: { width: event.width, height: event.height },
|
|
1870
|
+
origin: hasOrigin ? { x: event.x, y: event.y } : reported.origin,
|
|
1871
|
+
safeArea: event.safeArea ?? reported.safeArea,
|
|
1872
|
+
// A frame report without a scroll view means the reader is in none.
|
|
1873
|
+
scrollView: hasOrigin ? event.scrollView ?? null : reported.scrollView
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1876
|
+
function geometryProxy(reported, spaces, onReadFrame) {
|
|
1877
|
+
return {
|
|
1878
|
+
size: reported.size,
|
|
1879
|
+
frame: (space = "local") => {
|
|
1880
|
+
if (space === "local") return { x: 0, y: 0, ...reported.size };
|
|
1881
|
+
onReadFrame();
|
|
1882
|
+
const origin = reported.origin ?? { x: 0, y: 0 };
|
|
1883
|
+
if (space === "global") return { ...origin, ...reported.size };
|
|
1884
|
+
const named = spaces[space.named];
|
|
1885
|
+
return { x: origin.x - (named?.x ?? 0), y: origin.y - (named?.y ?? 0), ...reported.size };
|
|
1886
|
+
},
|
|
1887
|
+
bounds: () => {
|
|
1888
|
+
onReadFrame();
|
|
1889
|
+
const view = reported.scrollView;
|
|
1890
|
+
if (!view || !reported.origin) return null;
|
|
1891
|
+
return { x: view.x - reported.origin.x, y: view.y - reported.origin.y, width: view.width, height: view.height };
|
|
1892
|
+
},
|
|
1893
|
+
get safeAreaInsets() {
|
|
1894
|
+
onReadFrame();
|
|
1895
|
+
return reported.safeArea;
|
|
1624
1896
|
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
function GeometryReader(props) {
|
|
1900
|
+
const { own, modifiers } = splitProps(props);
|
|
1901
|
+
const [reported, setReported] = useState(NO_GEOMETRY);
|
|
1902
|
+
const [needsFrame, setNeedsFrame] = useState(false);
|
|
1903
|
+
let readFrame = false;
|
|
1904
|
+
const proxy = geometryProxy(reported, useCoordinateSpaces(), () => {
|
|
1905
|
+
readFrame = true;
|
|
1906
|
+
});
|
|
1907
|
+
const content = own.children(proxy);
|
|
1908
|
+
useEffect(() => {
|
|
1909
|
+
if (readFrame && !needsFrame) setNeedsFrame(true);
|
|
1910
|
+
});
|
|
1911
|
+
return applyModifiers(
|
|
1912
|
+
sb(
|
|
1913
|
+
"geometry",
|
|
1914
|
+
needsFrame ? { reportsFrame: true } : {},
|
|
1915
|
+
{
|
|
1916
|
+
geometry: (event) => {
|
|
1917
|
+
const next = nextGeometry(event, reported);
|
|
1918
|
+
if (JSON.stringify(next) !== JSON.stringify(reported)) setReported(next);
|
|
1919
|
+
}
|
|
1920
|
+
},
|
|
1921
|
+
content
|
|
1922
|
+
),
|
|
1923
|
+
modifiers
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
const DEFAULT_VIEW_SPACING = { distance: () => 8 };
|
|
1927
|
+
function subviewTraits(children) {
|
|
1928
|
+
return flattenChildren(children).map((element) => {
|
|
1929
|
+
const props = element.props;
|
|
1930
|
+
return { priority: props.layoutPriority ?? 0, values: props.layoutValue ?? {} };
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1933
|
+
const fromDimension = (value) => value === "infinity" ? Infinity : value;
|
|
1934
|
+
const toDimension = (value) => Number.isFinite(value) ? Math.round(value * 100) / 100 : "infinity";
|
|
1935
|
+
const toSize = (size) => ({
|
|
1936
|
+
width: fromDimension(size.width) ?? 0,
|
|
1937
|
+
height: fromDimension(size.height) ?? 0
|
|
1938
|
+
});
|
|
1939
|
+
const GUIDES = ["leading", "horizontalCenter", "trailing", "top", "verticalCenter", "bottom", "firstTextBaseline", "lastTextBaseline"];
|
|
1940
|
+
function clamp(value, min, max) {
|
|
1941
|
+
return Math.min(Math.max(value, min), max);
|
|
1942
|
+
}
|
|
1943
|
+
function answerLayout(layout, record, traits = []) {
|
|
1944
|
+
const frames = record.children.map(() => null);
|
|
1945
|
+
const subviews = record.children.map((measurement, index) => {
|
|
1946
|
+
const min = toSize(measurement.min);
|
|
1947
|
+
const ideal = toSize(measurement.ideal);
|
|
1948
|
+
const max = toSize(measurement.max);
|
|
1949
|
+
const sizeThatFits = (proposal) => ({
|
|
1950
|
+
width: proposal.width === null ? ideal.width : clamp(proposal.width, min.width, max.width),
|
|
1951
|
+
height: proposal.height === null ? ideal.height : clamp(proposal.height, min.height, max.height)
|
|
1952
|
+
});
|
|
1953
|
+
return {
|
|
1954
|
+
min,
|
|
1955
|
+
ideal,
|
|
1956
|
+
max,
|
|
1957
|
+
priority: traits[index]?.priority ?? 0,
|
|
1958
|
+
values: traits[index]?.values ?? {},
|
|
1959
|
+
spacing: DEFAULT_VIEW_SPACING,
|
|
1960
|
+
sizeThatFits,
|
|
1961
|
+
place: ({ x, y, anchor, proposal }) => {
|
|
1962
|
+
const size2 = sizeThatFits(proposal ?? { width: null, height: null });
|
|
1963
|
+
const point = unitPoint(anchor ?? "topLeading");
|
|
1964
|
+
frames[index] = { x: x - point.x * size2.width, y: y - point.y * size2.height, ...size2 };
|
|
1629
1965
|
}
|
|
1630
|
-
|
|
1966
|
+
};
|
|
1967
|
+
});
|
|
1968
|
+
const cache = layout.makeCache ? layout.makeCache(subviews) : void 0;
|
|
1969
|
+
const measure = (proposal) => layout.sizeThatFits(proposal, subviews, cache);
|
|
1970
|
+
const size = measure(record.proposal);
|
|
1971
|
+
layout.placeSubviews({ x: 0, y: 0, ...size }, record.proposal, subviews, cache);
|
|
1972
|
+
const placed = frames.map((frame2, index) => {
|
|
1973
|
+
if (frame2) return frame2;
|
|
1974
|
+
const own = subviews[index].sizeThatFits({ width: size.width, height: size.height });
|
|
1975
|
+
return { x: (size.width - own.width) / 2, y: (size.height - own.height) / 2, ...own };
|
|
1976
|
+
});
|
|
1977
|
+
const guides = {};
|
|
1978
|
+
if (layout.explicitAlignment) {
|
|
1979
|
+
const bounds = { x: 0, y: 0, ...size };
|
|
1980
|
+
for (const guide of GUIDES) {
|
|
1981
|
+
const value = layout.explicitAlignment(guide, bounds, record.proposal, subviews, cache);
|
|
1982
|
+
if (value !== null && value !== void 0 && Number.isFinite(value)) guides[guide] = value;
|
|
1631
1983
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1984
|
+
}
|
|
1985
|
+
return {
|
|
1986
|
+
size,
|
|
1987
|
+
frames: placed,
|
|
1988
|
+
guides,
|
|
1989
|
+
sizes: {
|
|
1990
|
+
min: measure({ width: 0, height: 0 }),
|
|
1991
|
+
ideal: measure({ width: null, height: null }),
|
|
1992
|
+
max: measure({ width: Infinity, height: Infinity })
|
|
1635
1993
|
}
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
function Layout(props) {
|
|
1997
|
+
const { own, modifiers } = splitProps(props);
|
|
1998
|
+
const [record, setRecord] = useState(null);
|
|
1999
|
+
let layoutProps = { proposal: null, size: null, frames: null };
|
|
2000
|
+
const guideModifiers = [];
|
|
2001
|
+
if (record) {
|
|
2002
|
+
const answer = answerLayout(own.layout, record, subviewTraits(own.children));
|
|
2003
|
+
for (const [guide, value] of Object.entries(answer.guides)) guideModifiers.push(["alignmentGuide", { guide, value: () => value }]);
|
|
2004
|
+
const encode = (size) => ({ width: toDimension(size.width), height: toDimension(size.height) });
|
|
2005
|
+
const round2 = (value) => Math.round(value * 100) / 100;
|
|
2006
|
+
layoutProps = {
|
|
2007
|
+
proposal: {
|
|
2008
|
+
width: record.proposal.width === null ? null : toDimension(record.proposal.width),
|
|
2009
|
+
height: record.proposal.height === null ? null : toDimension(record.proposal.height)
|
|
2010
|
+
},
|
|
2011
|
+
size: { width: round2(answer.size.width), height: round2(answer.size.height) },
|
|
2012
|
+
frames: answer.frames.map((frame2) => ({ x: round2(frame2.x), y: round2(frame2.y), width: round2(frame2.width), height: round2(frame2.height) })),
|
|
2013
|
+
sizes: { min: encode(answer.sizes.min), ideal: encode(answer.sizes.ideal), max: encode(answer.sizes.max) }
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
return applyModifiers(
|
|
2017
|
+
sb(
|
|
2018
|
+
"layout",
|
|
2019
|
+
layoutProps,
|
|
2020
|
+
{
|
|
2021
|
+
layout: (event) => {
|
|
2022
|
+
const proposal = event.proposal;
|
|
2023
|
+
setRecord({
|
|
2024
|
+
proposal: { width: fromDimension(proposal.width), height: fromDimension(proposal.height) },
|
|
2025
|
+
children: event.children
|
|
2026
|
+
});
|
|
2027
|
+
}
|
|
2028
|
+
},
|
|
2029
|
+
own.children
|
|
2030
|
+
),
|
|
2031
|
+
[...guideModifiers, ...modifiers]
|
|
2032
|
+
);
|
|
2033
|
+
}
|
|
2034
|
+
const IDENTITY$1 = {
|
|
2035
|
+
offsetX: 0,
|
|
2036
|
+
offsetY: 0,
|
|
2037
|
+
scaleX: 1,
|
|
2038
|
+
scaleY: 1,
|
|
2039
|
+
rotation: 0,
|
|
2040
|
+
opacity: 1,
|
|
2041
|
+
blur: 0,
|
|
2042
|
+
brightness: 0,
|
|
2043
|
+
contrast: 1,
|
|
2044
|
+
saturation: 1,
|
|
2045
|
+
grayscale: 0,
|
|
2046
|
+
hueRotation: 0
|
|
2047
|
+
};
|
|
2048
|
+
class VisualEffect {
|
|
2049
|
+
/** @internal */
|
|
2050
|
+
constructor(values = IDENTITY$1) {
|
|
2051
|
+
this.values = values;
|
|
2052
|
+
}
|
|
2053
|
+
values;
|
|
2054
|
+
with(patch) {
|
|
2055
|
+
return new VisualEffect({ ...this.values, ...patch });
|
|
2056
|
+
}
|
|
2057
|
+
offset(offset) {
|
|
2058
|
+
return this.with({ offsetX: this.values.offsetX + (offset.x ?? 0), offsetY: this.values.offsetY + (offset.y ?? 0) });
|
|
2059
|
+
}
|
|
2060
|
+
scaleEffect(scale, anchor) {
|
|
2061
|
+
const x = typeof scale === "number" ? scale : scale.x ?? 1;
|
|
2062
|
+
const y = typeof scale === "number" ? scale : scale.y ?? 1;
|
|
2063
|
+
return this.with({ scaleX: this.values.scaleX * x, scaleY: this.values.scaleY * y, ...anchor !== void 0 ? { scaleAnchor: unitPoint(anchor) } : {} });
|
|
2064
|
+
}
|
|
2065
|
+
/** Degrees. */
|
|
2066
|
+
rotationEffect(degrees, anchor) {
|
|
2067
|
+
return this.with({ rotation: this.values.rotation + degrees, ...anchor !== void 0 ? { rotationAnchor: unitPoint(anchor) } : {} });
|
|
2068
|
+
}
|
|
2069
|
+
rotation3DEffect(spec) {
|
|
2070
|
+
const rotation = { angle: spec.angle, axis: spec.axis };
|
|
2071
|
+
if (spec.anchor !== void 0) rotation.anchor = unitPoint(spec.anchor);
|
|
2072
|
+
if (spec.perspective !== void 0) rotation.perspective = spec.perspective;
|
|
2073
|
+
return this.with({ rotation3D: rotation });
|
|
2074
|
+
}
|
|
2075
|
+
opacity(opacity2) {
|
|
2076
|
+
return this.with({ opacity: this.values.opacity * opacity2 });
|
|
2077
|
+
}
|
|
2078
|
+
blur(radius) {
|
|
2079
|
+
return this.with({ blur: this.values.blur + radius });
|
|
2080
|
+
}
|
|
2081
|
+
brightness(amount) {
|
|
2082
|
+
return this.with({ brightness: this.values.brightness + amount });
|
|
2083
|
+
}
|
|
2084
|
+
contrast(amount) {
|
|
2085
|
+
return this.with({ contrast: this.values.contrast * amount });
|
|
2086
|
+
}
|
|
2087
|
+
saturation(amount) {
|
|
2088
|
+
return this.with({ saturation: this.values.saturation * amount });
|
|
2089
|
+
}
|
|
2090
|
+
grayscale(amount) {
|
|
2091
|
+
return this.with({ grayscale: Math.min(1, this.values.grayscale + amount) });
|
|
2092
|
+
}
|
|
2093
|
+
/** Degrees. */
|
|
2094
|
+
hueRotation(degrees) {
|
|
2095
|
+
return this.with({ hueRotation: this.values.hueRotation + degrees });
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
const EMPTY_EFFECT = new VisualEffect();
|
|
2099
|
+
const round = (value) => Math.round(value * 1e3) / 1e3;
|
|
2100
|
+
function effectStyle(values) {
|
|
2101
|
+
const style = {};
|
|
2102
|
+
if (values.offsetX !== 0 || values.offsetY !== 0) style.offset = { x: round(values.offsetX), y: round(values.offsetY) };
|
|
2103
|
+
if (values.scaleX !== 1 || values.scaleY !== 1) {
|
|
2104
|
+
style.scale = { x: round(values.scaleX), y: round(values.scaleY) };
|
|
2105
|
+
if (values.scaleAnchor) style.scaleAnchor = values.scaleAnchor;
|
|
2106
|
+
}
|
|
2107
|
+
if (values.rotation !== 0) {
|
|
2108
|
+
style.rotation = round(values.rotation);
|
|
2109
|
+
if (values.rotationAnchor) style.rotationAnchor = values.rotationAnchor;
|
|
1636
2110
|
}
|
|
2111
|
+
if (values.rotation3D && values.rotation3D.angle !== 0) style.rotation3D = { ...values.rotation3D, angle: round(values.rotation3D.angle) };
|
|
2112
|
+
if (values.opacity !== 1) style.opacity = round(values.opacity);
|
|
2113
|
+
if (values.blur !== 0) style.blur = round(values.blur);
|
|
2114
|
+
if (values.brightness !== 0) style.brightness = round(values.brightness);
|
|
2115
|
+
if (values.contrast !== 1) style.contrast = round(values.contrast);
|
|
2116
|
+
if (values.saturation !== 1) style.saturation = round(values.saturation);
|
|
2117
|
+
if (values.grayscale !== 0) style.grayscale = round(values.grayscale);
|
|
2118
|
+
if (values.hueRotation !== 0) style.hueRotation = round(values.hueRotation);
|
|
2119
|
+
return style;
|
|
1637
2120
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
2121
|
+
function interpolateEffects(from, to, t) {
|
|
2122
|
+
const mix = (a, b) => a + (b - a) * t;
|
|
2123
|
+
const result = {
|
|
2124
|
+
offsetX: mix(from.offsetX, to.offsetX),
|
|
2125
|
+
offsetY: mix(from.offsetY, to.offsetY),
|
|
2126
|
+
scaleX: mix(from.scaleX, to.scaleX),
|
|
2127
|
+
scaleY: mix(from.scaleY, to.scaleY),
|
|
2128
|
+
rotation: mix(from.rotation, to.rotation),
|
|
2129
|
+
opacity: mix(from.opacity, to.opacity),
|
|
2130
|
+
blur: mix(from.blur, to.blur),
|
|
2131
|
+
brightness: mix(from.brightness, to.brightness),
|
|
2132
|
+
contrast: mix(from.contrast, to.contrast),
|
|
2133
|
+
saturation: mix(from.saturation, to.saturation),
|
|
2134
|
+
grayscale: mix(from.grayscale, to.grayscale),
|
|
2135
|
+
hueRotation: mix(from.hueRotation, to.hueRotation)
|
|
1644
2136
|
};
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
2137
|
+
const scaleAnchor = to.scaleAnchor ?? from.scaleAnchor;
|
|
2138
|
+
if (scaleAnchor) result.scaleAnchor = scaleAnchor;
|
|
2139
|
+
const rotationAnchor = to.rotationAnchor ?? from.rotationAnchor;
|
|
2140
|
+
if (rotationAnchor) result.rotationAnchor = rotationAnchor;
|
|
2141
|
+
const rotation3D = to.rotation3D ?? from.rotation3D;
|
|
2142
|
+
if (rotation3D) result.rotation3D = { ...rotation3D, angle: mix(from.rotation3D?.angle ?? 0, to.rotation3D?.angle ?? 0) };
|
|
2143
|
+
return result;
|
|
1651
2144
|
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
|
-
|
|
2145
|
+
function EffectBox({
|
|
2146
|
+
render,
|
|
2147
|
+
alwaysFrame,
|
|
2148
|
+
animationToken,
|
|
2149
|
+
children
|
|
2150
|
+
}) {
|
|
2151
|
+
const [reported, setReported] = useState(NO_GEOMETRY);
|
|
2152
|
+
const [needsFrame, setNeedsFrame] = useState(alwaysFrame);
|
|
2153
|
+
let readFrame = false;
|
|
2154
|
+
const style = render(reported, () => {
|
|
2155
|
+
readFrame = true;
|
|
2156
|
+
});
|
|
2157
|
+
useEffect(() => {
|
|
2158
|
+
if (readFrame && !needsFrame) setNeedsFrame(true);
|
|
2159
|
+
});
|
|
2160
|
+
let content = Object.keys(style).length > 0 ? sb("styled", { style }, void 0, children) : children;
|
|
2161
|
+
if (animationToken) content = sb("styled", { style: { animation: { type: "default" }, animationToken: animationToken(reported) } }, void 0, content);
|
|
1666
2162
|
return sb(
|
|
1667
|
-
"
|
|
1668
|
-
|
|
2163
|
+
"zstack",
|
|
2164
|
+
{ alignment: "center", reportsSize: true, ...needsFrame ? { reportsFrame: true } : {} },
|
|
1669
2165
|
{
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
const start = (containerIndex ?? index ?? 0) - (index ?? 0);
|
|
1674
|
-
onMove?.(Math.max(0, event.to - start));
|
|
2166
|
+
geometry: (event) => {
|
|
2167
|
+
const next = nextGeometry(event, reported);
|
|
2168
|
+
if (JSON.stringify(next) !== JSON.stringify(reported)) setReported(next);
|
|
1675
2169
|
}
|
|
1676
2170
|
},
|
|
1677
|
-
|
|
2171
|
+
content
|
|
1678
2172
|
);
|
|
1679
2173
|
}
|
|
1680
|
-
|
|
1681
|
-
const
|
|
1682
|
-
|
|
1683
|
-
const axis = useContext(LazyContext);
|
|
1684
|
-
const request = useContext(ScrollRequestContext);
|
|
1685
|
-
const [count, setCount] = useState(LAZY_BATCH);
|
|
1686
|
-
const target = request ? rows.findIndex((row) => rowMatches(row, request.id)) : -1;
|
|
1687
|
-
const needed = target >= 0 ? Math.ceil((target + 1) / LAZY_BATCH) * LAZY_BATCH : 0;
|
|
1688
|
-
useEffect(() => {
|
|
1689
|
-
if (needed > count) setCount(needed);
|
|
1690
|
-
}, [needed, count]);
|
|
1691
|
-
const visible = Math.max(count, needed);
|
|
1692
|
-
const shown = axis === null ? rows : rows.slice(0, visible);
|
|
1693
|
-
const built = shown.map((row, index) => wrap2 ? wrap2(row, start + index) : row);
|
|
1694
|
-
if (axis === null || shown.length >= rows.length) return built;
|
|
1695
|
-
return [
|
|
1696
|
-
...built,
|
|
1697
|
-
createElement(
|
|
1698
|
-
LazySpacer,
|
|
1699
|
-
{ key: `lazy-${visible}`, axis, remaining: rows.length - shown.length, more: () => setCount(visible + LAZY_BATCH) }
|
|
1700
|
-
)
|
|
1701
|
-
];
|
|
1702
|
-
}
|
|
1703
|
-
function LazySpacer({ axis, remaining, more }) {
|
|
1704
|
-
return sb("lazyspacer", { axis, remaining }, { lazy: more });
|
|
1705
|
-
}
|
|
1706
|
-
function rowMatches(row, id) {
|
|
1707
|
-
if (row.key !== null && row.key === String(id)) return true;
|
|
1708
|
-
let element = row;
|
|
1709
|
-
for (let depth = 0; element && depth < 3; depth++) {
|
|
1710
|
-
const props = element.props;
|
|
1711
|
-
if (props.scrollID === id) return true;
|
|
1712
|
-
element = isValidElement(props.children) ? props.children : null;
|
|
1713
|
-
}
|
|
1714
|
-
return false;
|
|
1715
|
-
}
|
|
1716
|
-
function VStack(props) {
|
|
1717
|
-
const { own, modifiers } = splitProps(props);
|
|
1718
|
-
const stack = { spacing: own.spacing ?? null, alignment: own.alignment ?? "center" };
|
|
1719
|
-
if (own.scrollTargetLayout) stack["scrollTarget"] = true;
|
|
1720
|
-
return applyModifiers(sb("vstack", stack, void 0, own.children), modifiers);
|
|
1721
|
-
}
|
|
1722
|
-
function HStack(props) {
|
|
1723
|
-
const { own, modifiers } = splitProps(props);
|
|
1724
|
-
const stack = { spacing: own.spacing ?? null, alignment: own.alignment ?? "center" };
|
|
1725
|
-
if (own.scrollTargetLayout) stack["scrollTarget"] = true;
|
|
1726
|
-
return applyModifiers(sb("hstack", stack, void 0, own.children), modifiers);
|
|
1727
|
-
}
|
|
1728
|
-
function ZStack(props) {
|
|
1729
|
-
const { own, modifiers } = splitProps(props);
|
|
1730
|
-
return applyModifiers(sb("zstack", { alignment: own.alignment ?? "center" }, void 0, own.children), modifiers);
|
|
1731
|
-
}
|
|
1732
|
-
function Spacer(props) {
|
|
1733
|
-
const { own, modifiers } = splitProps(props);
|
|
1734
|
-
return applyModifiers(sb("spacer", { minLength: own.minLength ?? null }), modifiers);
|
|
1735
|
-
}
|
|
1736
|
-
function Divider(props) {
|
|
1737
|
-
const { modifiers } = splitProps(props);
|
|
1738
|
-
return applyModifiers(sb("divider", {}), modifiers);
|
|
1739
|
-
}
|
|
1740
|
-
function ScrollView(props) {
|
|
1741
|
-
const { own, modifiers } = splitProps(props);
|
|
1742
|
-
const refresh = useRefreshable(takeModifier(modifiers, "refreshable"));
|
|
1743
|
-
const scroll = { axes: own.axes ?? "vertical", ...refresh.props };
|
|
1744
|
-
if (own.scrollTargetBehavior) scroll["snap"] = own.scrollTargetBehavior;
|
|
1745
|
-
if (own.scrollDismissesKeyboard) scroll["dismissesKeyboard"] = true;
|
|
1746
|
-
return applyModifiers(sb("scrollview", scroll, refresh.handlers, own.children), modifiers);
|
|
1747
|
-
}
|
|
1748
|
-
function useRefreshable(own) {
|
|
1749
|
-
const environment = useViewEnvironment();
|
|
1750
|
-
const refresh = own ?? environment.refresh;
|
|
1751
|
-
const [refreshing, setRefreshing] = useState(false);
|
|
1752
|
-
if (!refresh) return { props: {} };
|
|
1753
|
-
return {
|
|
1754
|
-
props: { refreshable: true, refreshing },
|
|
1755
|
-
handlers: {
|
|
1756
|
-
refresh: () => {
|
|
1757
|
-
if (refreshing) return;
|
|
1758
|
-
setRefreshing(true);
|
|
1759
|
-
Promise.resolve().then(refresh).catch((error) => console.error(error)).finally(() => setRefreshing(false));
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
};
|
|
1763
|
-
}
|
|
1764
|
-
function Group(props) {
|
|
1765
|
-
const { own, modifiers } = splitProps(props);
|
|
1766
|
-
if (modifiers.length === 0) return own.children;
|
|
1767
|
-
return Children.map(own.children, (child) => applyModifiers(child, modifiers));
|
|
1768
|
-
}
|
|
1769
|
-
function moveItems(items, offsets, to) {
|
|
1770
|
-
const moving = new Set(offsets);
|
|
1771
|
-
const picked = items.filter((_, index) => moving.has(index));
|
|
1772
|
-
const rest = items.filter((_, index) => !moving.has(index));
|
|
1773
|
-
const before = offsets.filter((offset) => offset < to).length;
|
|
1774
|
-
const at = to - before;
|
|
1775
|
-
return [...rest.slice(0, at), ...picked, ...rest.slice(at)];
|
|
2174
|
+
function VisualEffectView({ effect, children }) {
|
|
2175
|
+
const spaces = useCoordinateSpaces();
|
|
2176
|
+
return /* @__PURE__ */ jsx(EffectBox, { alwaysFrame: false, render: (reported, markRead) => effectStyle(effect(EMPTY_EFFECT, geometryProxy(reported, spaces, markRead)).values), children });
|
|
1776
2177
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
2178
|
+
const PHASES = {
|
|
2179
|
+
topLeading: { phase: "topLeading", value: -1, isIdentity: false },
|
|
2180
|
+
identity: { phase: "identity", value: 0, isIdentity: true },
|
|
2181
|
+
bottomTrailing: { phase: "bottomTrailing", value: 1, isIdentity: false }
|
|
2182
|
+
};
|
|
2183
|
+
function scrollProgress(reported, axis) {
|
|
2184
|
+
const view = reported.scrollView;
|
|
2185
|
+
const origin = reported.origin;
|
|
2186
|
+
if (!view || !origin) return 0;
|
|
2187
|
+
const horizontal = (axis ?? view.axis) === "horizontal";
|
|
2188
|
+
const start = horizontal ? origin.x : origin.y;
|
|
2189
|
+
const length = horizontal ? reported.size.width : reported.size.height;
|
|
2190
|
+
const viewStart = horizontal ? view.x : view.y;
|
|
2191
|
+
const viewEnd = viewStart + (horizontal ? view.width : view.height);
|
|
2192
|
+
if (length <= 0) return 0;
|
|
2193
|
+
if (start < viewStart) return -Math.min(1, (viewStart - start) / length);
|
|
2194
|
+
if (start + length > viewEnd) return Math.min(1, (start + length - viewEnd) / length);
|
|
2195
|
+
return 0;
|
|
2196
|
+
}
|
|
2197
|
+
function scrollTransitionValues(spec, progress) {
|
|
2198
|
+
const identity = spec.transition(EMPTY_EFFECT, PHASES.identity).values;
|
|
2199
|
+
const configuration = spec.configuration ?? "interactive";
|
|
2200
|
+
if (configuration === "identity" || progress === 0) return identity;
|
|
2201
|
+
const edge = spec.transition(EMPTY_EFFECT, progress < 0 ? PHASES.topLeading : PHASES.bottomTrailing).values;
|
|
2202
|
+
if (configuration === "animated") return edge;
|
|
2203
|
+
return interpolateEffects(identity, edge, Math.abs(progress));
|
|
2204
|
+
}
|
|
2205
|
+
function ScrollTransitionView({ spec, children }) {
|
|
2206
|
+
return /* @__PURE__ */ jsx(
|
|
2207
|
+
EffectBox,
|
|
2208
|
+
{
|
|
2209
|
+
alwaysFrame: true,
|
|
2210
|
+
render: (reported) => effectStyle(scrollTransitionValues(spec, scrollProgress(reported, spec.axis))),
|
|
2211
|
+
...spec.configuration === "animated" ? { animationToken: (reported) => Math.sign(scrollProgress(reported, spec.axis)) + 1 } : {},
|
|
2212
|
+
children
|
|
1792
2213
|
}
|
|
1793
|
-
|
|
1794
|
-
});
|
|
1795
|
-
return rows.length > LAZY_BATCH ? createElement(LazyGroup, { rows }) : rows;
|
|
2214
|
+
);
|
|
1796
2215
|
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
2216
|
+
const r = (n) => {
|
|
2217
|
+
const v = Math.round(n * 100) / 100;
|
|
2218
|
+
return Object.is(v, -0) ? "0" : String(v);
|
|
2219
|
+
};
|
|
2220
|
+
class Path {
|
|
2221
|
+
parts = [];
|
|
2222
|
+
current = null;
|
|
2223
|
+
start = null;
|
|
2224
|
+
constructor(build) {
|
|
2225
|
+
build?.(this);
|
|
1802
2226
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
}
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
2227
|
+
/** `Path(rect)` */
|
|
2228
|
+
static rect(rect) {
|
|
2229
|
+
return new Path().addRect(rect);
|
|
2230
|
+
}
|
|
2231
|
+
/** `Path(roundedRect:cornerRadius:)` */
|
|
2232
|
+
static roundedRect(rect, cornerRadius) {
|
|
2233
|
+
return new Path().addRoundedRect(rect, cornerRadius);
|
|
2234
|
+
}
|
|
2235
|
+
/** `Path(ellipseIn:)` */
|
|
2236
|
+
static ellipse(rect) {
|
|
2237
|
+
return new Path().addEllipse(rect);
|
|
2238
|
+
}
|
|
2239
|
+
move(to) {
|
|
2240
|
+
this.parts.push(`M${r(to.x)} ${r(to.y)}`);
|
|
2241
|
+
this.current = to;
|
|
2242
|
+
this.start = to;
|
|
2243
|
+
return this;
|
|
2244
|
+
}
|
|
2245
|
+
addLine(to) {
|
|
2246
|
+
if (!this.current) return this.move(to);
|
|
2247
|
+
this.parts.push(`L${r(to.x)} ${r(to.y)}`);
|
|
2248
|
+
this.current = to;
|
|
2249
|
+
return this;
|
|
2250
|
+
}
|
|
2251
|
+
addLines(points) {
|
|
2252
|
+
points.forEach((point, index) => index === 0 ? this.move(point) : this.addLine(point));
|
|
2253
|
+
return this;
|
|
2254
|
+
}
|
|
2255
|
+
addQuadCurve(to, control) {
|
|
2256
|
+
if (!this.current) this.move(control);
|
|
2257
|
+
this.parts.push(`Q${r(control.x)} ${r(control.y)} ${r(to.x)} ${r(to.y)}`);
|
|
2258
|
+
this.current = to;
|
|
2259
|
+
return this;
|
|
2260
|
+
}
|
|
2261
|
+
addCurve(to, control1, control2) {
|
|
2262
|
+
if (!this.current) this.move(control1);
|
|
2263
|
+
this.parts.push(`C${r(control1.x)} ${r(control1.y)} ${r(control2.x)} ${r(control2.y)} ${r(to.x)} ${r(to.y)}`);
|
|
2264
|
+
this.current = to;
|
|
2265
|
+
return this;
|
|
2266
|
+
}
|
|
2267
|
+
/**
|
|
2268
|
+
* `addArc(center:radius:startAngle:endAngle:clockwise:)`, angles in
|
|
2269
|
+
* degrees. As in SwiftUI's flipped coordinates, `clockwise: false` draws
|
|
2270
|
+
* clockwise on screen.
|
|
2271
|
+
*/
|
|
2272
|
+
addArc(center, radius, startAngle, endAngle, clockwise) {
|
|
2273
|
+
const rad = (deg) => deg * Math.PI / 180;
|
|
2274
|
+
const point = (deg) => ({ x: center.x + radius * Math.cos(rad(deg)), y: center.y + radius * Math.sin(rad(deg)) });
|
|
2275
|
+
const from = point(startAngle);
|
|
2276
|
+
if (this.current) this.addLine(from);
|
|
2277
|
+
else this.move(from);
|
|
2278
|
+
const sweepPositive = !clockwise;
|
|
2279
|
+
let delta = endAngle - startAngle;
|
|
2280
|
+
if (sweepPositive) while (delta < 0) delta += 360;
|
|
2281
|
+
else while (delta > 0) delta -= 360;
|
|
2282
|
+
if (Math.abs(delta) >= 360) {
|
|
2283
|
+
const half = point(startAngle + (sweepPositive ? 180 : -180));
|
|
2284
|
+
const flag = sweepPositive ? 1 : 0;
|
|
2285
|
+
this.parts.push(`A${r(radius)} ${r(radius)} 0 0 ${flag} ${r(half.x)} ${r(half.y)}`);
|
|
2286
|
+
this.parts.push(`A${r(radius)} ${r(radius)} 0 0 ${flag} ${r(from.x)} ${r(from.y)}`);
|
|
2287
|
+
this.current = from;
|
|
2288
|
+
return this;
|
|
1831
2289
|
}
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
2290
|
+
const to = point(startAngle + delta);
|
|
2291
|
+
const large = Math.abs(delta) > 180 ? 1 : 0;
|
|
2292
|
+
this.parts.push(`A${r(radius)} ${r(radius)} 0 ${large} ${sweepPositive ? 1 : 0} ${r(to.x)} ${r(to.y)}`);
|
|
2293
|
+
this.current = to;
|
|
2294
|
+
return this;
|
|
2295
|
+
}
|
|
2296
|
+
addRect(rect) {
|
|
2297
|
+
this.move({ x: rect.x, y: rect.y });
|
|
2298
|
+
this.addLine({ x: rect.x + rect.width, y: rect.y });
|
|
2299
|
+
this.addLine({ x: rect.x + rect.width, y: rect.y + rect.height });
|
|
2300
|
+
this.addLine({ x: rect.x, y: rect.y + rect.height });
|
|
2301
|
+
return this.closeSubpath();
|
|
2302
|
+
}
|
|
2303
|
+
addRoundedRect(rect, cornerRadius) {
|
|
2304
|
+
const c = Math.max(0, Math.min(cornerRadius, rect.width / 2, rect.height / 2));
|
|
2305
|
+
if (c === 0) return this.addRect(rect);
|
|
2306
|
+
const { x, y, width: w, height: h } = rect;
|
|
2307
|
+
this.move({ x: x + c, y });
|
|
2308
|
+
this.addLine({ x: x + w - c, y });
|
|
2309
|
+
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x + w)} ${r(y + c)}`);
|
|
2310
|
+
this.current = { x: x + w, y: y + c };
|
|
2311
|
+
this.addLine({ x: x + w, y: y + h - c });
|
|
2312
|
+
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x + w - c)} ${r(y + h)}`);
|
|
2313
|
+
this.current = { x: x + w - c, y: y + h };
|
|
2314
|
+
this.addLine({ x: x + c, y: y + h });
|
|
2315
|
+
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x)} ${r(y + h - c)}`);
|
|
2316
|
+
this.current = { x, y: y + h - c };
|
|
2317
|
+
this.addLine({ x, y: y + c });
|
|
2318
|
+
this.parts.push(`A${r(c)} ${r(c)} 0 0 1 ${r(x + c)} ${r(y)}`);
|
|
2319
|
+
this.current = { x: x + c, y };
|
|
2320
|
+
return this.closeSubpath();
|
|
2321
|
+
}
|
|
2322
|
+
addEllipse(rect) {
|
|
2323
|
+
const rx = rect.width / 2;
|
|
2324
|
+
const ry = rect.height / 2;
|
|
2325
|
+
const cx = rect.x + rx;
|
|
2326
|
+
const cy = rect.y + ry;
|
|
2327
|
+
this.move({ x: cx + rx, y: cy });
|
|
2328
|
+
this.parts.push(`A${r(rx)} ${r(ry)} 0 0 1 ${r(cx - rx)} ${r(cy)}`);
|
|
2329
|
+
this.parts.push(`A${r(rx)} ${r(ry)} 0 0 1 ${r(cx + rx)} ${r(cy)}`);
|
|
2330
|
+
this.current = { x: cx + rx, y: cy };
|
|
2331
|
+
return this.closeSubpath();
|
|
2332
|
+
}
|
|
2333
|
+
addPath(path) {
|
|
2334
|
+
this.parts.push(path.svg());
|
|
2335
|
+
return this;
|
|
2336
|
+
}
|
|
2337
|
+
closeSubpath() {
|
|
2338
|
+
this.parts.push("Z");
|
|
2339
|
+
this.current = this.start;
|
|
2340
|
+
return this;
|
|
2341
|
+
}
|
|
2342
|
+
get isEmpty() {
|
|
2343
|
+
return this.parts.length === 0;
|
|
2344
|
+
}
|
|
2345
|
+
/** The SVG path data. */
|
|
2346
|
+
svg() {
|
|
2347
|
+
return this.parts.join("");
|
|
2348
|
+
}
|
|
2349
|
+
toString() {
|
|
2350
|
+
return this.svg();
|
|
1846
2351
|
}
|
|
1847
|
-
return { size, spacing: spec.spacing ?? null, alignment: spec.alignment ?? null };
|
|
1848
|
-
}
|
|
1849
|
-
GridItem.flexible = (options = {}) => GridItem({ size: { flexible: options }, spacing: options.spacing, alignment: options.alignment });
|
|
1850
|
-
GridItem.fixed = (value, options = {}) => GridItem({ size: { fixed: value }, spacing: options.spacing, alignment: options.alignment });
|
|
1851
|
-
GridItem.adaptive = (options) => GridItem({ size: { adaptive: options }, spacing: options.spacing, alignment: options.alignment });
|
|
1852
|
-
function LazyVGrid(props) {
|
|
1853
|
-
const { own, modifiers } = splitProps(props);
|
|
1854
|
-
return applyModifiers(
|
|
1855
|
-
sb("lazyvgrid", { columns: own.columns, spacing: own.spacing ?? null, alignment: own.alignment ?? "center" }, void 0, own.children),
|
|
1856
|
-
modifiers
|
|
1857
|
-
);
|
|
1858
|
-
}
|
|
1859
|
-
function Grid(props) {
|
|
1860
|
-
const { own, modifiers } = splitProps(props);
|
|
1861
|
-
return applyModifiers(
|
|
1862
|
-
sb(
|
|
1863
|
-
"grid",
|
|
1864
|
-
{ horizontalSpacing: own.horizontalSpacing ?? null, verticalSpacing: own.verticalSpacing ?? null, alignment: own.alignment ?? "center" },
|
|
1865
|
-
void 0,
|
|
1866
|
-
own.children
|
|
1867
|
-
),
|
|
1868
|
-
modifiers
|
|
1869
|
-
);
|
|
1870
|
-
}
|
|
1871
|
-
function GridRow(props) {
|
|
1872
|
-
const { own, modifiers } = splitProps(props);
|
|
1873
|
-
return applyModifiers(sb("gridrow", { alignment: own.alignment ?? null }, void 0, own.children), modifiers);
|
|
1874
2352
|
}
|
|
1875
2353
|
function runStyleOf(props, inherited, nested) {
|
|
1876
2354
|
const style = { ...inherited };
|
|
@@ -2357,7 +2835,10 @@ function List(props) {
|
|
|
2357
2835
|
useReportSplitSelection(split, selected, clearSelection);
|
|
2358
2836
|
const refresh = useRefreshable(takeModifier(modifiers, "refreshable"));
|
|
2359
2837
|
Object.assign(listProps, refresh.props);
|
|
2360
|
-
const
|
|
2838
|
+
const ownSettings = takeScrollSettings(modifiers);
|
|
2839
|
+
const edgeEffect = edgeEffectProp(useScrollSettings(ownSettings));
|
|
2840
|
+
if (edgeEffect) listProps["edgeEffect"] = edgeEffect;
|
|
2841
|
+
const element = /* @__PURE__ */ jsx(LazyContext.Provider, { value: "vertical", children: sb("list", listProps, refresh.handlers, providingScrollSettings(ownSettings, wrapRows(own.children))) });
|
|
2361
2842
|
return applyModifiers(
|
|
2362
2843
|
selection ? /* @__PURE__ */ jsx(ListSelectionContext.Provider, { value: selection, children: element }) : element,
|
|
2363
2844
|
modifiers
|
|
@@ -2543,11 +3024,11 @@ function Host(props) {
|
|
|
2543
3024
|
if (typeof document === "undefined") return null;
|
|
2544
3025
|
const element = document.createElement("div");
|
|
2545
3026
|
element.className = "sb-host-content";
|
|
2546
|
-
registerHostContent(key, element);
|
|
2547
3027
|
return element;
|
|
2548
3028
|
});
|
|
2549
3029
|
const bridge = useContextBridge(own.contexts);
|
|
2550
3030
|
const root = useRef(null);
|
|
3031
|
+
const mounted = useRef(false);
|
|
2551
3032
|
const sizing = own.sizing ?? "content";
|
|
2552
3033
|
const style = sizing === "fill" ? { height: "100%", ...own.style } : own.style;
|
|
2553
3034
|
const tree = bridge(
|
|
@@ -2555,6 +3036,8 @@ function Host(props) {
|
|
|
2555
3036
|
);
|
|
2556
3037
|
useLayoutEffect(() => {
|
|
2557
3038
|
if (!content) return;
|
|
3039
|
+
mounted.current = true;
|
|
3040
|
+
registerHostContent(key, content);
|
|
2558
3041
|
root.current ??= createRoot(content);
|
|
2559
3042
|
const current = root.current;
|
|
2560
3043
|
queueMicrotask(() => {
|
|
@@ -2565,168 +3048,19 @@ function Host(props) {
|
|
|
2565
3048
|
});
|
|
2566
3049
|
useEffect(
|
|
2567
3050
|
() => () => {
|
|
2568
|
-
|
|
2569
|
-
root.current = null;
|
|
3051
|
+
mounted.current = false;
|
|
2570
3052
|
unregisterHostContent(key);
|
|
2571
|
-
queueMicrotask(() =>
|
|
3053
|
+
queueMicrotask(() => {
|
|
3054
|
+
if (mounted.current) return;
|
|
3055
|
+
const current = root.current;
|
|
3056
|
+
root.current = null;
|
|
3057
|
+
current?.unmount();
|
|
3058
|
+
});
|
|
2572
3059
|
},
|
|
2573
3060
|
[key]
|
|
2574
3061
|
);
|
|
2575
3062
|
return applyModifiers(sb("host", { content: key, sizing }), modifiers);
|
|
2576
3063
|
}
|
|
2577
|
-
const NO_INSETS = { top: 0, leading: 0, bottom: 0, trailing: 0 };
|
|
2578
|
-
function GeometryReader(props) {
|
|
2579
|
-
const { own, modifiers } = splitProps(props);
|
|
2580
|
-
const [reported, setReported] = useState({ size: { width: 0, height: 0 }, origin: null, safeArea: NO_INSETS });
|
|
2581
|
-
const [needsFrame, setNeedsFrame] = useState(false);
|
|
2582
|
-
const spaces = useCoordinateSpaces();
|
|
2583
|
-
let readFrame = false;
|
|
2584
|
-
const proxy = {
|
|
2585
|
-
size: reported.size,
|
|
2586
|
-
frame: (space = "local") => {
|
|
2587
|
-
if (space === "local") return { x: 0, y: 0, ...reported.size };
|
|
2588
|
-
readFrame = true;
|
|
2589
|
-
const origin = reported.origin ?? { x: 0, y: 0 };
|
|
2590
|
-
if (space === "global") return { ...origin, ...reported.size };
|
|
2591
|
-
const named = spaces[space.named];
|
|
2592
|
-
return { x: origin.x - (named?.x ?? 0), y: origin.y - (named?.y ?? 0), ...reported.size };
|
|
2593
|
-
},
|
|
2594
|
-
get safeAreaInsets() {
|
|
2595
|
-
readFrame = true;
|
|
2596
|
-
return reported.safeArea;
|
|
2597
|
-
}
|
|
2598
|
-
};
|
|
2599
|
-
const content = own.children(proxy);
|
|
2600
|
-
useEffect(() => {
|
|
2601
|
-
if (readFrame && !needsFrame) setNeedsFrame(true);
|
|
2602
|
-
});
|
|
2603
|
-
return applyModifiers(
|
|
2604
|
-
sb(
|
|
2605
|
-
"geometry",
|
|
2606
|
-
needsFrame ? { reportsFrame: true } : {},
|
|
2607
|
-
{
|
|
2608
|
-
geometry: (event) => {
|
|
2609
|
-
const next = {
|
|
2610
|
-
size: { width: event.width, height: event.height },
|
|
2611
|
-
origin: event.x !== void 0 && event.y !== void 0 ? { x: event.x, y: event.y } : reported.origin,
|
|
2612
|
-
safeArea: event.safeArea ?? reported.safeArea
|
|
2613
|
-
};
|
|
2614
|
-
if (JSON.stringify(next) !== JSON.stringify(reported)) setReported(next);
|
|
2615
|
-
}
|
|
2616
|
-
},
|
|
2617
|
-
content
|
|
2618
|
-
),
|
|
2619
|
-
modifiers
|
|
2620
|
-
);
|
|
2621
|
-
}
|
|
2622
|
-
const DEFAULT_VIEW_SPACING = { distance: () => 8 };
|
|
2623
|
-
function subviewTraits(children) {
|
|
2624
|
-
return flattenChildren(children).map((element) => {
|
|
2625
|
-
const props = element.props;
|
|
2626
|
-
return { priority: props.layoutPriority ?? 0, values: props.layoutValue ?? {} };
|
|
2627
|
-
});
|
|
2628
|
-
}
|
|
2629
|
-
const fromDimension = (value) => value === "infinity" ? Infinity : value;
|
|
2630
|
-
const toDimension = (value) => Number.isFinite(value) ? Math.round(value * 100) / 100 : "infinity";
|
|
2631
|
-
const toSize = (size) => ({
|
|
2632
|
-
width: fromDimension(size.width) ?? 0,
|
|
2633
|
-
height: fromDimension(size.height) ?? 0
|
|
2634
|
-
});
|
|
2635
|
-
const GUIDES = ["leading", "horizontalCenter", "trailing", "top", "verticalCenter", "bottom", "firstTextBaseline", "lastTextBaseline"];
|
|
2636
|
-
function clamp(value, min, max) {
|
|
2637
|
-
return Math.min(Math.max(value, min), max);
|
|
2638
|
-
}
|
|
2639
|
-
function answerLayout(layout, record, traits = []) {
|
|
2640
|
-
const frames = record.children.map(() => null);
|
|
2641
|
-
const subviews = record.children.map((measurement, index) => {
|
|
2642
|
-
const min = toSize(measurement.min);
|
|
2643
|
-
const ideal = toSize(measurement.ideal);
|
|
2644
|
-
const max = toSize(measurement.max);
|
|
2645
|
-
const sizeThatFits = (proposal) => ({
|
|
2646
|
-
width: proposal.width === null ? ideal.width : clamp(proposal.width, min.width, max.width),
|
|
2647
|
-
height: proposal.height === null ? ideal.height : clamp(proposal.height, min.height, max.height)
|
|
2648
|
-
});
|
|
2649
|
-
return {
|
|
2650
|
-
min,
|
|
2651
|
-
ideal,
|
|
2652
|
-
max,
|
|
2653
|
-
priority: traits[index]?.priority ?? 0,
|
|
2654
|
-
values: traits[index]?.values ?? {},
|
|
2655
|
-
spacing: DEFAULT_VIEW_SPACING,
|
|
2656
|
-
sizeThatFits,
|
|
2657
|
-
place: ({ x, y, anchor, proposal }) => {
|
|
2658
|
-
const size2 = sizeThatFits(proposal ?? { width: null, height: null });
|
|
2659
|
-
const point = unitPoint(anchor ?? "topLeading");
|
|
2660
|
-
frames[index] = { x: x - point.x * size2.width, y: y - point.y * size2.height, ...size2 };
|
|
2661
|
-
}
|
|
2662
|
-
};
|
|
2663
|
-
});
|
|
2664
|
-
const cache = layout.makeCache ? layout.makeCache(subviews) : void 0;
|
|
2665
|
-
const measure = (proposal) => layout.sizeThatFits(proposal, subviews, cache);
|
|
2666
|
-
const size = measure(record.proposal);
|
|
2667
|
-
layout.placeSubviews({ x: 0, y: 0, ...size }, record.proposal, subviews, cache);
|
|
2668
|
-
const placed = frames.map((frame2, index) => {
|
|
2669
|
-
if (frame2) return frame2;
|
|
2670
|
-
const own = subviews[index].sizeThatFits({ width: size.width, height: size.height });
|
|
2671
|
-
return { x: (size.width - own.width) / 2, y: (size.height - own.height) / 2, ...own };
|
|
2672
|
-
});
|
|
2673
|
-
const guides = {};
|
|
2674
|
-
if (layout.explicitAlignment) {
|
|
2675
|
-
const bounds = { x: 0, y: 0, ...size };
|
|
2676
|
-
for (const guide of GUIDES) {
|
|
2677
|
-
const value = layout.explicitAlignment(guide, bounds, record.proposal, subviews, cache);
|
|
2678
|
-
if (value !== null && value !== void 0 && Number.isFinite(value)) guides[guide] = value;
|
|
2679
|
-
}
|
|
2680
|
-
}
|
|
2681
|
-
return {
|
|
2682
|
-
size,
|
|
2683
|
-
frames: placed,
|
|
2684
|
-
guides,
|
|
2685
|
-
sizes: {
|
|
2686
|
-
min: measure({ width: 0, height: 0 }),
|
|
2687
|
-
ideal: measure({ width: null, height: null }),
|
|
2688
|
-
max: measure({ width: Infinity, height: Infinity })
|
|
2689
|
-
}
|
|
2690
|
-
};
|
|
2691
|
-
}
|
|
2692
|
-
function Layout(props) {
|
|
2693
|
-
const { own, modifiers } = splitProps(props);
|
|
2694
|
-
const [record, setRecord] = useState(null);
|
|
2695
|
-
let layoutProps = { proposal: null, size: null, frames: null };
|
|
2696
|
-
const guideModifiers = [];
|
|
2697
|
-
if (record) {
|
|
2698
|
-
const answer = answerLayout(own.layout, record, subviewTraits(own.children));
|
|
2699
|
-
for (const [guide, value] of Object.entries(answer.guides)) guideModifiers.push(["alignmentGuide", { guide, value: () => value }]);
|
|
2700
|
-
const encode = (size) => ({ width: toDimension(size.width), height: toDimension(size.height) });
|
|
2701
|
-
const round = (value) => Math.round(value * 100) / 100;
|
|
2702
|
-
layoutProps = {
|
|
2703
|
-
proposal: {
|
|
2704
|
-
width: record.proposal.width === null ? null : toDimension(record.proposal.width),
|
|
2705
|
-
height: record.proposal.height === null ? null : toDimension(record.proposal.height)
|
|
2706
|
-
},
|
|
2707
|
-
size: { width: round(answer.size.width), height: round(answer.size.height) },
|
|
2708
|
-
frames: answer.frames.map((frame2) => ({ x: round(frame2.x), y: round(frame2.y), width: round(frame2.width), height: round(frame2.height) })),
|
|
2709
|
-
sizes: { min: encode(answer.sizes.min), ideal: encode(answer.sizes.ideal), max: encode(answer.sizes.max) }
|
|
2710
|
-
};
|
|
2711
|
-
}
|
|
2712
|
-
return applyModifiers(
|
|
2713
|
-
sb(
|
|
2714
|
-
"layout",
|
|
2715
|
-
layoutProps,
|
|
2716
|
-
{
|
|
2717
|
-
layout: (event) => {
|
|
2718
|
-
const proposal = event.proposal;
|
|
2719
|
-
setRecord({
|
|
2720
|
-
proposal: { width: fromDimension(proposal.width), height: fromDimension(proposal.height) },
|
|
2721
|
-
children: event.children
|
|
2722
|
-
});
|
|
2723
|
-
}
|
|
2724
|
-
},
|
|
2725
|
-
own.children
|
|
2726
|
-
),
|
|
2727
|
-
[...guideModifiers, ...modifiers]
|
|
2728
|
-
);
|
|
2729
|
-
}
|
|
2730
3064
|
function Menu(props) {
|
|
2731
3065
|
const { own, modifiers } = splitProps(props);
|
|
2732
3066
|
const label = own.title !== void 0 ? /* @__PURE__ */ jsx(Text, { children: own.title }) : own.label;
|
|
@@ -3006,9 +3340,9 @@ function Chart(props) {
|
|
|
3006
3340
|
}
|
|
3007
3341
|
const xScale = scaleFor(xValues, { domain: own.xScale?.domain });
|
|
3008
3342
|
const yScale = scaleFor(yValues, { includesZero: own.yScale?.includesZero ?? true, domain: own.yScale?.domain });
|
|
3009
|
-
const
|
|
3010
|
-
const ux = (v) =>
|
|
3011
|
-
const uy = (v) =>
|
|
3343
|
+
const round2 = (n) => Math.round(n * 1e6) / 1e6;
|
|
3344
|
+
const ux = (v) => round2(xScale.unit(v));
|
|
3345
|
+
const uy = (v) => round2(1 - yScale.unit(v));
|
|
3012
3346
|
let continuousBand = 1;
|
|
3013
3347
|
if (xScale.kind !== "band") {
|
|
3014
3348
|
const centers = [...new Set(marks.filter((m) => m.kind === "bar").map((m) => ux(m.props.x)))].sort((a, b) => a - b);
|
|
@@ -3054,15 +3388,15 @@ function Chart(props) {
|
|
|
3054
3388
|
case "bar": {
|
|
3055
3389
|
const style = common(mark);
|
|
3056
3390
|
const [b0, b1] = xScale.kind === "band" ? xScale.band(p.x) : [ux(p.x) - continuousBand / 2, ux(p.x) + continuousBand / 2];
|
|
3057
|
-
const center =
|
|
3058
|
-
const half =
|
|
3391
|
+
const center = round2((b0 + b1) / 2);
|
|
3392
|
+
const half = round2((b1 - b0) * 0.8 / 2);
|
|
3059
3393
|
const top = uy(Math.max(asNumber(p.y), p.yStart ?? 0));
|
|
3060
3394
|
const bottom = uy(Math.min(asNumber(p.y), p.yStart ?? 0));
|
|
3061
3395
|
const rect = {
|
|
3062
3396
|
kind: "rect",
|
|
3063
3397
|
...style,
|
|
3064
|
-
x0: p.width !== void 0 ? center :
|
|
3065
|
-
x1: p.width !== void 0 ? center :
|
|
3398
|
+
x0: p.width !== void 0 ? center : round2(center - half),
|
|
3399
|
+
x1: p.width !== void 0 ? center : round2(center + half),
|
|
3066
3400
|
y0: top,
|
|
3067
3401
|
y1: bottom,
|
|
3068
3402
|
cornerRadius: p.cornerRadius ?? 0,
|
|
@@ -3133,7 +3467,7 @@ function Chart(props) {
|
|
|
3133
3467
|
}
|
|
3134
3468
|
}
|
|
3135
3469
|
const axis = (scale, position, flipY) => {
|
|
3136
|
-
const flip = (u) =>
|
|
3470
|
+
const flip = (u) => round2(flipY ? 1 - u : u);
|
|
3137
3471
|
return {
|
|
3138
3472
|
position,
|
|
3139
3473
|
gridLines: scale.gridLines.map(flip),
|
|
@@ -3948,6 +4282,7 @@ export {
|
|
|
3948
4282
|
Label,
|
|
3949
4283
|
LabeledContent,
|
|
3950
4284
|
Layout,
|
|
4285
|
+
LazyHGrid,
|
|
3951
4286
|
LazyHStack,
|
|
3952
4287
|
LazyVGrid,
|
|
3953
4288
|
LazyVStack,
|
|
@@ -3956,6 +4291,7 @@ export {
|
|
|
3956
4291
|
Link,
|
|
3957
4292
|
List,
|
|
3958
4293
|
Menu,
|
|
4294
|
+
NO_GEOMETRY,
|
|
3959
4295
|
NavigationLink,
|
|
3960
4296
|
NavigationSplitView,
|
|
3961
4297
|
NavigationStack,
|
|
@@ -3994,6 +4330,7 @@ export {
|
|
|
3994
4330
|
VStack,
|
|
3995
4331
|
VideoPlayer,
|
|
3996
4332
|
ViewThatFits,
|
|
4333
|
+
VisualEffect,
|
|
3997
4334
|
ZStack,
|
|
3998
4335
|
answerLayout,
|
|
3999
4336
|
color,
|
|
@@ -4001,22 +4338,26 @@ export {
|
|
|
4001
4338
|
flattenChildren,
|
|
4002
4339
|
font,
|
|
4003
4340
|
frame,
|
|
4341
|
+
geometryProxy,
|
|
4004
4342
|
gradient,
|
|
4005
4343
|
hex,
|
|
4006
4344
|
insets,
|
|
4007
4345
|
keyframeValues,
|
|
4008
4346
|
mount,
|
|
4009
4347
|
moveItems,
|
|
4348
|
+
nextGeometry,
|
|
4010
4349
|
niceStep,
|
|
4011
4350
|
opacity,
|
|
4012
4351
|
openURL,
|
|
4013
4352
|
padding,
|
|
4014
4353
|
placeholder,
|
|
4015
4354
|
plainText,
|
|
4355
|
+
providingScrollSettings,
|
|
4016
4356
|
readBinding,
|
|
4017
4357
|
rgb,
|
|
4018
4358
|
shapeStyle,
|
|
4019
4359
|
system,
|
|
4360
|
+
takeScrollSettings,
|
|
4020
4361
|
timeTicks,
|
|
4021
4362
|
unitPoint,
|
|
4022
4363
|
useAVPlayer,
|