@pipelex/mthds-form 0.6.0 → 0.7.0

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.
@@ -247,6 +247,26 @@ type StuffViewerView = 'rendered' | 'json';
247
247
  interface StuffViewerProps {
248
248
  field: RunField;
249
249
  value: unknown;
250
+ /**
251
+ * The STUFF's name, for the header — `report_pages`, not `output`.
252
+ *
253
+ * A result descriptor's root node is named by the engine that built it, and
254
+ * `build_output_form` calls it `output` for every pipe there has ever been.
255
+ * That is correct in the artifact: the descriptor describes a pipe's output
256
+ * slot, which has no name of its own. It is wrong on screen, where the reader
257
+ * is looking at ONE data item and every other surface — the graph node they
258
+ * clicked, the input panel beside it, the method's own code — calls that item
259
+ * by the name the author gave it.
260
+ *
261
+ * So the name comes from the caller, because only the caller knows it: the
262
+ * graph knows which node was opened, a run page knows which variable it is
263
+ * showing. Absent, the descriptor's own name stands, which keeps a host that
264
+ * has nothing better to say honest rather than blank.
265
+ *
266
+ * It also supplies `downloadBaseName`'s default, so the file a reader saves
267
+ * is named after the thing they were reading rather than `output.json`.
268
+ */
269
+ name?: string;
250
270
  /** Which view opens first. Rendered, unless a host has a reason. */
251
271
  defaultView?: StuffViewerView;
252
272
  /**
@@ -276,7 +296,7 @@ interface StuffViewerProps {
276
296
  declare function JsonView({ value }: {
277
297
  value: unknown;
278
298
  }): react.JSX.Element;
279
- declare function StuffViewer({ field, value, defaultView, downloadBaseName, hideDownload, className, }: StuffViewerProps): react.JSX.Element;
299
+ declare function StuffViewer({ field, value, name, defaultView, downloadBaseName, hideDownload, className, }: StuffViewerProps): react.JSX.Element;
280
300
 
281
301
  /** How a host turns a stored reference into something fetchable. */
282
302
  type ResolveForDownload = (url: string) => string | undefined;
@@ -2062,14 +2062,22 @@ function LoadingImage({ src, alt, className }) {
2062
2062
  ] });
2063
2063
  }
2064
2064
  function ScalarChips({ field, items }) {
2065
- return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: items.map((item, index) => /* @__PURE__ */ jsx(
2066
- "span",
2067
- {
2068
- className: "rounded-md border border-border bg-card/40 px-2 py-0.5 text-[12.5px] text-foreground",
2069
- children: /* @__PURE__ */ jsx(LeafValue, { field, value: item })
2070
- },
2071
- index
2072
- )) });
2065
+ return (
2066
+ // `data-chips` is the hook the definition grid's value cell reaches through:
2067
+ // `text-right` has no effect on flex children, so a row of tags would keep
2068
+ // starting under its label while every value beside it ended at the right
2069
+ // edge. The attribute keeps that one selector out of this component's own
2070
+ // class list - chips are laid out the same way everywhere, and only the
2071
+ // caller knows which edge they should end on.
2072
+ /* @__PURE__ */ jsx("div", { "data-chips": true, className: "flex flex-wrap gap-1.5", children: items.map((item, index) => /* @__PURE__ */ jsx(
2073
+ "span",
2074
+ {
2075
+ className: "rounded-md border border-border bg-card/40 px-2 py-0.5 text-[12.5px] text-foreground",
2076
+ children: /* @__PURE__ */ jsx(LeafValue, { field, value: item })
2077
+ },
2078
+ index
2079
+ )) })
2080
+ );
2073
2081
  }
