@pipelex/mthds-form 0.32.0 → 0.34.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.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/dist/brand/index.js +2 -2
  3. package/dist/{chunk-PCNFELNT.js → chunk-5RV3ASMO.js} +141 -69
  4. package/dist/chunk-5RV3ASMO.js.map +1 -0
  5. package/dist/{chunk-VH5CDQDR.js → chunk-AURDKAIC.js} +3 -3
  6. package/dist/{chunk-VH5CDQDR.js.map → chunk-AURDKAIC.js.map} +1 -1
  7. package/dist/{chunk-ZX52CQJ4.js → chunk-CFBK7NO7.js} +3 -3
  8. package/dist/{chunk-ZX52CQJ4.js.map → chunk-CFBK7NO7.js.map} +1 -1
  9. package/dist/{chunk-3GO65HWP.js → chunk-PNNWNRPG.js} +11 -7
  10. package/dist/chunk-PNNWNRPG.js.map +1 -0
  11. package/dist/{chunk-XO5OENNF.js → chunk-TF4RTKLH.js} +32 -5
  12. package/dist/chunk-TF4RTKLH.js.map +1 -0
  13. package/dist/{chunk-IBBAJXIO.js → chunk-XIWBKV7T.js} +3 -3
  14. package/dist/{chunk-IBBAJXIO.js.map → chunk-XIWBKV7T.js.map} +1 -1
  15. package/dist/{chunk-VBXFGUCG.js → chunk-XYS5KCXB.js} +465 -112
  16. package/dist/chunk-XYS5KCXB.js.map +1 -0
  17. package/dist/core/gate.js +2 -2
  18. package/dist/core/index.js +4 -4
  19. package/dist/core/readiness.d.ts +34 -1
  20. package/dist/core/readiness.js +1 -1
  21. package/dist/core/seed.js +2 -2
  22. package/dist/core/values.js +2 -2
  23. package/dist/{field-renderer-Dz03dpig.d.ts → field-renderer-BYN6YrU-.d.ts} +6 -6
  24. package/dist/generative/headless/index.d.ts +53 -16
  25. package/dist/generative/headless/index.js +3 -2
  26. package/dist/generative/index.d.ts +79 -25
  27. package/dist/generative/index.js +942 -275
  28. package/dist/generative/index.js.map +1 -1
  29. package/dist/react/index.d.ts +56 -29
  30. package/dist/react/index.js +4 -4
  31. package/dist/styles.css +1 -1
  32. package/package.json +1 -1
  33. package/dist/chunk-3GO65HWP.js.map +0 -1
  34. package/dist/chunk-PCNFELNT.js.map +0 -1
  35. package/dist/chunk-VBXFGUCG.js.map +0 -1
  36. package/dist/chunk-XO5OENNF.js.map +0 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@ The input form for MTHDS methods, as a library: a headless kernel that maps the
4
4
 
5
5
  It exists because "the form" is one problem that keeps being solved separately. A method declares its inputs; something has to decide what widget each input deserves, whether the Run button may light up, what shape the values take on the wire, and what a validation failure says to a person. That logic belongs in one place with tests around it, not copied into each surface that happens to need a form.
6
6
 
7
- ## Five entry points
7
+ ## Entry points
8
8
 
