@savvifi/meridian-web-react 0.3.0 → 0.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvifi/meridian-web-react",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "description": "React adapter for the meridian WebRenderer seam: a kit-agnostic core (MeridianProvider, PanelRenderer, ComponentKit, reactWebRenderer) that renders meridian.ui.v1 PanelDescriptors through a swappable ComponentKit (MUI, shadcn, \u2026). The premium web renderer tier of the meridian renderer family.",
6
6
  "publishConfig": {
@@ -34,6 +34,8 @@ export interface PagedTable {
34
34
  goNext: () => void;
35
35
  /** Jump to a page (OFFSET only; no-op otherwise). */
36
36
  setPage: (page: number) => void;
37
+ /** True when the populate RPC rejected — so the kit shows an error, not "no data". */
38
+ error: boolean;
37
39
  }
38
40
  /**
39
41
  * Fetch + page a TablePanel's rows through the invoker. CLIENT returns all rows
package/src/pagination.js CHANGED
@@ -99,6 +99,7 @@ export function usePagedRows(panel, invoker) {
99
99
  const [total, setTotal] = useState(undefined);
100
100
  const [nextCursor, setNextCursor] = useState(undefined);
101
101
  const [loading, setLoading] = useState(Boolean(panel.populate));
102
+ const [error, setError] = useState(false);
102
103
  // Reset paging when the panel identity changes.
103
104
  useEffect(() => {
104
105
  setPageState(0);
@@ -111,6 +112,7 @@ export function usePagedRows(panel, invoker) {
111
112
  }
112
113
  let cancelled = false;
113
114
  setLoading(true);
115
+ setError(false);
114
116
  const cursor = mode === PaginationMode.CURSOR ? cursorStack[page] ?? "" : undefined;
115
117
  const request = mode === PaginationMode.CLIENT
116
118
  ? {}
@@ -126,8 +128,12 @@ export function usePagedRows(panel, invoker) {
126
128
  setNextCursor(read.nextCursor);
127
129
  })
128
130
  .catch(() => {
129
- if (!cancelled)
131
+ // Surface the failure — a table that shows "no data" on a failed fetch is
132
+ // a UI mishap (the user reads it as "there are none").
133
+ if (!cancelled) {
130
134
  setRows([]);
135
+ setError(true);
136
+ }
131
137
  })
132
138
  .finally(() => {
133
139
  if (!cancelled)
@@ -165,5 +171,5 @@ export function usePagedRows(panel, invoker) {
165
171
  if (mode === PaginationMode.OFFSET)
166
172
  setPageState(Math.max(0, target));
167
173
  };
168
- return { mode, pageSize, rows, loading, page, total, hasPrev, hasNext, goNext, goPrev, setPage };
174
+ return { mode, pageSize, rows, loading, error, page, total, hasPrev, hasNext, goNext, goPrev, setPage };
169
175
  }
@@ -61,11 +61,39 @@ export function ViewRenderer({ view }) {
61
61
  function TabbedSlots({ slots }) {
62
62
  const [active, setActive] = useState(0);
63
63
  const ordered = [...slots].sort((a, b) => (a.placement?.tabPosition || 0) - (b.placement?.tabPosition || 0));
64
- return (_jsxs("div", { className: "mer-tabs", children: [_jsx("div", { className: "mer-tabstrip", role: "tablist", children: ordered.map((s, i) => (_jsx("button", { type: "button", role: "tab", "aria-selected": i === active, className: i === active ? "mer-tab active" : "mer-tab", onClick: () => setActive(i), children: s.placement?.tabLabel || s.title || s.id }, s.id))) }), ordered[active] ? _jsx(SlotView, { slot: ordered[active] }) : null] }));
64
+ return (_jsxs("div", { className: "mer-tabs", children: [_jsx("div", { className: "mer-tabstrip", role: "tablist",
65
+ // Structural + affordance styling (kit-neutral). Colors read the --mer-*
66
+ // theme vars a kit exposes (MeridianMuiProvider / htmlKit set these),
67
+ // falling back to sensible defaults so tabs look like tabs in any kit.
68
+ style: {
69
+ display: "flex",
70
+ gap: 4,
71
+ borderBottom: "1px solid var(--mer-border, #e0e0e0)",
72
+ marginBottom: 16,
73
+ }, children: ordered.map((s, i) => {
74
+ const isActive = i === active;
75
+ return (_jsx("button", { type: "button", role: "tab", "aria-selected": isActive, className: isActive ? "mer-tab active" : "mer-tab", onClick: () => setActive(i), style: {
76
+ appearance: "none",
77
+ background: "transparent",
78
+ border: "none",
79
+ cursor: "pointer",
80
+ padding: "8px 14px",
81
+ fontSize: 14,
82
+ fontFamily: "inherit",
83
+ color: isActive ? "var(--mer-accent, #1976d2)" : "var(--mer-fg, inherit)",
84
+ fontWeight: isActive ? 600 : 400,
85
+ borderBottom: isActive
86
+ ? "2px solid var(--mer-accent, #1976d2)"
87
+ : "2px solid transparent",
88
+ marginBottom: "-1px",
89
+ }, children: s.placement?.tabLabel || s.title || s.id }, s.id));
90
+ }) }), ordered[active] ? _jsx(SlotView, { slot: ordered[active] }) : null] }));
65
91
  }
66
92
  function TwoColumnSlots({ slots }) {
67
93
  // Column.COLUMN_SIDEBAR = 2; everything else (main / unspecified) is main.
68
94
  const sidebar = slots.filter((s) => s.placement?.column === 2);
69
95
  const main = slots.filter((s) => s.placement?.column !== 2);
70
- return (_jsxs("div", { className: "mer-two-column", children: [_jsx("div", { className: "mer-col-main", children: main.map((s) => (_jsx(SlotView, { slot: s }, s.id))) }), _jsx("aside", { className: "mer-col-sidebar", children: sidebar.map((s) => (_jsx(SlotView, { slot: s }, s.id))) })] }));
96
+ // Structural flex (kit-neutral): main + sidebar sit side by side, wrapping to
97
+ // stacked on narrow viewports. Without this the columns would stack always.
98
+ return (_jsxs("div", { className: "mer-two-column", style: { display: "flex", gap: 24, alignItems: "flex-start", flexWrap: "wrap" }, children: [_jsx("div", { className: "mer-col-main", style: { flex: "2 1 320px", minWidth: 0 }, children: main.map((s) => (_jsx(SlotView, { slot: s }, s.id))) }), _jsx("aside", { className: "mer-col-sidebar", style: { flex: "1 1 240px", minWidth: 0 }, children: sidebar.map((s) => (_jsx(SlotView, { slot: s }, s.id))) })] }));
71
99
  }