@protobase/ui 0.14.4 → 0.14.6
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/dist/activity-chart/activity-chart.js +1 -1
- package/dist/app/app.d.ts +2 -1
- package/dist/app/app.js +10 -3
- package/dist/app/displays/display-controls.js +1 -1
- package/dist/app/embedded-list/embedded-list.js +35 -27
- package/dist/app/index.html +10 -0
- package/dist/app/list-page.js +20 -3
- package/dist/app/menu-icons.js +2 -1
- package/dist/app/named-icon.js +3 -2
- package/dist/app/pages/blocks/field.js +2 -2
- package/dist/app/pages/blocks/progress.js +1 -1
- package/dist/app/pages/blocks/show.js +1 -1
- package/dist/app/pages/blocks/stat.js +2 -2
- package/dist/app/pages/blocks/table.js +1 -1
- package/dist/app/searches/save-search-button.js +44 -0
- package/dist/app/searches/saved-search-section.js +97 -0
- package/dist/app/searches/saved-search.js +94 -0
- package/dist/app/searches/saved-searches.js +107 -0
- package/dist/app/searches/search-controls.js +64 -0
- package/dist/app/searches/use-filter-chips.js +27 -0
- package/dist/app/searches/use-save-search.js +70 -0
- package/dist/app/searches/use-saved-searches.js +37 -0
- package/dist/app-shell/app-shell.js +4 -3
- package/dist/app-shell/drawer.js +1 -1
- package/dist/app-shell/logo.js +2 -2
- package/dist/app-shell/profile-menu.js +10 -2
- package/dist/app-shell/sidebar.js +3 -2
- package/dist/app-shell/theme-switch.js +41 -0
- package/dist/auth/auth-gate.js +0 -9
- package/dist/data-grid/data-grid.js +1 -1
- package/dist/live/use-filter-config.js +2 -6
- package/dist/live/view-fields.js +8 -1
- package/dist/package.js +1 -1
- package/dist/primitives/dialog.js +1 -1
- package/dist/primitives/responsive-dialog.d.ts +1 -2
- package/dist/primitives/responsive-dialog.js +11 -13
- package/dist/primitives/segmented.js +6 -2
- package/dist/primitives/sheet.js +39 -39
- package/dist/shell/assets/app-CYs0l-vz.js +66 -0
- package/dist/shell/assets/{index-DhgTXlZ3.js → index-BCqsBT_o.js} +1 -1
- package/dist/shell/assets/index-ibaHR5wQ.css +2 -0
- package/dist/shell/assets/{maplibre-gl-CKQN3M1I.js → maplibre-gl-CxevrnFA.js} +1 -1
- package/dist/shell/assets/{record-map-CzJ60-ux.js → record-map-Mn5aTqIF.js} +2 -2
- package/dist/shell/assets/{records-map-dch_o1ug.js → records-map-BdPiGjmg.js} +1 -1
- package/dist/shell/assets/{shared-protobase-ui-C-qDEeIK.js → shared-protobase-ui-CRhV6ipQ.js} +1 -1
- package/dist/shell/index.html +14 -4
- package/dist/shell/protobase.shell.json +1 -1
- package/dist/styles.css +5 -2
- package/dist/theme/theme-preference.js +23 -0
- package/dist/theme/theme-provider.js +43 -0
- package/dist/theme.css +4 -0
- package/dist/tokens.css +2 -0
- package/package.json +4 -5
- package/dist/shell/assets/app-CyW0VzOi.js +0 -66
- package/dist/shell/assets/index-DthLyPYI.css +0 -2
|
@@ -1 +1 @@
|
|
|
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-
|
|
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-CYs0l-vz.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-Mn5aTqIF.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};
|
package/dist/shell/assets/{shared-protobase-ui-C-qDEeIK.js → shared-protobase-ui-CRhV6ipQ.js}
RENAMED
|
@@ -1 +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-
|
|
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-CYs0l-vz.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};
|
package/dist/shell/index.html
CHANGED
|
@@ -6,15 +6,25 @@
|
|
|
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
|
-
|
|
10
|
-
<script
|
|
9
|
+
<!-- The theme before the first paint, so a dark page never flashes light: as theme/theme-preference.ts resolves it, the choice stored in this browser, else the system's. -->
|
|
10
|
+
<script>
|
|
11
|
+
var stored = null
|
|
12
|
+
try {
|
|
13
|
+
stored = localStorage.getItem('protobase:theme')
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (!(error instanceof DOMException)) throw error
|
|
16
|
+
}
|
|
17
|
+
document.documentElement.dataset.theme = stored === 'light' || stored === 'dark' ? stored : matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
18
|
+
</script>
|
|
19
|
+
<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-CRhV6ipQ.js"}}</script>
|
|
20
|
+
<script type="module" crossorigin src="/assets/index-BCqsBT_o.js"></script>
|
|
11
21
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
|
|
12
22
|
<link rel="modulepreload" crossorigin href="/assets/react-Cvdyeg_0.js">
|
|
13
23
|
<link rel="modulepreload" crossorigin href="/assets/react-dom-B-VxWsjA.js">
|
|
14
24
|
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-NZYk81nU.js">
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/app-
|
|
25
|
+
<link rel="modulepreload" crossorigin href="/assets/app-CYs0l-vz.js">
|
|
16
26
|
<link rel="stylesheet" crossorigin href="/assets/app-GUjJKojE.css">
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
27
|
+
<link rel="stylesheet" crossorigin href="/assets/index-ibaHR5wQ.css">
|
|
18
28
|
<link rel="stylesheet" href="/protobase.theme.css">
|
|
19
29
|
</head>
|
|
20
30
|
<body>
|
package/dist/styles.css
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
@import "./tokens.css";
|
|
4
4
|
@source "./";
|
|
5
5
|
|
|
6
|
-
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
7
|
-
|
|
8
6
|
@layer base {
|
|
9
7
|
html {
|
|
10
8
|
font-size: 16px;
|
|
9
|
+
color-scheme: light;
|
|
10
|
+
}
|
|
11
|
+
/* Native parts, such as scrollbars, date pickers and autofill, follow the theme too. */
|
|
12
|
+
html[data-theme="dark"] {
|
|
13
|
+
color-scheme: dark;
|
|
11
14
|
}
|
|
12
15
|
body {
|
|
13
16
|
background: var(--background);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { guarded } from "../lib/guarded.js";
|
|
2
|
+
//#region src/theme/theme-preference.ts
|
|
3
|
+
const themePreferences = [
|
|
4
|
+
"light",
|
|
5
|
+
"dark",
|
|
6
|
+
"system"
|
|
7
|
+
];
|
|
8
|
+
/** Where the choice is kept in this browser; index.html reads the same key before the first paint. */
|
|
9
|
+
const themeStorageKey = "protobase:theme";
|
|
10
|
+
/** Matches while the system asks for dark. */
|
|
11
|
+
const systemDarkQuery = "(prefers-color-scheme: dark)";
|
|
12
|
+
const isPreference = (value) => themePreferences.includes(value);
|
|
13
|
+
/** The choice made in this browser; the system's until someone picks a theme, or when storage is unavailable. */
|
|
14
|
+
const readThemePreference = (storage) => guarded(() => {
|
|
15
|
+
const stored = storage.getItem(themeStorageKey);
|
|
16
|
+
return isPreference(stored) ? stored : "system";
|
|
17
|
+
}, "system");
|
|
18
|
+
/** Remembers a picked theme; following the system again is the default, so it costs no storage. */
|
|
19
|
+
const writeThemePreference = (storage, preference) => guarded(() => preference === "system" ? storage.removeItem(themeStorageKey) : storage.setItem(themeStorageKey, preference), void 0);
|
|
20
|
+
/** The theme to draw in, for a choice and whether the system asks for dark. */
|
|
21
|
+
const resolveTheme = (preference, systemDark) => preference === "system" ? systemDark ? "dark" : "light" : preference;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { readThemePreference, resolveTheme, systemDarkQuery, themePreferences, themeStorageKey, writeThemePreference };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useMediaQuery } from "../lib/use-media-query.js";
|
|
2
|
+
import { readThemePreference, resolveTheme, systemDarkQuery, writeThemePreference } from "./theme-preference.js";
|
|
3
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/theme/theme-provider.tsx
|
|
6
|
+
const ThemeContext = createContext(void 0);
|
|
7
|
+
/**
|
|
8
|
+
* Draws the page in the theme this browser chose, or the system's, by setting `data-theme` on the root element, and
|
|
9
|
+
* follows the system and other tabs as they change. index.html sets the same before the first paint.
|
|
10
|
+
*/
|
|
11
|
+
const ThemeProvider = ({ children }) => {
|
|
12
|
+
const [preference, setPreference] = useState(() => readThemePreference(localStorage));
|
|
13
|
+
const theme = resolveTheme(preference, useMediaQuery(systemDarkQuery));
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
document.documentElement.dataset.theme = theme;
|
|
16
|
+
}, [theme]);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const follow = (event) => {
|
|
19
|
+
if (event.key === "protobase:theme" || event.key === null) setPreference(readThemePreference(localStorage));
|
|
20
|
+
};
|
|
21
|
+
window.addEventListener("storage", follow);
|
|
22
|
+
return () => window.removeEventListener("storage", follow);
|
|
23
|
+
}, []);
|
|
24
|
+
const choose = (next) => {
|
|
25
|
+
writeThemePreference(localStorage, next);
|
|
26
|
+
setPreference(next);
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ jsx(ThemeContext.Provider, {
|
|
29
|
+
value: {
|
|
30
|
+
preference,
|
|
31
|
+
theme,
|
|
32
|
+
choose
|
|
33
|
+
},
|
|
34
|
+
children
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const useTheme = () => {
|
|
38
|
+
const state = useContext(ThemeContext);
|
|
39
|
+
if (!state) throw new Error("useTheme needs a ThemeProvider above it");
|
|
40
|
+
return state;
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { ThemeProvider, useTheme };
|
package/dist/theme.css
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* imports it, and a plugin's stylesheet references it, so a plugin's utilities draw with the app's theme whatever
|
|
5
5
|
* version of the app loads them, and with these defaults where the app sets none.
|
|
6
6
|
*/
|
|
7
|
+
|
|
8
|
+
/* `dark:` follows the theme the user picked in the app, not only the system's, for the app and plugins alike. */
|
|
9
|
+
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
7
10
|
@theme inline {
|
|
8
11
|
--color-background: var(--background);
|
|
9
12
|
--color-surface: var(--surface);
|
|
@@ -33,6 +36,7 @@
|
|
|
33
36
|
--color-violet-text: var(--violet-text);
|
|
34
37
|
--color-sidebar: var(--sidebar);
|
|
35
38
|
--shadow-pop: var(--shadow-pop);
|
|
39
|
+
--color-backdrop: var(--backdrop);
|
|
36
40
|
--font-sans: var(--font, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);
|
|
37
41
|
--font-mono: var(--font-code, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
|
|
38
42
|
--radius-sm: max(0px, calc(var(--radius, 6px) - 2px));
|
package/dist/tokens.css
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
--violet-text: #6d28d9;
|
|
34
34
|
--sidebar: #f8f8f9;
|
|
35
35
|
--shadow-pop: 0 8px 24px -4px rgb(0 0 0 / 0.12), 0 2px 6px rgb(0 0 0 / 0.06);
|
|
36
|
+
--backdrop: #18181b;
|
|
36
37
|
--radius: 6px;
|
|
37
38
|
--font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
38
39
|
--font-code: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
@@ -67,5 +68,6 @@
|
|
|
67
68
|
--violet-text: #c4b5fd;
|
|
68
69
|
--sidebar: #121215;
|
|
69
70
|
--shadow-pop: 0 8px 24px -4px rgb(0 0 0 / 0.6), 0 2px 6px rgb(0 0 0 / 0.4);
|
|
71
|
+
--backdrop: #000000;
|
|
70
72
|
}
|
|
71
73
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/ui",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.6",
|
|
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": {
|
|
@@ -36,12 +36,11 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@base-ui/react": "^1.9.0",
|
|
40
39
|
"@dnd-kit/core": "^6.3.1",
|
|
41
40
|
"@dnd-kit/sortable": "^10.0.0",
|
|
42
|
-
"@protobase/client": "0.14.
|
|
43
|
-
"@protobase/layout": "0.14.
|
|
44
|
-
"@protobase/schema": "0.14.
|
|
41
|
+
"@protobase/client": "0.14.6",
|
|
42
|
+
"@protobase/layout": "0.14.6",
|
|
43
|
+
"@protobase/schema": "0.14.6",
|
|
45
44
|
"@sentry/browser": "^11.7.0",
|
|
46
45
|
"@tanstack/react-query": "^5.104.1",
|
|
47
46
|
"@tanstack/react-table": "^9.2.6",
|