@protobase/ui 0.44.2 → 0.44.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.
Files changed (33) hide show
  1. package/dist/app/gallery/lightbox.js +4 -4
  2. package/dist/app/index.html +2 -2
  3. package/dist/app/main.js +4 -1
  4. package/dist/app/native-viewport.js +17 -0
  5. package/dist/app-shell/app-shell.js +2 -2
  6. package/dist/app-shell/bottom-bar.js +1 -1
  7. package/dist/app-shell/drawer.js +1 -1
  8. package/dist/app-shell/page-scroll.js +1 -1
  9. package/dist/app-shell/sidebar.js +1 -1
  10. package/dist/app-shell/top-bar.js +2 -2
  11. package/dist/auth/auth-layout.js +1 -1
  12. package/dist/package.js +1 -1
  13. package/dist/primitives/dialog.js +2 -2
  14. package/dist/primitives/sheet.js +2 -2
  15. package/dist/shell/assets/{app-dlNPzXMF.js → app-By06l4Sd.js} +6 -6
  16. package/dist/shell/assets/index-7kqOfiyQ.js +2 -0
  17. package/dist/shell/assets/index-DGJkc-U0.css +2 -0
  18. package/dist/shell/assets/{records-map-DaWm_7pC.js → records-map-CPjNQELa.js} +2 -2
  19. package/dist/shell/assets/{shared-protobase-ui-BeWti4z6.js → shared-protobase-ui-iAXtn7yM.js} +2 -2
  20. package/dist/shell/index.html +6 -6
  21. package/dist/shell/protobase.shell.json +1 -1
  22. package/dist/shell/protobase.sw.js +2 -2
  23. package/dist/shell-source-maps/assets/app-By06l4Sd.js.map +1 -0
  24. package/dist/shell-source-maps/assets/index-7kqOfiyQ.js.map +1 -0
  25. package/dist/shell-source-maps/assets/{records-map-DaWm_7pC.js.map → records-map-CPjNQELa.js.map} +1 -1
  26. package/dist/shell-source-maps/assets/{shared-protobase-ui-BeWti4z6.js.map → shared-protobase-ui-iAXtn7yM.js.map} +1 -1
  27. package/dist/styles.css +10 -0
  28. package/dist/toasts/toast-provider.js +1 -1
  29. package/package.json +4 -4
  30. package/dist/shell/assets/index-CxRZztw-.js +0 -2
  31. package/dist/shell/assets/index-DT92y8N1.css +0 -2
  32. package/dist/shell-source-maps/assets/app-dlNPzXMF.js.map +0 -1
  33. package/dist/shell-source-maps/assets/index-CxRZztw-.js.map +0 -1
