@protobase/ui 0.14.0 → 0.14.2

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 (75) hide show
  1. package/dist/app/current-address.js +19 -1
  2. package/dist/app/displays/card-carousel.js +47 -39
  3. package/dist/app/displays/card-image.js +25 -0
  4. package/dist/app/displays/card-photos.js +11 -15
  5. package/dist/app/displays/cards-display.js +2 -1
  6. package/dist/app/displays/list-cards.js +2 -2
  7. package/dist/app/displays/list-displays.d.ts +2 -0
  8. package/dist/app/displays/list-displays.js +9 -3
  9. package/dist/app/displays/map-display.js +5 -4
  10. package/dist/app/displays/record-card.js +28 -34
  11. package/dist/app/displays/use-map-records.js +8 -6
  12. package/dist/app/displays/virtual-cards.js +43 -65
  13. package/dist/app/embedded-list/embedded-columns.js +1 -1
  14. package/dist/app/embedded-list/use-embedded-rows.js +11 -6
  15. package/dist/app/list-page.js +53 -13
  16. package/dist/app/menu-icons.js +3 -1
  17. package/dist/app/named-icon.js +5 -3
  18. package/dist/app/nav-from-meta.js +21 -1
  19. package/dist/app/pages/blocks/card-row.js +1 -1
  20. package/dist/app/pages/blocks/modal-form.js +1 -1
  21. package/dist/app/pages/blocks/record-card.js +1 -1
  22. package/dist/app/pages/blocks/show.js +1 -1
  23. package/dist/app/pages/blocks/stat.js +1 -1
  24. package/dist/app/pages/use-run-action.js +1 -1
  25. package/dist/app/saved/favorite-button.js +49 -0
  26. package/dist/app/saved/saved-list.js +43 -0
  27. package/dist/app/saved/saved-records.js +38 -0
  28. package/dist/app/saved/use-favorite.js +62 -0
  29. package/dist/app/saved/use-saved-records.js +36 -0
  30. package/dist/app/use-app-address.js +5 -2
  31. package/dist/app-shell/app-shell.js +54 -38
  32. package/dist/app-shell/bottom-bar.d.ts +1 -0
  33. package/dist/app-shell/bottom-bar.js +3 -2
  34. package/dist/app-shell/index.d.ts +1 -0
  35. package/dist/app-shell/page-scroll.d.ts +1 -0
  36. package/dist/app-shell/page-scroll.js +56 -0
  37. package/dist/app-shell/sidebar.js +2 -2
  38. package/dist/app-shell/top-bar.js +3 -2
  39. package/dist/auth/sign-in-prompt.d.ts +22 -0
  40. package/dist/auth/sign-in-prompt.js +84 -0
  41. package/dist/data/api-provider.d.ts +2 -0
  42. package/dist/data/meta-data.d.ts +3 -1
  43. package/dist/data/query-keys.js +0 -5
  44. package/dist/data/use-meta.js +1 -0
  45. package/dist/data-grid/data-grid.js +92 -85
  46. package/dist/data-grid/geometry.js +26 -6
  47. package/dist/data-grid/grid-footer.js +5 -12
  48. package/dist/data-grid/scroll-parent.js +35 -0
  49. package/dist/data-grid/use-virtual-rows.js +123 -18
  50. package/dist/index.d.ts +3 -1
  51. package/dist/index.js +3 -1
  52. package/dist/live/grid-loader.js +8 -3
  53. package/dist/live/reference-options.js +2 -2
  54. package/dist/live/relation-labels.js +16 -18
  55. package/dist/live/row-photos.js +18 -0
  56. package/dist/live/use-filter-config.js +7 -2
  57. package/dist/package.js +1 -1
  58. package/dist/primitives/button.js +7 -2
  59. package/dist/primitives/dialog.js +1 -1
  60. package/dist/primitives/responsive-dialog.d.ts +17 -0
  61. package/dist/primitives/responsive-dialog.js +44 -0
  62. package/dist/shell/assets/app-B2GAOqtJ.js +66 -0
  63. package/dist/shell/assets/index-BXYHpFoe.css +2 -0
  64. package/dist/shell/assets/{index-CwUFCDf9.js → index-DTbA97zz.js} +1 -1
  65. package/dist/shell/assets/{maplibre-gl-QGc1hPKt.js → maplibre-gl-CSTJJJQT.js} +1 -1
  66. package/dist/shell/assets/{record-map-D5vqYcYw.js → record-map-CeTF-ArN.js} +2 -2
  67. package/dist/shell/assets/{records-map-DqqaK1rm.js → records-map-Cl0Ofb1s.js} +1 -1
  68. package/dist/shell/assets/shared-protobase-ui-4J-P80A-.js +1 -0
  69. package/dist/shell/index.html +4 -4
  70. package/dist/shell/protobase.shell.json +1 -1
  71. package/package.json +4 -4
  72. package/dist/data-grid/use-grid-scroll.js +0 -87
  73. package/dist/shell/assets/app-DtPlcCA3.js +0 -66
  74. package/dist/shell/assets/index-CYWfU_c1.css +0 -2
  75. package/dist/shell/assets/shared-protobase-ui-0ozDlcDr.js +0 -1
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-Cvdyeg_0.js";import{W as n,g as r}from"./app-DtPlcCA3.js";import{t as i}from"./jsx-runtime-NZYk81nU.js";import{Ft as a,it as o,n as s,r as c,t as l}from"./record-map-D5vqYcYw.js";var u=e(t(),1),d=e(i(),1),f=28,p={padding:48,maxZoom:15,duration:0},m={padding:48,maxZoom:16,duration:300},h=32,g=new Intl.NumberFormat(`en-IE`,{notation:`compact`,maximumFractionDigits:1}),_=e=>[[e.west,e.south],[e.east,e.north]],v=({style:e,initial:t,points:i,buckets:v,fit:y,onFitted:b,onMove:x,selected:S,covered:C,onSelect:w,onClear:T,markerLabel:E,bucketLabel:D})=>{let O=(0,u.useRef)(null),[k,A]=(0,u.useState)([]),j=new globalThis.Map(i.map(e=>[e.key,e])),M=i.map(e=>e.key).join(`,`),N=y&&JSON.stringify(y),P=()=>{let e=O.current?.getMap();e&&A(r(i.map(t=>({key:t.key,...e.project([t.longitude,t.latitude])})),f))},F=()=>{let e=O.current?.getMap();if(!e)return;let t=e.getBounds(),n=e.getCenter();x({bounds:{south:t.getSouth(),west:t.getWest(),north:t.getNorth(),east:t.getEast()},zoom:e.getZoom()},{latitude:n.lat,longitude:n.lng,zoom:e.getZoom()})},I=()=>{let e=O.current?.getMap();e&&y&&(e.fitBounds(_(y),p),b(),F())};(0,u.useEffect)(P,[M]),(0,u.useEffect)(I,[N]);let L=k.find(e=>S!==void 0&&e.keys.some(e=>S.includes(e)))?.at;return(0,u.useEffect)(()=>{let e=O.current?.getMap(),t=L===void 0?void 0:j.get(L);if(!e||!t||C===0)return;let{y:n}=e.project([t.longitude,t.latitude]),r=e.getContainer().clientHeight-C;n>h&&n<r||e.easeTo({center:[t.longitude,t.latitude],offset:[0,(h-C)/2],duration:300})},[L,C]),(0,d.jsxs)(c,{ref:O,mapLib:o,mapStyle:e,initialViewState:t??{latitude:0,longitude:0,zoom:1},style:{width:`100%`,height:`100%`},onLoad:()=>{P(),y?I():F()},onZoomEnd:P,onMoveEnd:F,onClick:T,children:[(0,d.jsx)(l,{showCompass:!1}),v.map(e=>(0,d.jsx)(s,{latitude:e.latitude,longitude:e.longitude,anchor:`center`,children:(0,d.jsx)(`button`,{type:`button`,"aria-label":D(e.count),className:`flex size-10 cursor-pointer items-center justify-center rounded-full border-2 border-background bg-primary text-xs font-semibold text-primary-foreground tabular-nums shadow`,onClick:t=>{t.stopPropagation(),O.current?.getMap().fitBounds(_(e.bounds),m)},children:g.format(e.count)})},`${e.latitude},${e.longitude}`)),k.map(e=>{let t=j.get(e.at);if(!t)return null;let r=S!==void 0&&e.keys.some(e=>S.includes(e));return(0,d.jsx)(s,{latitude:t.latitude,longitude:t.longitude,anchor:`bottom`,style:{zIndex:+!!r},children:(0,d.jsxs)(`button`,{type:`button`,"aria-label":E(e.keys),"aria-pressed":r,className:`relative block cursor-pointer`,onClick:t=>{t.stopPropagation(),w(e.keys)},children:[(0,d.jsx)(a,{"aria-hidden":!0,className:n(`size-8 drop-shadow`,r?`fill-foreground text-background`:`fill-primary text-primary-foreground`),strokeWidth:1.5}),e.keys.length>1&&(0,d.jsx)(`span`,{className:`absolute -right-2 -top-1 min-w-5 rounded-full border border-background bg-foreground px-1 text-center text-[11px] font-medium leading-4 text-background tabular-nums`,children:e.keys.length})]})},e.at)})]})};export{v as RecordsMap};
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-Cvdyeg_0.js";import{K as n,g as r}from"./app-B2GAOqtJ.js";import{t as i}from"./jsx-runtime-NZYk81nU.js";import{Ft as a,it as o,n as s,r as c,t as l}from"./record-map-CeTF-ArN.js";var u=e(t(),1),d=e(i(),1),f=28,p={padding:48,maxZoom:15,duration:0},m={padding:48,maxZoom:16,duration:300},h=32,g=new Intl.NumberFormat(`en-IE`,{notation:`compact`,maximumFractionDigits:1}),_=e=>[[e.west,e.south],[e.east,e.north]],v=({style:e,initial:t,points:i,buckets:v,fit:y,onFitted:b,onMove:x,selected:S,covered:C,onSelect:w,onClear:T,markerLabel:E,bucketLabel:D})=>{let O=(0,u.useRef)(null),[k,A]=(0,u.useState)([]),j=new globalThis.Map(i.map(e=>[e.key,e])),M=i.map(e=>e.key).join(`,`),N=y&&JSON.stringify(y),P=()=>{let e=O.current?.getMap();e&&A(r(i.map(t=>({key:t.key,...e.project([t.longitude,t.latitude])})),f))},F=()=>{let e=O.current?.getMap();if(!e)return;let t=e.getBounds(),n=e.getCenter();x({bounds:{south:t.getSouth(),west:t.getWest(),north:t.getNorth(),east:t.getEast()},zoom:e.getZoom()},{latitude:n.lat,longitude:n.lng,zoom:e.getZoom()})},I=()=>{let e=O.current?.getMap();e&&y&&(e.fitBounds(_(y),p),b(),F())};(0,u.useEffect)(P,[M]),(0,u.useEffect)(I,[N]);let L=k.find(e=>S!==void 0&&e.keys.some(e=>S.includes(e)))?.at;return(0,u.useEffect)(()=>{let e=O.current?.getMap(),t=L===void 0?void 0:j.get(L);if(!e||!t||C===0)return;let{y:n}=e.project([t.longitude,t.latitude]),r=e.getContainer().clientHeight-C;n>h&&n<r||e.easeTo({center:[t.longitude,t.latitude],offset:[0,(h-C)/2],duration:300})},[L,C]),(0,d.jsxs)(c,{ref:O,mapLib:o,mapStyle:e,initialViewState:t??{latitude:0,longitude:0,zoom:1},style:{width:`100%`,height:`100%`},onLoad:()=>{P(),y?I():F()},onZoomEnd:P,onMoveEnd:F,onClick:T,children:[(0,d.jsx)(l,{showCompass:!1}),v.map(e=>(0,d.jsx)(s,{latitude:e.latitude,longitude:e.longitude,anchor:`center`,children:(0,d.jsx)(`button`,{type:`button`,"aria-label":D(e.count),className:`flex size-10 cursor-pointer items-center justify-center rounded-full border-2 border-background bg-primary text-xs font-semibold text-primary-foreground tabular-nums shadow`,onClick:t=>{t.stopPropagation(),O.current?.getMap().fitBounds(_(e.bounds),m)},children:g.format(e.count)})},`${e.latitude},${e.longitude}`)),k.map(e=>{let t=j.get(e.at);if(!t)return null;let r=S!==void 0&&e.keys.some(e=>S.includes(e));return(0,d.jsx)(s,{latitude:t.latitude,longitude:t.longitude,anchor:`bottom`,style:{zIndex:+!!r},children:(0,d.jsxs)(`button`,{type:`button`,"aria-label":E(e.keys),"aria-pressed":r,className:`relative block cursor-pointer`,onClick:t=>{t.stopPropagation(),w(e.keys)},children:[(0,d.jsx)(a,{"aria-hidden":!0,className:n(`size-8 drop-shadow`,r?`fill-foreground text-background`:`fill-primary text-primary-foreground`),strokeWidth:1.5}),e.keys.length>1&&(0,d.jsx)(`span`,{className:`absolute -right-2 -top-1 min-w-5 rounded-full border border-background bg-foreground px-1 text-center text-[11px] font-medium leading-4 text-background tabular-nums`,children:e.keys.length})]})},e.at)})]})};export{v as RecordsMap};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,L as u,M as d,N as f,O as p,P as m,R as h,S as g,T as _,U as v,V as y,W as b,_ as x,a as S,b as C,c as w,d as T,f as E,h as D,i as O,j as k,l as A,m as j,n as M,o as N,p as P,r as F,s as I,t as L,u as R,v as z,w as B,x as V,y as H,z as U}from"./app-B2GAOqtJ.js";import{t as W}from"./jsx-runtime-NZYk81nU.js";var G=e(W(),1),K=({row:e,resource:t,recordKey:n,...r})=>{let i=D(),a=R(),o=t??i?.resource??a?.model.name;if(o===void 0)throw Error(`RecordLink needs a resource outside a list display or a record`);return(0,G.jsx)(H,{to:{kind:`record`,resource:o,key:e?e.key:n},...r})};export{l as ActionCard,v as ApiProvider,L as App,H as AppLink,B as AssistantDock,n as ChatMessage,U as ChatThread,m as CompactTable,h as Composer,k as DiffView,o as FieldList,a as PartView,K as RecordLink,z as ResponsiveDialog,u as SidePanel,x as SignInPrompt,t as StepList,i as definePlugin,p as defineUi,d as diffStats,M as isConflict,w as mergeUi,f as parseDiff,S as pluginApi,N as protobaseVersion,A as uiFromModule,c as useApiToken,C as useAppAddress,r as useAssistant,g as useAssistantClient,_ as useBackendData,b as useClient,T as useFacets,E as useHistogram,R as useLayoutRecord,O as useList,j as useListDisplay,V as useMeta,I as usePlugin,y as useRecord,s as useResourceClient,P as useSeries,F as useUpdateRecord};
@@ -6,15 +6,15 @@
6
6
  <meta charset="utf-8" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