9
9
  ```ts
10
10
  import { buildRunFields, computeReadiness } from '@pipelex/mthds-form'; // headless
@@ -1,7 +1,7 @@
1
1
  import { httpUrl, brandManifestSchema } from '../chunk-QGFR57OH.js';
2
2
  export { brandManifestSchema } from '../chunk-QGFR57OH.js';
3
- import { BRAND_CONTRACT, resolveColor, colorIsHex, colorHex, COLOR_TOKEN_NAMES, modeValue, aliasTarget, asWritten, isControlCharacter, validateBrandTokens } from '../chunk-3GO65HWP.js';
4
- export { APP_STYLES, APP_STYLE_IDS, BRAND_CONTRACT, COLOR_TOKEN_NAMES, CONTRAST_PAIRS, MIN_CONTRAST, MIN_CONTROL_CONTRAST, TYPEFACES, colorHex, colorIsHex, contractVariable, contrastRatio, deriveBrandRoles, deriveStyleRoles, isAccentAdjusted, isActionFaint, isAppStyle, isColorTokenName, isTypeface, readableTextOn, resolveColor, resolveDarkSeeds, resolveRoleColor, srgbColorSchema, validateBrandTokens } from '../chunk-3GO65HWP.js';
3
+ import { BRAND_CONTRACT, resolveColor, colorIsHex, colorHex, COLOR_TOKEN_NAMES, modeValue, aliasTarget, asWritten, isControlCharacter, validateBrandTokens } from '../chunk-PNNWNRPG.js';
4
+ export { APP_STYLES, APP_STYLE_IDS, BRAND_CONTRACT, COLOR_TOKEN_NAMES, CONTRAST_PAIRS, MIN_CONTRAST, MIN_CONTROL_CONTRAST, TYPEFACES, colorHex, colorIsHex, contractVariable, contrastRatio, deriveBrandRoles, deriveStyleRoles, isAccentAdjusted, isActionFaint, isAppStyle, isColorTokenName, isTypeface, readableTextOn, resolveColor, resolveDarkSeeds, resolveRoleColor, srgbColorSchema, validateBrandTokens } from '../chunk-PNNWNRPG.js';
5
5
  import { z } from 'zod';
6
6
 
7
7
  var statedHex = z.string().regex(/^#[0-9a-f]{6}$/i, "a stated accent is #rrggbb");
@@ -1,14 +1,14 @@
1
1
  import { planFileSave, planStuffSave, splitFileName, typedFileStem } from './chunk-4VAO6BDE.js';
2
- import { seedInputs, closeOptionalStructures, openOptionalStructures } from './chunk-VH5CDQDR.js';
2
+ import { seedInputs, closeOptionalStructures, openOptionalStructures } from './chunk-AURDKAIC.js';
3
3
  import { sourceFileValue, roomForChosenFiles, roomForDroppedFiles, addChosenFiles, placeDroppedFiles, chosenFilesAdded } from './chunk-L23R3JNQ.js';
4
4
  import { readStuffFile } from './chunk-56WECFBD.js';
5
- import { apiInputsFromRunValues, sameRunValues, runValuesFromInputs, setValueAtPath } from './chunk-ZX52CQJ4.js';
5
+ import { apiInputsFromRunValues, sameRunValues, runValuesFromInputs, setValueAtPath } from './chunk-CFBK7NO7.js';
6
6
  import { enumValueLabeler, humanizeFieldName, humanizeEnumValue } from './chunk-GHVVULHY.js';
7
7
  import { TYPED_SCALAR_MARKERS, viewableUrl, splitCitations, webHref, isNativeDateNode, isNativeHtmlNode, readHtmlContent, isNativeCompositeNode, readCompositeContent, isNativePageNode, nativeVerdictOf, isNativeSearchResultNode, readSearchResultContent, isNativeValueNode, readDateContent, formatDateContent, readPageContent, readYesNoContent, readRatingContent, readChoiceContent, readDocumentContent, readImageContent, readDataUrl, citedSource } from './chunk-QQK6Y55E.js';
8
8
  import { buildRunFields } from './chunk-ZB4RYUKV.js';
9
9
  import { conceptCategory } from './chunk-FABY3DEY.js';
10
10
  import { acceptLabel, acceptMap, isAcceptedFile, normalizeMimeType, formatOfFilename, DOCUMENT_FORMATS, IMAGE_FORMATS } from './chunk-XCO6GTEC.js';
11
- import { shownAsOptional, isFoldedOptional, anyOptionalStructureOpen, isOptionalStructure, computeReadiness, optionalStructureOpen, mustBeFilled, fieldFilled, isFilled } from './chunk-XO5OENNF.js';
11
+ import { shownAsOptional, isFoldedOptional, anyOptionalStructureOpen, isOptionalStructure, computeReadiness, gateRefusal, optionalStructureOpen, mustBeFilled } from './chunk-TF4RTKLH.js';
12
12
  import { ownProp } from './chunk-V3OV2XQT.js';
13
13
  import { toStoredDateValue, toDateInputValue } from './chunk-GKV77RAS.js';
14
14
  import { clsx } from 'clsx';
@@ -84,11 +84,27 @@ function fieldLabel(title, name, presentation) {
84
84
  if (title !== void 0) return title;
85
85
  return presentation === "app" ? humanizeFieldName(name) : name;
86
86
  }
87
+
88
+ // src/react/role-tokens.ts
89
+ var linkTextClass = "text-[color:var(--link,var(--primary,hsl(240_5.9%_10%)))]";
90
+ var selectedFillClass = "bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
91
+ var selectedStateFillClass = "data-[state=on]:bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
92
+ var selectedCheckedFillClass = "aria-checked:bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
93
+ var selectedFillStrongClass = "bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_15%,transparent))]";
94
+ var selectedBorderClass = "border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
95
+ var selectedStateBorderClass = "data-[state=on]:border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
96
+ var selectedHoverBorderClass = "hover:border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
97
+ var checkedAccentClass = "accent-[color:var(--link,var(--primary,hsl(240_5.9%_10%)))]";
98
+ var focusOutlineClass = "focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring";
99
+ var focusWithinOutlineClass = "focus-within:outline-solid focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-ring";
100
+ var focusOutlineInsetClass = "focus-visible:outline-solid focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring";
101
+ var frameFocusOutlineClass = "data-focus-visible:outline-solid data-focus-visible:outline-2 data-focus-visible:-outline-offset-2 data-focus-visible:outline-ring";
87
102
  var Switch = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
88
103
  SwitchPrimitives.Root,
89
104
  {
90
105
  className: cn(
91
- "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-muted-foreground",
106
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-muted-foreground",
107
+ focusOutlineClass,
92
108
  "max-sm:relative max-sm:after:absolute max-sm:after:-inset-x-0.5 max-sm:after:-inset-y-3 max-sm:after:content-['']",
93
109
  className
94
110
  ),
@@ -284,6 +300,7 @@ var EN_FIELD_STRINGS = {
284
300
  optionalInputsCount: (count) => count === 1 ? "1 optional input" : `${count} optional inputs`,
285
301
  requiredField: "Required",
286
302
  incompleteField: "Incomplete: fill in its required fields",
303
+ runWaitsFor: (names, more) => `Fill in ${someNames(names, more)} to run`,
287
304
  uploadFailed: "This file could not be uploaded. Try again.",
288
305
  chooseFromSource: "Choose from your team's files",
289
306
  chooseFromSourceAria: (label) => label ? `Choose from your team's files for ${label}` : "Choose from your team's files",