@@ -71,12 +71,12 @@ const Lightbox = ({ title, photos, index, onIndex, onClose, details, detailsTitl
71
71
  "aria-modal": "true",
72
72
  "aria-label": title,
73
73
  onKeyDown: key,
74
- className: "fixed inset-0 z-[90] flex flex-col overflow-y-auto overscroll-contain bg-backdrop outline-none md:flex-row",
74
+ className: "fixed inset-0 z-[90] flex flex-col overflow-y-auto overscroll-contain bg-backdrop pl-[var(--pb-safe-left)] pr-[var(--pb-safe-right)] outline-none md:flex-row",
75
75
  children: [
76
76
  /* @__PURE__ */ jsxs("div", {
77
77
  className: "flex h-dvh shrink-0 flex-col md:sticky md:top-0 md:min-w-0 md:flex-1",
78
78
  children: [/* @__PURE__ */ jsxs("div", {
79
- className: "flex shrink-0 items-center justify-between gap-2 p-3",
79
+ className: "flex shrink-0 items-center justify-between gap-2 p-3 pt-[calc(0.75rem+var(--pb-safe-top))]",
80
80
  children: [/* @__PURE__ */ jsx("span", {
81
81
  className: "rounded-full bg-background/85 px-3 py-1 font-medium tabular-nums text-foreground",
82
82
  "aria-live": "polite",
@@ -107,7 +107,7 @@ const Lightbox = ({ title, photos, index, onIndex, onClose, details, detailsTitl
107
107
  })]
108
108
  })]
109
109
  }), /* @__PURE__ */ jsxs("div", {
110
- className: "relative flex min-h-0 flex-1 touch-pan-y items-center justify-center px-3 pb-3 md:px-16",
110
+ className: "relative flex min-h-0 flex-1 touch-pan-y items-center justify-center px-3 pb-[calc(0.75rem+var(--pb-safe-bottom))] md:px-16",
111
111
  onPointerDown: down,
112
112
  onPointerUp: up,
113
113
  onPointerCancel: () => start.current = void 0,
@@ -140,7 +140,7 @@ const Lightbox = ({ title, photos, index, onIndex, onClose, details, detailsTitl
140
140
  hasDetails && detailsOpen && desktop && /* @__PURE__ */ jsxs("aside", {
141
141
  id: sidebarId,
142
142
  "aria-label": detailsTitle,
143
- className: "min-h-dvh w-[360px] shrink-0 border-l border-border bg-background p-5 text-foreground",
143
+ className: "min-h-dvh w-[360px] shrink-0 border-l border-border bg-background p-5 pt-[calc(1.25rem+var(--pb-safe-top))] text-foreground",
144
144
  children: [/* @__PURE__ */ jsx("h2", {
145
145
  className: "mb-3 text-[16px] font-semibold",
146
146
  children: detailsTitle
@@ -18,8 +18,8 @@
18
18
  </script>
19
19
  </head>
20
20
  <body>
21
- <!-- As tall as the screen shows, browser toolbars aside, so a page that fills it, such as a map, keeps the bottom bar in view. The page reaches under the iPhone home indicator, which the bottom bar keeps clear of; the sides keep clear of the notch. -->
22
- <div id="root" class="h-dvh" style="padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right)"></div>
21
+ <!-- As tall as the screen shows, browser toolbars aside, so a page that fills it, such as a map, keeps the bottom bar in view. The page reaches under the status bar and the home indicator, which the shell's bars keep clear of; the sides keep clear of the notch. -->
22
+ <div id="root" class="h-dvh" style="padding-left: var(--pb-safe-left); padding-right: var(--pb-safe-right)"></div>
23
23
  <script type="module" src="./main"></script>
24
24
  </body>
25
25
  </html>
package/dist/app/main.js CHANGED
@@ -2,6 +2,7 @@ import { browserLocale } from "../locale/active-locale.js";
2
2
  import { nativeBridgeOf } from "./native-auth-fetch.js";
3
3
  import { uiFromModule } from "./pages/ui-from-module.js";
4
4
  import { App } from "./app.js";
5
+ import { applyNativeViewport } from "./native-viewport.js";
5
6
  import { pageApiOrigin } from "./page-api-origin.js";
6
7
  import { StrictMode } from "react";
7
8
  import { jsx } from "react/jsx-runtime";
@@ -11,10 +12,12 @@ import "../styles.css";
11
12
  //#region src/app/main.tsx
12
13
  const root = document.getElementById("root");
13
14
  if (!root) throw new Error("index.html needs an element with id \"root\"");
15
+ const nativeBridge = nativeBridgeOf(window);
16
+ if (nativeBridge) applyNativeViewport(document);
14
17
  createRoot(root).render(/* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(App, {
15
18
  baseUrl: `${pageApiOrigin() ?? ""}/api/v1`,
16
19
  ui: uiFromModule(projectUi),
17
20
  locale: browserLocale(),
18
- nativeBridge: nativeBridgeOf(window)
21
+ nativeBridge
19
22
  }) }));
20
23
  //#endregion
@@ -0,0 +1,17 @@
1
+ //#region src/app/native-viewport.ts
2
+ /**
3
+ * The viewport of the iOS and Android app: as the page's, at a scale of one. Safari on iOS zooms into an input whose
4
+ * text is smaller than 16px when it is focused, and in the app the page then stays zoomed with its right side cut off;
5
+ * an app does not zoom, so its viewport stays at that scale, under a pinch too. The page in a browser keeps its zoom.
6
+ */
7
+ const nativeViewport = (content) => {
8
+ return [...content.split(",").map((part) => part.trim()).filter((part) => part && !/^maximum-scale\s*=/.test(part)), "maximum-scale=1"].join(", ");
9
+ };
10
+ /** Gives the document's viewport the app's scale; a document without a viewport tag needs none. */
11
+ const applyNativeViewport = (doc) => {
12
+ const meta = doc.querySelector("meta[name=\"viewport\"]");
13
+ if (!meta) return;
14
+ meta.setAttribute("content", nativeViewport(meta.getAttribute("content") ?? ""));
15
+ };
16
+ //#endregion
17
+ export { applyNativeViewport, nativeViewport };
@@ -59,7 +59,7 @@ const AppShell = ({ sidebarMode, activeItem, breadcrumb, user, workspace, appNam
59
59
  children: sidebar("text-large")
60
60
  }),
61
61
  /* @__PURE__ */ jsxs("div", {
62
- className: "flex min-w-0 flex-1 flex-col",
62
+ className: cn("flex min-w-0 flex-1 flex-col", !tabs && "pb-[var(--pb-safe-bottom)]"),
63
63
  children: [
64
64
  /* @__PURE__ */ jsx(TopBar, {
65
65
  ref: topBarRef,
@@ -92,7 +92,7 @@ const AppShell = ({ sidebarMode, activeItem, breadcrumb, user, workspace, appNam
92
92
  ]
93
93
  }),
94
94
  rightPanel && /* @__PURE__ */ jsx("div", {
95
- className: pageScroll ? "sticky top-0 flex h-dvh shrink-0 self-start" : "flex shrink-0",
95
+ className: pageScroll ? "sticky top-0 flex h-dvh shrink-0 self-start pt-[var(--pb-safe-top)]" : "flex shrink-0",
96
96
  children: rightPanel
97
97
  })
98
98
  ]
@@ -15,7 +15,7 @@ const BottomBar = ({ tabs, onNavigate, onMore, moreOpen, moreControls, sticky, r
15
15
  return /* @__PURE__ */ jsxs("nav", {
16
16
  ref,
17
17
  "aria-label": text("tabs"),
18
- className: cn("flex shrink-0 border-t bg-background pb-[env(safe-area-inset-bottom)] md:hidden", sticky && "sticky bottom-0 z-30"),
18
+ className: cn("flex shrink-0 border-t bg-background pb-[var(--pb-safe-bottom)] md:hidden", sticky && "sticky bottom-0 z-30"),
19
19
  children: [tabs.map((item) => {
20
20
  const Icon = item.icon;
21
21
  return /* @__PURE__ */ jsxs("a", {
@@ -21,7 +21,7 @@ const Drawer = ({ id, open, onClose, children }) => {
21
21
  "aria-modal": "true",
22
22
  "aria-label": text("navigation"),
23
23
  tabIndex: -1,
24
- className: "absolute inset-y-0 left-0 flex w-60 max-w-[85vw] bg-sidebar shadow-pop outline-none",
24
+ className: "absolute inset-y-0 left-0 flex w-[calc(15rem+var(--pb-safe-left))] max-w-[85vw] bg-sidebar pl-[var(--pb-safe-left)] shadow-pop outline-none",
25
25
  onClick: (event) => event.target.closest("a") && onClose(),
26
26
  children
27
27
  })]
@@ -49,7 +49,7 @@ const usePageInsets = (on, top, bottom, bottomShown) => {
49
49
  const root = document.documentElement;
50
50
  const update = () => {
51
51
  const above = `${top.current?.offsetHeight ?? 0}px`;
52
- const below = `${bottom.current?.offsetHeight ?? 0}px`;
52
+ const below = bottom.current ? `${bottom.current.offsetHeight}px` : "var(--pb-safe-bottom)";
53
53
  root.style.setProperty("--pb-sticky-top", above);
54
54
  root.style.setProperty("--pb-sticky-bottom", below);
55
55
  root.style.setProperty("scroll-padding-top", above);
@@ -19,7 +19,7 @@ const Sidebar = ({ mode, activeItem, user, workspace, appName, appIcon, forceExp
19
19
  "aria-label": text("resources"),
20
20
  className: cn(sticky ? "sticky top-0 h-dvh self-start" : "relative", "z-30 shrink-0", sidebarWidth[mode]),
21
21
  children: /* @__PURE__ */ jsxs("div", {
22
- className: cn("group/side absolute inset-y-0 left-0 flex flex-col overflow-hidden border-r bg-sidebar", expanding ? "w-14 transition-[width,box-shadow] duration-150 hover:w-60 hover:shadow-pop focus-within:w-60 focus-within:shadow-pop" : "w-full", expanded && "w-60 shadow-pop"),
22
+ className: cn("group/side absolute inset-y-0 left-0 flex flex-col overflow-hidden border-r bg-sidebar pb-[var(--pb-safe-bottom)] pt-[var(--pb-safe-top)]", expanding ? "w-14 transition-[width,box-shadow] duration-150 hover:w-60 hover:shadow-pop focus-within:w-60 focus-within:shadow-pop" : "w-full", expanded && "w-60 shadow-pop"),
23
23
  children: [
24
24
  /* @__PURE__ */ jsx("div", {
25
25
  className: cn("flex h-12 shrink-0 items-center px-3.5", mode === "icon-label" && "justify-center px-0"),
@@ -27,7 +27,7 @@ const TopBar = ({ breadcrumb, onNavigate, actions, onMenu, menuOpen, menuControl
27
27
  }, [search]);
28
28
  return /* @__PURE__ */ jsxs("header", {
29
29
  ref,
30
- className: cn(sticky ? "sticky top-0 z-30" : "relative", "flex h-12 shrink-0 items-center gap-1 border-b bg-background pl-4 pr-2 md:gap-4 md:px-5"),
30
+ className: cn(sticky ? "sticky top-0 z-30" : "relative", "flex h-[calc(3rem+var(--pb-safe-top))] shrink-0 items-center gap-1 border-b bg-background pl-4 pr-2 pt-[var(--pb-safe-top)] md:gap-4 md:px-5"),
31
31
  children: [
32
32
  onMenu && /* @__PURE__ */ jsx("button", {
33
33
  type: "button",
@@ -78,7 +78,7 @@ const TopBar = ({ breadcrumb, onNavigate, actions, onMenu, menuOpen, menuControl
78
78
  ]
79
79
  }),
80
80
  search && searchOpen && /* @__PURE__ */ jsxs("div", {
81
- className: "absolute inset-0 z-20 flex items-center gap-1 bg-background px-3 md:hidden",
81
+ className: "absolute inset-0 z-20 flex items-center gap-1 bg-background px-3 pt-[var(--pb-safe-top)] md:hidden",
82
82
  children: [/* @__PURE__ */ jsx(GlobalSearch, {
83
83
  className: "min-w-0 flex-1",
84
84
  autoFocus: true,
@@ -4,7 +4,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/auth/auth-layout.tsx
5
5
  /** The frame of the sign-in and first-run pages and of public forms: logo, title and a card. */
6
6
  const AuthLayout = ({ title, description, size = "sm", children }) => /* @__PURE__ */ jsx("div", {
7
- className: "flex min-h-full w-full items-center justify-center bg-surface px-4 py-10",
7
+ className: "flex min-h-full w-full items-center justify-center bg-surface px-4 pb-[calc(2.5rem+var(--pb-safe-bottom))] pt-[calc(2.5rem+var(--pb-safe-top))]",
8
8
  children: /* @__PURE__ */ jsxs("div", {
9
9
  className: cn("w-full", size === "sm" ? "max-w-sm" : "max-w-lg"),
10
10
  children: [/* @__PURE__ */ jsxs("div", {
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.44.2";
2
+ var version = "0.44.4";
3
3
  var protobase = { "pluginApi": 1 };
4
4
  //#endregion
5
5
  export { protobase, version };
@@ -8,7 +8,7 @@ const Dialog = ({ title, description, onClose, actions, children, wide = false }
8
8
  const panel = useRef(null);
9
9
  useFocusTrap(panel, true, onClose);
10
10
  return /* @__PURE__ */ jsx("div", {
11
- className: "fixed inset-0 z-[90] flex items-center justify-center bg-backdrop/30 p-4",
11
+ className: "fixed inset-0 z-[90] flex items-center justify-center bg-backdrop/30 p-4 pb-[calc(1rem+var(--pb-safe-bottom))] pl-[calc(1rem+var(--pb-safe-left))] pr-[calc(1rem+var(--pb-safe-right))] pt-[calc(1rem+var(--pb-safe-top))]",
12
12
  onMouseDown: (event) => event.target === event.currentTarget && onClose(),
13
13
  children: /* @__PURE__ */ jsxs("div", {
14
14
  ref: panel,
@@ -16,7 +16,7 @@ const Dialog = ({ title, description, onClose, actions, children, wide = false }
16
16
  role: "dialog",
17
17
  "aria-modal": "true",
18
18
  "aria-label": title,
19
- className: cn("outline-none max-h-[90vh] w-full overflow-y-auto rounded-lg border bg-background p-4 shadow-pop sm:p-5", wide ? "max-w-3xl" : "max-w-md"),
19
+ className: cn("outline-none max-h-[min(90vh,100%)] w-full overflow-y-auto rounded-lg border bg-background p-4 shadow-pop sm:p-5", wide ? "max-w-3xl" : "max-w-md"),
20
20
  children: [
21
21
  /* @__PURE__ */ jsx("h2", {
22
22
  className: "text-[16px] font-semibold",
@@ -39,7 +39,7 @@ const Sheet = ({ title, open, onClose, children }) => {
39
39
  "aria-modal": "true",
40
40
  "aria-label": title,
41
41
  tabIndex: -1,
42
- className: "absolute inset-x-0 bottom-0 flex max-h-[85vh] flex-col rounded-t-xl border-t bg-background shadow-pop outline-none",
42
+ className: "absolute inset-x-0 bottom-0 flex max-h-[85vh] flex-col rounded-t-xl border-t bg-background pl-[var(--pb-safe-left)] pr-[var(--pb-safe-right)] shadow-pop outline-none",
43
43
  children: [/* @__PURE__ */ jsxs("header", {
44
44
  className: "relative flex shrink-0 touch-none items-center justify-between border-b px-4",
45
45
  onPointerDown: down,
@@ -63,7 +63,7 @@ const Sheet = ({ title, open, onClose, children }) => {
63
63
  })
64
64
  ]
65
65
  }), /* @__PURE__ */ jsx("div", {
66
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 pb-6",
66
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 pb-[calc(1.5rem+var(--pb-safe-bottom))]",
67
67
  children
68
68
  })]
69
69
  })]