8
8
  <title>Protobase</title>
9
- <script type="importmap">{"imports":{"react":"/assets/shared-react-DhkZ2M4l.js","react/jsx-runtime":"/assets/shared-react-jsx-runtime-xPQrWk0g.js","react-dom":"/assets/shared-react-dom-D508a1cq.js","@protobase/ui":"/assets/shared-protobase-ui-0ozDlcDr.js"}}</script>
10
- <script type="module" crossorigin src="/assets/index-CwUFCDf9.js"></script>
9
+ <script type="importmap">{"imports":{"react":"/assets/shared-react-DhkZ2M4l.js","react/jsx-runtime":"/assets/shared-react-jsx-runtime-xPQrWk0g.js","react-dom":"/assets/shared-react-dom-D508a1cq.js","@protobase/ui":"/assets/shared-protobase-ui-4J-P80A-.js"}}</script>
10
+ <script type="module" crossorigin src="/assets/index-DTbA97zz.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/react-Cvdyeg_0.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/react-dom-B-VxWsjA.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-NZYk81nU.js">
15
- <link rel="modulepreload" crossorigin href="/assets/app-DtPlcCA3.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/app-B2GAOqtJ.js">
16
16
  <link rel="stylesheet" crossorigin href="/assets/app-GUjJKojE.css">