2074
2082
  function ItemCount({ count }) {
2075
2083
  const s = useFieldStrings();
@@ -2080,6 +2088,7 @@ function isInlineColumn(field) {
2080
2088
  return TABULAR_KINDS.has(field.kind);
2081
2089
  }
2082
2090
  var CELL_LENGTH_LIMIT = 80;
2091
+ var EXPAND_COLUMN = "2rem";
2083
2092
  function fitsACellWhole(field) {
2084
2093
  switch (field.kind) {
2085
2094
  case "boolean":
@@ -2148,9 +2157,9 @@ function ObjectTable({
2148
2157
  "aria-label": label,
2149
2158
  tabIndex: 0,
2150
2159
  className: "overflow-x-auto rounded-lg border border-border",
2151
- children: /* @__PURE__ */ jsxs("table", { className: "min-w-full border-collapse text-[13px]", children: [
2152
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border bg-card/40 text-left", children: [
2153
- canExpand && /* @__PURE__ */ jsx("th", { scope: "col", className: "w-8 px-1", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: s.rowDetailsColumn }) }),
2160
+ children: /* @__PURE__ */ jsxs("table", { className: "w-full min-w-full border-collapse text-[13px]", children: [
2161
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border bg-muted text-left", children: [
2162
+ canExpand && /* @__PURE__ */ jsx("th", { scope: "col", style: { width: EXPAND_COLUMN }, className: "px-1", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: s.rowDetailsColumn }) }),
2154
2163
  columns.map((column) => /* @__PURE__ */ jsx(
2155
2164
  "th",
2156
2165
  {
@@ -2182,7 +2191,15 @@ function ObjectTable({
2182
2191
  "div",
2183
2192
  {
2184
2193
  className: "sticky left-0 px-3.5 py-3",
2185
- ...viewportWidth ? { style: { width: viewportWidth } } : {},
2194
+ ...viewportWidth ? {
2195
+ style: {
2196
+ // Minus the chevron column: this cell starts
2197
+ // after it, so pinning it to the FULL visible
2198
+ // width pushes its right edge that far past the
2199
+ // scroller. See `EXPAND_COLUMN`.
2200
+ width: canExpand ? `calc(${viewportWidth}px - ${EXPAND_COLUMN})` : viewportWidth
2201
+ }
2202
+ } : {},
2186
2203
  children: /* @__PURE__ */ jsx(ResultField, { field: element, value: item, hideLabel: true })
2187
2204
  }
2188
2205
  ) }) : columns.map((column) => {
@@ -2326,7 +2343,7 @@ function ResultField({ field, value, depth = 0, hideLabel = false }) {
2326
2343
  // longest label left over.
2327
2344
  isInlineColumn(child) ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
2328
2345
  /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(Label2, { field: child, describe: true }) }),
2329
- /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(LeafValue, { field: child, value: memberValue(child) }) })
2346
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 text-right [&_[data-chips]]:justify-end", children: /* @__PURE__ */ jsx(LeafValue, { field: child, value: memberValue(child) }) })
2330
2347
  ] }, child.name) : /* @__PURE__ */ jsx("div", { className: "col-span-2 min-w-0", children: /* @__PURE__ */ jsx(ResultField, { field: child, value: memberValue(child), depth: depth + 1 }) }, child.name)
2331
2348
  )
2332
2349
  )
@@ -2521,12 +2538,14 @@ function JsonView({ value }) {
2521
2538
  function StuffViewer({
2522
2539
  field,
2523
2540
  value,
2541
+ name,
2524
2542
  defaultView = "rendered",
2525
2543
  downloadBaseName,
2526
2544
  hideDownload = false,
2527
2545
  className
2528
2546
  }) {
2529
2547
  const s = useFieldStrings();
2548
+ const named = name ? { ...field, name } : field;
2530
2549
  const [view, setView] = useState(defaultView);
2531
2550
  const [saving, setSaving] = useState(false);
2532
2551
  const resolveUrl = useResolveUrl();
@@ -2536,20 +2555,20 @@ function StuffViewer({
2536
2555
  await downloadStuff({
2537
2556
  field,
2538
2557
  value,
2539
- baseName: downloadBaseName ?? field.name ?? "result",
2558
+ baseName: downloadBaseName ?? named.name ?? "result",
2540
2559
  resolveUrl
2541
2560
  });
2542
2561
  } finally {
2543
2562
  setSaving(false);
2544
2563
  }
2545
- }, [field, value, downloadBaseName, resolveUrl]);
2564
+ }, [field, named.name, value, downloadBaseName, resolveUrl]);
2546
2565
  const views = [
2547
2566
  { id: "rendered", label: s.viewRendered },
2548
2567
  { id: "json", label: s.viewJson }
2549
2568
  ];
2550
2569
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
2551
2570
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-x-4 gap-y-1", children: [
2552
- /* @__PURE__ */ jsx("div", { className: "min-w-0 space-y-1", children: /* @__PURE__ */ jsx(ResultHeader, { field }) }),
2571
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 space-y-1", children: /* @__PURE__ */ jsx(ResultHeader, { field: named }) }),
2553
2572
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
2554
2573
  !hideDownload && /* @__PURE__ */ jsxs(
2555
2574
  "button",