@ashley-shrok/viewmodel-shell 0.4.5 → 0.4.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.
Files changed (2) hide show
  1. package/dist/tui.js +13 -4
  2. package/package.json +1 -1
package/dist/tui.js CHANGED
@@ -12,6 +12,7 @@ const NO_CTX = {
12
12
  copiedKey: null,
13
13
  focusKey: () => undefined,
14
14
  interactive: false,
15
+ fill: false,
15
16
  draft: () => undefined,
16
17
  };
17
18
  /** OSC 52 clipboard write — the terminal-native analog of the clipboard API.
@@ -987,6 +988,7 @@ function App(props) {
987
988
  copiedKey,
988
989
  focusKey: (o) => map.get(o),
989
990
  interactive,
991
+ fill: fillViewport,
990
992
  draft: (k) => draftFor(k),
991
993
  onFieldChange: (k, v) => setDraft((s) => ({ ...s, [k]: v })),
992
994
  onFieldSubmit,
@@ -1245,9 +1247,16 @@ export class TuiAdapter {
1245
1247
  layoutContainer(layout, children, density, rctx) {
1246
1248
  const sp = this.spacing(density);
1247
1249
  const kids = (children ?? []).map((c, i) => this.renderNode(c, this.keyOf(c, i), density, undefined, rctx));
1250
+ // 0.4.6 — when filling a real terminal, the layout spine must carry the
1251
+ // terminal width into the panes. Probed fact: Yoga align-stretch ALONE
1252
+ // does NOT fill here; an explicit width:"100%" on the content wrapper
1253
+ // does. `cards` is intentionally excluded (a uniform small-tile grid by
1254
+ // design — force-filling defeats the preset). fill=false on the static /
1255
+ // non-TTY path ⇒ {} ⇒ byte-identical to pre-0.4.6.
1256
+ const fillW = rctx.fill ? { width: "100%" } : {};
1248
1257
  switch (layout) {
1249
1258
  case "split":
1250
- return (_jsx(Box, { flexDirection: "row", gap: sp.gap || 1, children: kids.map((el, i) => (_jsx(Box, { flexGrow: 1, flexShrink: 1, flexBasis: 0, children: el }, i))) }));
1259
+ return (_jsx(Box, { flexDirection: "row", gap: sp.gap || 1, ...fillW, children: kids.map((el, i) => (_jsx(Box, { flexGrow: 1, flexShrink: 1, flexBasis: 0, children: rctx.fill ? (_jsx(Box, { width: "100%", flexDirection: "column", children: el })) : (el) }, i))) }));
1251
1260
  case "cards":
1252
1261
  return (_jsx(Box, { flexDirection: "row", flexWrap: "wrap", gap: sp.gap || 1, children: kids.map((el, i) => (_jsx(Box, { flexGrow: 0, flexShrink: 1, flexBasis: 28, minWidth: 20, children: el }, i))) }));
1253
1262
  case "sidebar": {
@@ -1257,10 +1266,10 @@ export class TuiAdapter {
1257
1266
  if (rest.length === 0) {
1258
1267
  return (_jsx(Box, { flexShrink: 0, flexBasis: 24, minWidth: 18, children: rail }));
1259
1268
  }
1260
- return (_jsxs(Box, { flexDirection: "row", gap: sp.gap || 1, children: [_jsx(Box, { flexShrink: 0, flexBasis: 24, minWidth: 18, children: rail }), _jsx(Box, { flexGrow: 1, flexShrink: 1, flexBasis: 0, children: _jsx(Box, { flexDirection: "column", gap: sp.gap, children: rest }) })] }));
1269
+ return (_jsxs(Box, { flexDirection: "row", gap: sp.gap || 1, ...fillW, children: [_jsx(Box, { flexShrink: 0, flexBasis: 24, minWidth: 18, children: rail }), _jsx(Box, { flexGrow: 1, flexShrink: 1, flexBasis: 0, children: _jsx(Box, { flexDirection: "column", gap: sp.gap, ...fillW, children: rest }) })] }));
1261
1270
  }
1262
1271
  default: // "stack" / undefined
1263
- return (_jsx(Box, { flexDirection: "column", gap: sp.gap, children: kids }));
1272
+ return (_jsx(Box, { flexDirection: "column", gap: sp.gap, ...fillW, children: kids }));
1264
1273
  }
1265
1274
  }
1266
1275
  // ── the node switch ──────────────────────────────────────────────────────
@@ -1269,7 +1278,7 @@ export class TuiAdapter {
1269
1278
  case "page": {
1270
1279
  const d = node.density === "compact" ? "compact" : "comfortable";
1271
1280
  const sp = this.spacing(d);
1272
- return (_jsxs(Box, { flexDirection: "column", gap: sp.gap, children: [node.title ? (_jsx(Box, { children: _jsx(Text, { bold: true, underline: true, children: node.title }) })) : null, this.layoutContainer(node.layout, node.children ?? [], d, rctx)] }, key));
1281
+ return (_jsxs(Box, { flexDirection: "column", gap: sp.gap, ...(rctx.fill ? { width: "100%", flexGrow: 1 } : {}), children: [node.title ? (_jsx(Box, { children: _jsx(Text, { bold: true, underline: true, children: node.title }) })) : null, this.layoutContainer(node.layout, node.children ?? [], d, rctx)] }, key));
1273
1282
  }
1274
1283
  case "section": {
1275
1284
  const sp = this.spacing(density);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ashley-shrok/viewmodel-shell",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "A server-driven UI framework where the wire format is structured enough that agents can build full-stack apps without ever opening a browser and all UI tests are pure unit tests with no browser runtime. Server returns a JSON tree of typed nodes; a thin TypeScript adapter renders it to DOM. Backend-agnostic — a .NET reference backend ships with the repo, but any language can produce the JSON contract.",
5
5
  "type": "module",
6
6
  "license": "MIT",