17
- <link rel="stylesheet" crossorigin href="/assets/index-CYWfU_c1.css">
17
+ <link rel="stylesheet" crossorigin href="/assets/index-BXYHpFoe.css">
18
18
  <link rel="stylesheet" href="/protobase.theme.css">
19
19
  </head>
20
20
  <body>
@@ -1,5 +1,5 @@
1
1
  {
2
- "protobase": "0.14.0",
2
+ "protobase": "0.14.2",
3
3
  "pluginApi": 1,
4
4
  "paths": [
5
5
  "/index.html",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protobase/ui",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "The Protobase admin app and the React hooks and components for custom UI.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -38,9 +38,9 @@
38
38
  "dependencies": {
39
39
  "@dnd-kit/core": "^6.3.1",
40
40
  "@dnd-kit/sortable": "^10.0.0",
41
- "@protobase/client": "0.14.0",
42
- "@protobase/layout": "0.14.0",
43
- "@protobase/schema": "0.14.0",
41
+ "@protobase/client": "0.14.2",
42
+ "@protobase/layout": "0.14.2",
43
+ "@protobase/schema": "0.14.2",
44
44
  "@sentry/browser": "^11.7.0",
45
45
  "@tanstack/react-query": "^5.104.1",
46
46
  "@tanstack/react-table": "^9.2.6",
@@ -1,87 +0,0 @@
1
- import { clampTop, gridGeometry, scrollFromTop, topFromScroll } from "./geometry.js";
2
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
3
- //#region src/data-grid/use-grid-scroll.ts
4
- /**
5
- * Owns the scroll position of a grid whose true height may exceed what browsers can scroll.
6
- * The native scroller is a proxy: its position is mapped onto a virtual pixel offset `top`.
7
- */
8
- const useGridScroll = (total, rowHeight, initialIndex) => {
9
- const ref = useRef(null);
10
- const [viewport, setViewport] = useState(0);
11
- const [top, setTop] = useState(initialIndex * rowHeight);
12
- const geometry = useMemo(() => gridGeometry(total, rowHeight, viewport), [
13
- total,
14
- rowHeight,
15
- viewport
16
- ]);
17
- const latest = useRef({
18
- geometry,
19
- top
20
- });
21
- latest.current = {
22
- geometry,
23
- top
24
- };
25
- const ignoreScrollUntil = useRef(0);
26
- const positioned = useRef(false);
27
- const syncNative = useCallback((nextTop) => {
28
- const element = ref.current;
29
- if (!element) return;
30
- element.scrollTop = scrollFromTop(latest.current.geometry, nextTop);
31
- ignoreScrollUntil.current = performance.now() + 150;
32
- }, []);
33
- useLayoutEffect(() => {
34
- const element = ref.current;
35
- if (!element) return;
36
- const observer = new ResizeObserver(() => setViewport(element.clientHeight));
37
- observer.observe(element);
38
- setViewport(element.clientHeight);
39
- return () => observer.disconnect();
40
- }, []);
41
- useLayoutEffect(() => {
42
- if (viewport === 0 || positioned.current) return;
43
- positioned.current = true;
44
- const next = clampTop(geometry, top);
45
- setTop(next);
46
- syncNative(next);
47
- }, [
48
- viewport,
49
- geometry,
50
- top,
51
- syncNative
52
- ]);
53
- useEffect(() => {
54
- const element = ref.current;
55
- if (!element) return;
56
- const onWheel = (event) => {
57
- const { geometry: current, top: currentTop } = latest.current;
58
- if (!current.scaled || Math.abs(event.deltaX) > Math.abs(event.deltaY)) return;
59
- event.preventDefault();
60
- const next = clampTop(current, currentTop + event.deltaY);
61
- setTop(next);
62
- syncNative(next);
63
- };
64
- element.addEventListener("wheel", onWheel, { passive: false });
65
- return () => element.removeEventListener("wheel", onWheel);
66
- }, [syncNative]);
67
- /** Moves to a virtual offset, for a layout change that keeps a row in view. */
68
- const scrollTo = useCallback((nextTop) => {
69
- const next = clampTop(latest.current.geometry, nextTop);
70
- setTop(next);
71
- syncNative(next);
72
- }, [syncNative]);
73
- return {
74
- ref,
75
- onScroll: useCallback(() => {
76
- const element = ref.current;
77
- if (!element || performance.now() < ignoreScrollUntil.current) return;
78
- setTop(topFromScroll(latest.current.geometry, element.scrollTop));
79
- }, []),
80
- viewport,
81
- top,
82
- geometry,
83
- scrollTo
84
- };
85
- };
86
- //#endregion
87
- export { useGridScroll };