@swiftbrowser/react 0.28.5 → 0.28.7

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 CHANGED
@@ -332,7 +332,9 @@ own would add a second entry for the same screen). When the app pops on its
332
332
  own (the bar's back button), the renderer's step back is asynchronous and
333
333
  the app's `replaceState` for what it shows now runs before it lands; the
334
334
  renderer sets that URL again on the entry it arrives at, so the address bar
335
- follows either back button.
335
+ follows either back button. A reload keeps the entry it was on, and its URL,
336
+ while the app restores the screens it shows (ten seconds at most), rather
337
+ than stepping back to an older entry at the first commit.
336
338
  On a phone, a `fill` island follows the on-screen keyboard (`keyboard`,
337
339
  on by default for `fill`, or `mount(..., { keyboard: true })`): its height
338
340
  becomes a bottom inset, so a field, a bottom search field or a chat's
@@ -1198,7 +1200,11 @@ iPadOS's Settings and Files drill their sidebars. A back past the child's
1198
1200
  root shows the host's sidebar again, and the child's comes back when
1199
1201
  `options.shown` goes true anew or `options.generation` changes (the app
1200
1202
  chosen again); a back out of a screen the child pushed in its sidebar pops
1201
- the child's sidebar stack. In a compact width the child's split view is a
1203
+ the child's sidebar stack. `options.rootBackButtonHidden` leaves the child's
1204
+ sidebar root without a back button (`navigationBarBackButtonHidden`), for a
1205
+ host that offers its way out in the detail instead, so the two columns
1206
+ never each show a back; the hook answers whether the child's sidebar shows
1207
+ on the host's now, for the host to show that way out while it does. In a compact width the child's split view is a
1202
1208
  stack rooted at its sidebar, mapped as any stack, and the hook keeps nothing
1203
1209
  on the host's path. The host's sidebar `NavigationStack` is the split
1204
1210
  view's column stack when it is the `sidebar` prop itself:
@@ -63,6 +63,13 @@ export interface RemoteSidebarOptions {
63
63
  generation?: unknown;
64
64
  /** As `RemoteTree`'s `elements`: the host's views for the child's own element kinds. */
65
65
  elements?: Readonly<Record<string, HostElementRenderer>>;
66
+ /**
67
+ * The child's sidebar root without a back button: the host offers the way
68
+ * out elsewhere (a back in its detail that leaves the app), so the two
69
+ * columns never show a back each. Screens the child pushes in its sidebar
70
+ * keep theirs.
71
+ */
72
+ rootBackButtonHidden?: boolean;
66
73
  }
67
74
  /**
68
75
  * The child's sidebar, pushed on the host's own sidebar stack: the screens
@@ -76,8 +83,9 @@ export interface RemoteSidebarOptions {
76
83
  * its sidebar pops the child's sidebar stack, as a pop in the host's stack
77
84
  * pops the child's. Nothing while the child has no split view (a compact
78
85
  * width, where its sidebar is the root screen of the stack `RemoteTree`
79
- * maps), or while `root` is null.
86
+ * maps), or while `root` is null. Answers whether the child's sidebar is
87
+ * wanted on the host's sidebar now, so the host can offer its way out.
80
88
  */
81
- export declare function useRemoteSidebar(root: RemoteRoot | null, path: readonly unknown[], setPath: (path: readonly unknown[]) => void, options?: RemoteSidebarOptions): void;
89
+ export declare function useRemoteSidebar(root: RemoteRoot | null, path: readonly unknown[], setPath: (path: readonly unknown[]) => void, options?: RemoteSidebarOptions): boolean;
82
90
  export declare function RemoteTree({ root, initialPath, elements }: RemoteTreeProps): ReactNode;
83
91
  //# sourceMappingURL=remoteTree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remoteTree.d.ts","sourceRoot":"","sources":["../../src/components/remoteTree.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAsF,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3H,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAM7D,gIAAgI;AAChI,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,KAAK,SAAS,CAAC;AAE/G,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;IACzD;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAClC;AAwFD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA0BD,MAAM,WAAW,oBAAoB;IACnC,wHAAwH;IACxH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oHAAoH;IACpH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,EAAE,OAAO,GAAE,oBAAyB,GAAG,IAAI,CAqCzK;AAqBD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,SAAS,CA+DtF"}
1
+ {"version":3,"file":"remoteTree.d.ts","sourceRoot":"","sources":["../../src/components/remoteTree.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAsF,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3H,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAM7D,gIAAgI;AAChI,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,KAAK,SAAS,CAAC;AAE/G,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;IACzD;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CAClC;AA0FD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA2BD,MAAM,WAAW,oBAAoB;IACnC,wHAAwH;IACxH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oHAAoH;IACpH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;IACzD;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAwC5K;AAqBD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,SAAS,CA+DtF"}
package/dist/index.js CHANGED
@@ -977,7 +977,7 @@ function RegisterDestination({ destination }) {
977
977
  navigation?.registerDestination(destination);
978
978
  return null;
979
979
  }
980
- const SCREEN_PROPS = ["title", "subtitle", "displayMode", "toolbarRole", "navigationBarHidden", "bottomBarHidden", "statusBarHidden"];
980
+ const SCREEN_PROPS = ["title", "subtitle", "displayMode", "toolbarRole", "navigationBarHidden", "bottomBarHidden", "statusBarHidden", "backButtonHidden"];
981
981
  function screenPrefs(props, key) {
982
982
  const picked = {};
983
983
  for (const name of SCREEN_PROPS) if (name in props) picked[name] = props[name];
@@ -1023,8 +1023,9 @@ function renderSheet(root, node, stack, inherited, elements) {
1023
1023
  const children = node.children.map((child) => renderNode(root, child, stack, elements));
1024
1024
  return createElement(Fragment, { key: node.id }, sb(node.kind, node.props, root.handlersFor(node.id), replayStyles(inherited, children)));
1025
1025
  }
1026
- function renderScreen(root, screen, stack, elements) {
1026
+ function renderScreen(root, screen, stack, elements, hostPrefs) {
1027
1027
  const out = [screenPrefs(screen.props, "$screen")];
1028
+ if (hostPrefs) out.push(createElement(Fragment, { key: "$host" }, sb(PREF_KIND, hostPrefs, void 0, void 0, "navscreen")));
1028
1029
  for (const child of screen.children) {
1029
1030
  const drawn = renderNode(root, child, stack, elements);
1030
1031
  if (child.kind === "toolbar" || child.kind === "searchfield") out.push(createElement(Fragment, { key: child.id }, sb(HOIST_KIND, void 0, void 0, drawn, "navscreen")));
@@ -1032,21 +1033,22 @@ function renderScreen(root, screen, stack, elements) {
1032
1033
  }
1033
1034
  return createElement(Fragment, null, ...out);
1034
1035
  }
1035
- function RemoteScreen({ root, id, elements }) {
1036
+ function RemoteScreen({ root, id, elements, hostPrefs }) {
1036
1037
  useSyncExternalStore(root.subscribe, root.getVersion, root.getVersion);
1037
1038
  const screen = root.node(id);
1038
1039
  if (!screen?.parent) return null;
1039
- return renderScreen(root, screen, findStack(root.root), elements);
1040
+ return renderScreen(root, screen, findStack(root.root), elements, hostPrefs);
1040
1041
  }
1041
1042
  function useScreenValues(root, elements) {
1042
1043
  const values = useRef(/* @__PURE__ */ new Map());
1043
1044
  const ours = useRef(/* @__PURE__ */ new WeakSet());
1044
1045
  const keyOf2 = (screen) => `${screen.id}:${JSON.stringify(screen.props["route"] ?? null)}`;
1045
- const valueFor = (screen) => {
1046
+ const valueFor = (screen, hostPrefs) => {
1046
1047
  const key = keyOf2(screen);
1047
1048
  let value = values.current.get(key);
1048
1049
  if (!value) {
1049
- value = "route" in screen.props ? { view: /* @__PURE__ */ jsx(RemoteScreen, { root, id: screen.id, elements }), route: screen.props["route"] } : { view: /* @__PURE__ */ jsx(RemoteScreen, { root, id: screen.id, elements }) };
1050
+ const view = /* @__PURE__ */ jsx(RemoteScreen, { root, id: screen.id, elements, ...hostPrefs ? { hostPrefs } : {} });
1051
+ value = "route" in screen.props ? { view, route: screen.props["route"] } : { view };
1050
1052
  values.current.set(key, value);
1051
1053
  ours.current.add(value);
1052
1054
  }
@@ -1072,7 +1074,8 @@ function useRemoteSidebar(root, path, setPath, options = {}) {
1072
1074
  if (last.current.root !== root || !last.current.shown && shown || last.current.generation !== options.generation) dismissed.current = false;
1073
1075
  last.current = { root, shown, generation: options.generation };
1074
1076
  const keys = screens.map(keyOf2);
1075
- const wanted = shown && !dismissed.current ? screens.map(valueFor) : [];
1077
+ const rootPrefs = options.rootBackButtonHidden ? { backButtonHidden: true } : void 0;
1078
+ const wanted = shown && !dismissed.current ? screens.map((screen, i) => valueFor(screen, i === 0 ? rootPrefs : void 0)) : [];
1076
1079
  forget(keys);
1077
1080
  const hosts = path.filter((value) => !isOurs(value));
1078
1081
  const mine = path.filter(isOurs);
@@ -1092,6 +1095,7 @@ function useRemoteSidebar(root, path, setPath, options = {}) {
1092
1095
  lastMine.current = wanted.length;
1093
1096
  setPath([...hosts, ...wanted]);
1094
1097
  });
1098
+ return shown && screens.length > 0 && !dismissed.current;
1095
1099
  }
1096
1100
  const noSubscribe = () => () => {
1097
1101
  };
@@ -1147,7 +1151,7 @@ function RemoteTree({ root, initialPath, elements }) {
1147
1151
  useLayoutEffect(() => {
1148
1152
  if (!navigation) return;
1149
1153
  const keys = pushed.map(keyOf2);
1150
- const wanted = pushed.map(valueFor);
1154
+ const wanted = pushed.map((screen) => valueFor(screen));
1151
1155
  forget(keys);
1152
1156
  const tail = navigation.path.slice(depth);
1153
1157
  let shown = 0;
@@ -2958,6 +2962,7 @@ const MODIFIER_KEYS = /* @__PURE__ */ new Set([
2958
2962
  "toolbarRole",
2959
2963
  "toolbarVisibility",
2960
2964
  "statusBarHidden",
2965
+ "navigationBarBackButtonHidden",
2961
2966
  "toolbar",
2962
2967
  "searchable",
2963
2968
  "navigationDestination",
@@ -3413,6 +3418,9 @@ function apply(key, value, node, sides) {
3413
3418
  case "statusBarHidden":
3414
3419
  sides.push(sb(PREF_KIND, { statusBarHidden: Boolean(value) }, void 0, void 0, "navscreen"));
3415
3420
  return node;
3421
+ case "navigationBarBackButtonHidden":
3422
+ sides.push(sb(PREF_KIND, { backButtonHidden: Boolean(value) }, void 0, void 0, "navscreen"));
3423
+ return node;
3416
3424
  case "toolbar":
3417
3425
  sides.push(sb(HOIST_KIND, void 0, void 0, value, "navscreen"));
3418
3426
  return node;
@@ -3727,9 +3735,12 @@ function decidePlatform(width, media = matchesMedia) {
3727
3735
  function matchesMedia(query) {
3728
3736
  return typeof matchMedia === "function" && matchMedia(query).matches;
3729
3737
  }
3738
+ function pageRoot(root) {
3739
+ return { ...root, render: (element) => root.render(createElement(LazyWindowContext.Provider, { value: true }, element)) };
3740
+ }
3730
3741
  function mount(screen, element, options = {}) {
3731
3742
  let renderer = null;
3732
- const root = createSwiftUIRoot((ops) => renderer?.applyOps(ops));
3743
+ const root = pageRoot(createSwiftUIRoot((ops) => renderer?.applyOps(ops)));
3733
3744
  renderer = new Renderer(screen, (event) => root.dispatch(event));
3734
3745
  renderer.fileDrops = "reference";
3735
3746
  const measurer = (text, font2, width2) => renderer.measureText(text, font2, width2);
@@ -3776,7 +3787,7 @@ function mount(screen, element, options = {}) {
3776
3787
  }) : null;
3777
3788
  observer?.observe(screen);
3778
3789
  const stopScenePhase = typeof document !== "undefined" ? watchScenePhase((scenePhase) => root.setEnvironment({ scenePhase })) : null;
3779
- root.render(createElement(LazyWindowContext.Provider, { value: true }, element));
3790
+ root.render(element);
3780
3791
  const mounted = {
3781
3792
  root,
3782
3793
  renderer,