@@ -469,6 +486,7 @@ var FR_FIELD_STRINGS = {
469
486
  optionalInputsCount: (count) => `${count} ${plural(count, "entr\xE9e facultative", "entr\xE9es facultatives")}`,
470
487
  requiredField: "Obligatoire",
471
488
  incompleteField: "Incomplet\xA0: remplissez ses champs obligatoires",
489
+ runWaitsFor: (names, more) => `Remplissez ${someNames2(names, more)} pour lancer`,
472
490
  uploadFailed: "Ce fichier n\u2019a pas pu \xEAtre envoy\xE9. R\xE9essayez.",
473
491
  chooseFromSource: "Choisir parmi les fichiers de l\u2019\xE9quipe",
474
492
  chooseFromSourceAria: (label) => label ? `Choisir parmi les fichiers de l\u2019\xE9quipe pour ${label}` : "Choisir parmi les fichiers de l\u2019\xE9quipe",
@@ -550,6 +568,7 @@ function FieldStringsProvider({
550
568
  function useFieldStrings() {
551
569
  return useContext(FieldStringsContext);
552
570
  }
571
+ var ERROR_OUTLINE = "rounded-lg outline-solid outline-1 outline-offset-4 outline-destructive";
553
572
  function FieldShell({
554
573
  name,
555
574
  title,
@@ -568,6 +587,7 @@ function FieldShell({
568
587
  const Label3 = htmlFor ? "label" : "div";
569
588
  const labelText = fieldLabel(title, name, presentation);
570
589
  const showLabel = labelText.trim() !== "";
590
+ const outlined = isApp && !!error;
571
591
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
572
592
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
573
593
  showLabel && /* @__PURE__ */ jsx(
@@ -599,10 +619,8 @@ function FieldShell({
599
619
  /* @__PURE__ */ jsx(
600
620
  "div",
601
621
  {
602
- className: cn(
603
- "space-y-2",
604
- isApp && error && "rounded-lg ring-1 ring-destructive/70 ring-offset-4 ring-offset-background"
605
- ),
622
+ "data-error-outline": outlined ? "" : void 0,
623
+ className: cn("space-y-2", outlined && ERROR_OUTLINE),
606
624
  children
607
625
  }
608
626
  ),
@@ -648,20 +666,6 @@ function DateField({ field, value, onChange, id, error, disabled }) {
648
666
  );
649
667
  }
650
668
 
651
- // src/react/role-tokens.ts
652
- var linkTextClass = "text-[color:var(--link,var(--primary,hsl(240_5.9%_10%)))]";
653
- var selectedFillClass = "bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
654
- var selectedStateFillClass = "data-[state=on]:bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
655
- var selectedCheckedFillClass = "aria-checked:bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_10%,transparent))]";
656
- var selectedFillStrongClass = "bg-[color:var(--selected,color-mix(in_oklab,var(--primary,hsl(240_5.9%_10%))_15%,transparent))]";
657
- var selectedBorderClass = "border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
658
- var selectedStateBorderClass = "data-[state=on]:border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
659
- var selectedHoverBorderClass = "hover:border-[color:color-mix(in_oklab,var(--link,var(--primary,hsl(240_5.9%_10%)))_40%,transparent)]";
660
- var checkedAccentClass = "accent-[color:var(--link,var(--primary,hsl(240_5.9%_10%)))]";
661
- var focusOutlineClass = "focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring";
662
- var focusOutlineInsetClass = "focus-visible:outline-solid focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring";
663
- var frameFocusOutlineClass = "data-focus-visible:outline-solid data-focus-visible:outline-2 data-focus-visible:-outline-offset-2 data-focus-visible:outline-ring";
664
-
665
669
  // src/react/encoded-file.ts
666
670
  function encodedFileSummary(url, strings) {
667
671
  const view = readDataUrl(url);
@@ -919,7 +923,8 @@ var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @
919
923
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
920
924
  var toggleVariants = cva(
921
925
  [
922
- "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:text-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2",
926
+ "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:text-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2",
927
+ focusOutlineClass,
923
928
  selectedStateFillClass
924
929
  ],
925
930
  {
@@ -1653,8 +1658,9 @@ function FileField({
1653
1658
  // the visual affordance, and the control inside it is a real
1654
1659
  // `<input type="file">`, which already has the right role and now has a
1655
1660
  // name. Giving the div a `role="button"` of its own would put a second
1656
- // named control in the accessibility tree for one value. The focus ring
1657
- // is `focus-within` because the element that takes focus is clip-hidden.
1661
+ // named control in the accessibility tree for one value. The focus
1662
+ // outline is `focus-within` because the element that takes focus is
1663
+ // clip-hidden.
1658
1664
  /* @__PURE__ */ jsxs(
1659
1665
  "div",
1660
1666
  {
@@ -1662,7 +1668,7 @@ function FileField({
1662
1668
  className: cn(
1663
1669
  "flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed px-4 py-6 text-center",
1664
1670
  "cursor-pointer select-none transition-colors",
1665
- "focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background",
1671
+ focusWithinOutlineClass,
1666
1672
  isDragActive ? "border-primary/60 bg-primary/5" : "border-border bg-input hover:border-border hover:bg-muted",
1667
1673
  busy && "cursor-not-allowed opacity-60"
1668
1674
  ),
@@ -2205,6 +2211,7 @@ function OptionalToggle({ count, expanded, onToggle, noun = "field" }) {
2205
2211
  }
2206
2212
  var StructureDepthContext = createContext(0);
2207
2213
  var FramedFormContext = createContext(false);
2214
+ var RefusedStructureContext = createContext(null);
2208
2215
  function structureGrouping(depth, labelled, framed) {
2209
2216
  if (!labelled) return "none";
2210
2217
  if (depth > 0) return "rule";
@@ -2227,6 +2234,14 @@ function ObjectField({ field, value, onChange, id, error, env }) {
2227
2234
  const label = fieldLabel(field.title, field.name, presentation);
2228
2235
  const grouping = structureGrouping(depth, label.trim() !== "", use(FramedFormContext));
2229
2236
  const domId = useFieldDomId(id);
2237
+ const refused = use(RefusedStructureContext) === id;
2238
+ const s = useFieldStrings();
2239
+ const markOf = (child) => {
2240
+ if (!refused) return void 0;
2241
+ const refusal = gateRefusal(child, ownProp(data, child.name), child.required);
2242
+ if (refusal === "required") return s.requiredField;
2243
+ return refusal === "incomplete" ? s.incompleteField : void 0;
2244
+ };
2230
2245
  const setChild = (name, childValue) => onChange({ ...data, [name]: childValue });
2231
2246
  const folded = field.fields.filter((f) => isFoldedOptional(f, ownProp(data, f.name)));
2232
2247
  const structureOpen = anyOptionalStructureOpen(field.fields, data);
@@ -2266,20 +2281,27 @@ function ObjectField({ field, value, onChange, id, error, env }) {
2266
2281
  grouping === "box" && "rounded-lg border bg-card/40 p-4 max-sm:p-3",
2267
2282
  grouping === "section" && "pt-2",
2268
2283
  grouping === "rule" && "border-l-2 pl-4 max-sm:pl-3",
2269
- (grouping === "box" || grouping === "rule") && (error ? "border-destructive/50" : "border-border")
2284
+ // In error, a card's outline and a rule turn the error colour
2285
+ // itself, which the brand contract holds at 3:1 on the page and on
2286
+ // a card: at half of it they read under that bar in every palette.
2287
+ (grouping === "box" || grouping === "rule") && (error ? "border-destructive" : "border-border")
2270
2288
  ),
2271
2289
  children: [
2272
- /* @__PURE__ */ jsx(StructureDepthContext, { value: depth + 1, children: visible.map((child) => /* @__PURE__ */ jsx(
2273
- FieldRenderer,
2274
- {
2275
- field: child,
2276
- value: ownProp(data, child.name),
2277
- onChange: (v) => setChild(child.name, v),
2278
- id: `${id}.${child.name}`,
2279
- env
2280
- },
2281
- child.name
2282
- )) }),
2290
+ /* @__PURE__ */ jsx(StructureDepthContext, { value: depth + 1, children: visible.map((child) => {
2291
+ const childId = `${id}.${child.name}`;
2292
+ const mark = markOf(child);
2293
+ return /* @__PURE__ */ jsx(RefusedStructureContext, { value: mark ? childId : null, children: /* @__PURE__ */ jsx(
2294
+ FieldRenderer,
2295
+ {
2296
+ field: child,
2297
+ value: ownProp(data, child.name),
2298
+ onChange: (v) => setChild(child.name, v),
2299
+ id: childId,
2300
+ error: mark,
2301
+ env
2302
+ }
2303
+ ) }, child.name);
2304
+ }) }),
2283
2305
  (folded.length > 0 || structureOpen) && /* @__PURE__ */ jsx(
2284
2306
  OptionalToggle,
2285
2307
  {
@@ -2372,7 +2394,7 @@ function ListFileDrop({ label, formats, shut, onPlace }) {
2372
2394
  className: cn(
2373
2395
  "flex flex-col items-center justify-center gap-1 rounded-md border border-dashed px-4 py-4 text-center max-sm:min-h-11",
2374
2396
  "cursor-pointer select-none transition-colors",
2375
- "focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background",
2397
+ focusWithinOutlineClass,
2376
2398
  isDragActive ? "border-primary/60 bg-primary/5" : "border-border bg-input hover:border-border hover:bg-muted",
2377
2399
  shut && "cursor-not-allowed opacity-60"
2378
2400
  ),
@@ -3871,13 +3893,12 @@ function MethodFormFields({
3871
3893
  );
3872
3894
  }
3873
3895
  };
3874
- const errorFor = (field) => {
3896
+ const refusalOf = (field) => attempted ? gateRefusal(field, ownProp(values, field.name), mustBeFilled(field)) : void 0;
3897
+ const errorFor = (field, refusal) => {
3875
3898
  const hostError = errors ? ownProp(errors, field.name) : void 0;
3876
3899
  if (hostError) return hostError;
3877
- if (!attempted) return void 0;
3878
- const value = ownProp(values, field.name);
3879
- if (mustBeFilled(field)) return fieldFilled(field, value) ? void 0 : s.requiredField;
3880
- return isFilled(value) && !fieldFilled(field, value) ? s.incompleteField : void 0;
3900
+ if (refusal === "required") return s.requiredField;
3901
+ return refusal === "incomplete" ? s.incompleteField : void 0;
3881
3902
  };
3882
3903
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", framed && SECTION_RULES, className), children: [
3883
3904
  exampleSource && /* @__PURE__ */ jsx(
@@ -3890,18 +3911,33 @@ function MethodFormFields({
3890
3911
  disabled
3891
3912
  }
3892
3913
  ),
3893
- visible.map((field) => /* @__PURE__ */ jsx(
3894
- FieldRenderer,
3895
- {
3896
- field,
3897
- id: field.name,
3898
- value: ownProp(values, field.name),
3899
- error: errorFor(field),
3900
- env,
3901
- onChange: (next) => setValues((previous) => ({ ...previous, [field.name]: next }))
3902
- },
3903
- `${field.name}:${resets}`
3904
- )),
3914
+ visible.map((field) => {
3915
+ const refusal = refusalOf(field);
3916
+ return (
3917
+ // Remounted on each reset, so no control keeps what it held for the
3918
+ // values the reset replaced (a file still arriving, a failed drop). A
3919
+ // structure the gate refuses marks the members it refuses, whatever
3920
+ // a host's message says of the structure.
3921
+ /* @__PURE__ */ jsx(
3922
+ RefusedStructureContext,
3923
+ {
3924
+ value: refusal ? field.name : null,
3925
+ children: /* @__PURE__ */ jsx(
3926
+ FieldRenderer,
3927
+ {
3928
+ field,
3929
+ id: field.name,
3930
+ value: ownProp(values, field.name),
3931
+ error: errorFor(field, refusal),
3932
+ env,
3933
+ onChange: (next) => setValues((previous) => ({ ...previous, [field.name]: next }))
3934
+ }
3935
+ )
3936
+ },
3937
+ `${field.name}:${resets}`
3938
+ )
3939
+ );
3940
+ }),
3905
3941
  (folded.length > 0 || structureOpen) && /* @__PURE__ */ jsx(OptionalToggle, { count: folded.length, expanded, onToggle: toggle, noun: "input" })
3906
3942
  ] });
3907
3943
  }
@@ -4254,6 +4290,7 @@ function ResultEnvProvider({
4254
4290
  saveFiles,
4255
4291
  downloads,
4256
4292
  renderPdf,
4293
+ framed,
4257
4294
  children
4258
4295
  }) {
4259
4296
  const env = useMemo(
@@ -4267,7 +4304,8 @@ function ResultEnvProvider({
4267
4304
  tableLayout,
4268
4305
  saveFiles,
4269
4306
  downloads,
4270
- renderPdf
4307
+ renderPdf,
4308
+ framed
4271
4309
  }),
4272
4310
  [
4273
4311
  resolveUrl,
@@ -4279,7 +4317,8 @@ function ResultEnvProvider({
4279
4317
  tableLayout,
4280
4318
  saveFiles,
4281
4319
  downloads,
4282
- renderPdf
4320
+ renderPdf,
4321
+ framed
4283
4322
  ]
4284
4323
  );
4285
4324
  return /* @__PURE__ */ jsx(ResultEnvContext, { value: env, children });
@@ -4287,6 +4326,7 @@ function ResultEnvProvider({
4287
4326
  function PanelEnvOverride({
4288
4327
  downloads,
4289
4328
  tableLayout,
4329
+ framed,
4290
4330
  children
4291
4331
  }) {
4292
4332
  const env = use(ResultEnvContext);
@@ -4296,10 +4336,11 @@ function PanelEnvOverride({
4296
4336
  const askFileName = downloads?.askFileName;
4297
4337
  const merged = useMemo(() => {
4298
4338
  const ownDownloads = result !== void 0 || files !== void 0 || pdf !== void 0 || askFileName !== void 0;
4299
- if (!ownDownloads && tableLayout === void 0) return env;
4339
+ if (!ownDownloads && tableLayout === void 0 && framed === void 0) return env;
4300
4340
  return {
4301
4341
  ...env,
4302
4342
  ...tableLayout === void 0 ? {} : { tableLayout },
4343
+ ...framed === void 0 ? {} : { framed },
4303
4344
  ...ownDownloads ? {
4304
4345
  downloads: {
4305
4346
  result: result ?? env.downloads?.result,
@@ -4309,7 +4350,7 @@ function PanelEnvOverride({
4309
4350
  }
4310
4351
  } : {}
4311
4352
  };
4312
- }, [env, result, files, pdf, askFileName, tableLayout]);
4353
+ }, [env, result, files, pdf, askFileName, tableLayout, framed]);
4313
4354
  return /* @__PURE__ */ jsx(ResultEnvContext, { value: merged, children });
4314
4355
  }
4315
4356
  function useResolvedUrl(url) {
@@ -4380,6 +4421,9 @@ function useTableColumns() {
4380
4421
  function useTableLayout() {
4381
4422
  return use(ResultEnvContext).tableLayout ?? "scroll";
4382
4423
  }
4424
+ function useResultFramed() {
4425
+ return use(ResultEnvContext).framed ?? false;
4426
+ }
4383
4427
  var OverlayLayerContext = createContext(null);
4384
4428
  function OverlayLayer({ children }) {
4385
4429
  const outer = use(OverlayLayerContext);
@@ -7464,6 +7508,9 @@ function stackingFor(columns, rowsOpen) {
7464
7508
  }
7465
7509
  return columns > STACK_ALWAYS_BEYOND ? "always" : "narrow";
7466
7510
  }
7511
+ function useTableBox() {
7512
+ return useResultFramed() ? { name: "framed", className: "rounded-md" } : { name: "box", className: "rounded-lg border border-border" };
7513
+ }
7467
7514
  var STACKED = {
7468
7515
  phone: {
7469
7516
  table: "max-sm:block",
@@ -7567,6 +7614,7 @@ function ObjectTable({
7567
7614
  const presentation = useFieldPresentation();
7568
7615
  const budget = useTableColumns();
7569
7616
  const layout = useTableLayout();
7617
+ const box = useTableBox();
7570
7618
  const scrollerRef = useRef(null);
7571
7619
  const [expanded, setExpanded] = useState(() => /* @__PURE__ */ new Set());
7572
7620
  const [viewportWidth, setViewportWidth] = useState();
@@ -7637,8 +7685,10 @@ function ObjectTable({
7637
7685
  role: "group",
7638
7686
  "aria-label": label,
7639
7687
  ...fits && !overflows ? {} : { tabIndex: 0 },
7688
+ "data-table-box": box.name,
7640
7689
  className: cn(
7641
- "overflow-x-auto rounded-lg border border-border",
7690
+ "overflow-x-auto",
7691
+ box.className,
7642
7692
  focusOutlineInsetClass,
7643
7693
  EXPAND_COLUMN_WIDTH,
7644
7694
  fits && "@container"
@@ -7716,7 +7766,15 @@ function ObjectTable({
7716
7766
  width: canExpand ? `calc(${viewportWidth}px - ${EXPAND_COLUMN})` : viewportWidth
7717
7767
  }
7718
7768
  } : {},
7719
- children: /* @__PURE__ */ jsx(ResultField, { field: element, value: item, hideLabel: true })
7769
+ children: /* @__PURE__ */ jsx(
7770
+ PanelEnvOverride,
7771
+ {
7772
+ downloads: void 0,
7773
+ tableLayout: void 0,
7774
+ framed: false,
7775
+ children: /* @__PURE__ */ jsx(ResultField, { field: element, value: item, hideLabel: true })
7776
+ }
7777
+ )
7720
7778
  }
7721
7779
  ) }) : shown.map((column) => {
7722
7780
  const cell = typeof item === "object" && item !== null ? ownProp(item, column.name) : void 0;
@@ -7899,6 +7957,7 @@ function RecordsTable({
7899
7957
  }) {
7900
7958
  const presentation = useFieldPresentation();
7901
7959
  const isApp = presentation === "app";
7960
+ const box = useTableBox();
7902
7961
  const columns = [];
7903
7962
  for (const item of items) {
7904
7963
  for (const key of Object.keys(item)) if (!columns.includes(key)) columns.push(key);
@@ -7910,7 +7969,8 @@ function RecordsTable({
7910
7969
  role: "group",
7911
7970
  "aria-label": label,
7912
7971
  tabIndex: 0,
7913
- className: cn("overflow-x-auto rounded-lg border border-border", focusOutlineClass),
7972
+ "data-table-box": box.name,
7973
+ className: cn("overflow-x-auto", box.className, focusOutlineClass),
7914
7974
  children: /* @__PURE__ */ jsxs("table", { className: "min-w-full border-collapse text-[12.5px] text-foreground", children: [
7915
7975
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: "border-b border-border bg-card/40", children: columns.map((column) => /* @__PURE__ */ jsx(
7916
7976
  "th",
@@ -7926,7 +7986,19 @@ function RecordsTable({
7926
7986
  )) }) }),
7927
7987
  /* @__PURE__ */ jsx("tbody", { children: items.map((item, index) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border/60 last:border-b-0", children: columns.map((column) => {
7928
7988
  const cell = ownProp(item, column);
7929
- return /* @__PURE__ */ jsx("td", { className: "px-2.5 py-1.5 align-top", children: typeof cell === "boolean" ? /* @__PURE__ */ jsx(Bool, { value: cell }) : typeof cell === "object" && cell !== null ? /* @__PURE__ */ jsx(NativeValue, { value: cell, label: columnLabel(column) }) : /* @__PURE__ */ jsx(Scalar, { value: cell }) }, column);
7989
+ return /* @__PURE__ */ jsx("td", { className: "px-2.5 py-1.5 align-top", children: typeof cell === "boolean" ? /* @__PURE__ */ jsx(Bool, { value: cell }) : typeof cell === "object" && cell !== null ? (
7990
+ // Out of the host's panel, as far as a table in the
7991
+ // cell knows, since this table is what frames it.
7992
+ /* @__PURE__ */ jsx(
7993
+ PanelEnvOverride,
7994
+ {
7995
+ downloads: void 0,
7996
+ tableLayout: void 0,
7997
+ framed: false,
7998
+ children: /* @__PURE__ */ jsx(NativeValue, { value: cell, label: columnLabel(column) })
7999
+ }
8000
+ )
8001
+ ) : /* @__PURE__ */ jsx(Scalar, { value: cell }) }, column);
7930
8002
  }) }, index)) })
7931
8003
  ] })
7932
8004
  }
@@ -8557,8 +8629,8 @@ function resultKey(field, baseName, value) {
8557
8629
  return void 0;
8558
8630
  }
8559
8631
  }
8560
- function StuffViewer({ downloads, tableLayout, ...props }) {
8561
- return /* @__PURE__ */ jsx(PanelEnvOverride, { downloads, tableLayout, children: /* @__PURE__ */ jsx(StuffPanel, { ...props }) });
8632
+ function StuffViewer({ downloads, tableLayout, framed, ...props }) {
8633
+ return /* @__PURE__ */ jsx(PanelEnvOverride, { downloads, tableLayout, framed, children: /* @__PURE__ */ jsx(StuffPanel, { ...props }) });
8562
8634
  }
8563
8635
  function StuffPanel({
8564
8636
  field,
@@ -8739,6 +8811,6 @@ function pdfFileName(field, value, baseName) {
8739
8811
  return name === void 0 ? "" : name.replace(/\.[^.]+$/, "");
8740
8812
  }
8741
8813
 
8742
- export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EN_FIELD_STRINGS, EnumField, FIELD_STRINGS_BY_LOCALE, FR_FIELD_STRINGS, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, FilePicker, FilePickerEntry, FillWithExample, HtmlPreview, ImageField, JsonView, ListField, Markdown, MethodForm, NumberField, ObjectField, OptionalToggle, PdfDownloadButton, ProseField, ResultEnvProvider, ResultField, ResultRoot, SUPPORTED_LOCALES, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StuffViewer, Switch, TextField, ToggleGroup, ToggleGroupItem, UnknownField, actionShadowClass, checkedAccentClass, cn, enumLabeler, fieldControlClass, fieldStringsFor, focusOutlineClass, headingClass, isThenable, linkTextClass, panelFlatShadowClass, panelRaisedShadowClass, panelSurfaceClass, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, selectedBorderClass, selectedFillClass, selectedFillStrongClass, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveRendition, useResolveShareUrl, useResolveUrl, useResolvedUrl };
8743
- //# sourceMappingURL=chunk-PCNFELNT.js.map
8744
- //# sourceMappingURL=chunk-PCNFELNT.js.map
8814
+ export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EN_FIELD_STRINGS, EnumField, FIELD_STRINGS_BY_LOCALE, FR_FIELD_STRINGS, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, FilePicker, FilePickerEntry, FillWithExample, HtmlPreview, ImageField, JsonView, ListField, Markdown, MethodForm, NumberField, ObjectField, OptionalToggle, PdfDownloadButton, ProseField, ResultEnvProvider, ResultField, ResultRoot, SUPPORTED_LOCALES, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StuffViewer, Switch, TextField, ToggleGroup, ToggleGroupItem, UnknownField, actionShadowClass, checkedAccentClass, cn, enumLabeler, fieldControlClass, fieldLabel, fieldStringsFor, focusOutlineClass, headingClass, isThenable, linkTextClass, panelFlatShadowClass, panelRaisedShadowClass, panelSurfaceClass, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, selectedBorderClass, selectedFillClass, selectedFillStrongClass, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveRendition, useResolveShareUrl, useResolveUrl, useResolvedUrl };
8815
+ //# sourceMappingURL=chunk-5RV3ASMO.js.map
8816
+ //# sourceMappingURL=chunk-5RV3ASMO.js.map