@swiftbrowser/react 0.5.2 → 0.5.4
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 +8 -0
- package/dist/index.js +89 -6
- package/dist/index.js.map +1 -1
- package/dist/island.d.ts +17 -1
- package/dist/island.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -103,6 +103,14 @@ a React root of its own: the page's React state reaches it through props as
|
|
|
103
103
|
usual, and its contexts through `contexts={[…]}` (see
|
|
104
104
|
[Contexts across roots](#contexts-across-roots)).
|
|
105
105
|
|
|
106
|
+
There is no status bar in a page, so `safeArea` stands in for one. A
|
|
107
|
+
`fill` island keeps 10 points at the top, the way SwiftUI keeps a window's
|
|
108
|
+
bars off its edge. Navigation bars sit below that inset and their
|
|
109
|
+
background reaches up into it, and lists start below it. A `content`
|
|
110
|
+
island has no insets. Pass a number for the top inset (`safeArea={0}` puts
|
|
111
|
+
the bars flush with the edge) or an object such as
|
|
112
|
+
`safeArea={{ top: 24, bottom: 34 }}`.
|
|
113
|
+
|
|
106
114
|
### Try the demos
|
|
107
115
|
|
|
108
116
|
```sh
|
package/dist/index.js
CHANGED
|
@@ -483,7 +483,11 @@ function useContextBridge(contexts = [], options = {}) {
|
|
|
483
483
|
const values = all.map((context) => useContext(context));
|
|
484
484
|
return (children) => all.reduceRight((inner, context, index) => createElement(context.Provider, { value: values[index] }, inner), children);
|
|
485
485
|
}
|
|
486
|
-
const
|
|
486
|
+
const WINDOW_TOP_INSET = 10;
|
|
487
|
+
function insetsOf(safeArea, fit) {
|
|
488
|
+
const given = typeof safeArea === "number" ? { top: safeArea } : safeArea ?? { top: fit === "fill" ? WINDOW_TOP_INSET : 0 };
|
|
489
|
+
return { top: given.top ?? 0, leading: given.leading ?? 0, bottom: given.bottom ?? 0, trailing: given.trailing ?? 0 };
|
|
490
|
+
}
|
|
487
491
|
function SwiftUIView({
|
|
488
492
|
children,
|
|
489
493
|
fit = "fill",
|
|
@@ -491,6 +495,7 @@ function SwiftUIView({
|
|
|
491
495
|
dynamicTypeSize = "large",
|
|
492
496
|
contexts,
|
|
493
497
|
assets,
|
|
498
|
+
safeArea,
|
|
494
499
|
className,
|
|
495
500
|
style
|
|
496
501
|
}) {
|
|
@@ -506,7 +511,7 @@ function SwiftUIView({
|
|
|
506
511
|
const instance = mount(screen.current, latest.current, {
|
|
507
512
|
colorScheme,
|
|
508
513
|
dynamicTypeSize,
|
|
509
|
-
safeArea:
|
|
514
|
+
safeArea: insetsOf(safeArea, fit),
|
|
510
515
|
contentHeight: fit === "content",
|
|
511
516
|
...assets ? { assets } : {}
|
|
512
517
|
});
|
|
@@ -519,6 +524,11 @@ function SwiftUIView({
|
|
|
519
524
|
useLayoutEffect(() => {
|
|
520
525
|
mounted.current?.root.render(tree);
|
|
521
526
|
});
|
|
527
|
+
const insets2 = insetsOf(safeArea, fit);
|
|
528
|
+
const insetsKey = `${insets2.top},${insets2.leading},${insets2.bottom},${insets2.trailing}`;
|
|
529
|
+
useLayoutEffect(() => {
|
|
530
|
+
mounted.current?.renderer.setSafeArea(insets2);
|
|
531
|
+
}, [insetsKey]);
|
|
522
532
|
useLayoutEffect(() => {
|
|
523
533
|
if (device.current) applyTypeSizeVariables(device.current, dynamicTypeSize);
|
|
524
534
|
mounted.current?.setEnvironment({ colorScheme, dynamicTypeSize });
|
|
@@ -1759,18 +1769,91 @@ function Searchable({ text, onChange, prompt }) {
|
|
|
1759
1769
|
function applyModifiers(element, modifiers) {
|
|
1760
1770
|
const sides = [];
|
|
1761
1771
|
const node = wrap(element, modifiers, sides);
|
|
1762
|
-
if (sides.length === 0) return node;
|
|
1763
1772
|
return createElement(Fragment, null, node, ...sides);
|
|
1764
1773
|
}
|
|
1765
1774
|
function wrap(element, modifiers, sides) {
|
|
1766
1775
|
let node = element;
|
|
1767
1776
|
for (const [key, value] of modifiers) {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
node =
|
|
1777
|
+
const inactive = value === void 0 || value === null && key !== "lineLimit" && key !== "badge";
|
|
1778
|
+
const next = inactive ? node : apply(key, value, node, sides);
|
|
1779
|
+
node = next === node ? neutral(key, node) : next;
|
|
1771
1780
|
}
|
|
1772
1781
|
return node;
|
|
1773
1782
|
}
|
|
1783
|
+
const STYLED_KEYS = /* @__PURE__ */ new Set([
|
|
1784
|
+
"padding",
|
|
1785
|
+
"font",
|
|
1786
|
+
"fontWeight",
|
|
1787
|
+
"bold",
|
|
1788
|
+
"foregroundStyle",
|
|
1789
|
+
"background",
|
|
1790
|
+
"frame",
|
|
1791
|
+
"cornerRadius",
|
|
1792
|
+
"clipShape",
|
|
1793
|
+
"clipped",
|
|
1794
|
+
"opacity",
|
|
1795
|
+
"disabled",
|
|
1796
|
+
"hidden",
|
|
1797
|
+
"layoutPriority",
|
|
1798
|
+
"lineLimit",
|
|
1799
|
+
"multilineTextAlignment",
|
|
1800
|
+
"fixedSize",
|
|
1801
|
+
"offset",
|
|
1802
|
+
"rotationEffect",
|
|
1803
|
+
"scaleEffect",
|
|
1804
|
+
"shadow",
|
|
1805
|
+
"tint",
|
|
1806
|
+
"badge",
|
|
1807
|
+
"listRowInsets",
|
|
1808
|
+
"imageScale",
|
|
1809
|
+
"transition",
|
|
1810
|
+
"gridColumnAlignment",
|
|
1811
|
+
"gridCellColumns",
|
|
1812
|
+
"aspectRatio",
|
|
1813
|
+
"scaledToFit",
|
|
1814
|
+
"scaledToFill",
|
|
1815
|
+
"blur",
|
|
1816
|
+
"brightness",
|
|
1817
|
+
"contrast",
|
|
1818
|
+
"saturation",
|
|
1819
|
+
"grayscale",
|
|
1820
|
+
"hueRotation",
|
|
1821
|
+
"colorInvert",
|
|
1822
|
+
"colorMultiply",
|
|
1823
|
+
"blendMode",
|
|
1824
|
+
"mask",
|
|
1825
|
+
"position",
|
|
1826
|
+
"zIndex",
|
|
1827
|
+
"allowsHitTesting",
|
|
1828
|
+
"ignoresSafeArea",
|
|
1829
|
+
"rotation3DEffect",
|
|
1830
|
+
"gridCellAnchor",
|
|
1831
|
+
"alignmentGuide",
|
|
1832
|
+
"help",
|
|
1833
|
+
"pointerStyle",
|
|
1834
|
+
"matchedGeometryEffect",
|
|
1835
|
+
"containerRelativeFrame",
|
|
1836
|
+
"contentTransition"
|
|
1837
|
+
]);
|
|
1838
|
+
const ENVIRONMENT_KEYS = /* @__PURE__ */ new Set([
|
|
1839
|
+
"buttonStyle",
|
|
1840
|
+
"controlSize",
|
|
1841
|
+
"pickerStyle",
|
|
1842
|
+
"labelsHidden",
|
|
1843
|
+
"refreshable",
|
|
1844
|
+
"submitLabel",
|
|
1845
|
+
"labelStyle",
|
|
1846
|
+
"redacted",
|
|
1847
|
+
"textCase"
|
|
1848
|
+
]);
|
|
1849
|
+
const SCROLL_KEYS = /* @__PURE__ */ new Set(["scrollEdgeEffectStyle", "scrollEdgeEffectHidden", "contentMargins"]);
|
|
1850
|
+
function neutral(key, node) {
|
|
1851
|
+
if (key === "overlay") return decorated("overlay", "center", node, null);
|
|
1852
|
+
if (STYLED_KEYS.has(key)) return styled({}, node);
|
|
1853
|
+
if (ENVIRONMENT_KEYS.has(key)) return withEnvironment({}, node);
|
|
1854
|
+
if (SCROLL_KEYS.has(key)) return withScrollSettings({}, node);
|
|
1855
|
+
return node;
|
|
1856
|
+
}
|
|
1774
1857
|
function apply(key, value, node, sides) {
|
|
1775
1858
|
switch (key) {
|
|
1776
1859
|
case "padding":
|