@ogygie/ui 0.17.0 → 0.18.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ogygie/ui",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "Ogygie front socle: the five prescribed patterns (DataTable, EmptyState, ErrorBanner, ContractForm, VarianceChart), one screen-state component (ScreenState), fetchContract and EditableText. Ships TypeScript sources — Ogygie products run Vite/tsx/vitest by construction (D1); a product imports them, it no longer copies them (D39).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,7 +19,7 @@
19
19
  "./variance-chart": "./src/VarianceChart.tsx"
20
20
  },
21
21
  "dependencies": {
22
- "@ogygie/core": "0.17.0"
22
+ "@ogygie/core": "0.18.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "@tanstack/react-table": "^9.0.0",
@@ -110,6 +110,12 @@ describe("ContractForm", () => {
110
110
  expect(onCancel).toHaveBeenCalledTimes(1);
111
111
  });
112
112
 
113
+ it("ÉTANT DONNÉ controls ALORS un texte sans borne se saisit dans un textarea quand la vue le demande", () => {
114
+ const Import = z.object({ csv: z.string().min(1) });
115
+ render(<ContractForm schema={Import} onSubmit={() => undefined} submitLabel="Import" labels={{ csv: "CSV" }} controls={{ csv: "textarea" }} />);
116
+ expect(screen.getByLabelText(/CSV/).tagName).toBe("TEXTAREA");
117
+ });
118
+
113
119
  it("ÉTANT DONNÉ resetOnSubmit ALORS le formulaire se vide après une soumission acceptée", async () => {
114
120
  const Simple = z.object({ label: z.string().min(1) });
115
121
  render(<ContractForm schema={Simple} onSubmit={() => undefined} submitLabel="Create" resetOnSubmit />);
@@ -34,6 +34,8 @@ export interface ContractFormProps<TSchema extends z.ZodType<Record<string, unkn
34
34
  optionLabels?: Partial<Record<keyof z.input<TSchema> & string, Record<string, ReactNode>>>;
35
35
  /** Which fields to show, in which order. Default: every field of the shape, in its order. A hidden field still validates (its default value is sent). */
36
36
  fields?: ReadonlyArray<keyof z.input<TSchema> & string>;
37
+ /** The control of a text field when the schema cannot say it: a long text in a textarea, a bounded one in an input. */
38
+ controls?: Partial<Record<keyof z.input<TSchema> & string, "textarea" | "text">>;
37
39
  /** The write in flight outside the form (a mutation): the submit stays inactive. */
38
40
  pending?: boolean;
39
41
  /** The server's refusal, shown as a `save` banner above the actions. */
@@ -138,8 +140,10 @@ export function ContractForm<TSchema extends z.ZodType<Record<string, unknown>,
138
140
  disabled: busy,
139
141
  autoFocus: autoFocus && index === 0,
140
142
  };
143
+ const forced = props.controls?.[field.name as keyof z.input<TSchema> & string];
144
+ const kind = forced === undefined ? field.kind : forced === "textarea" && (field.kind === "text" || field.kind === "textarea") ? "textarea" : forced === "text" && field.kind === "textarea" ? "text" : field.kind;
141
145
  let control: ReactNode;
142
- switch (field.kind) {
146
+ switch (kind) {
143
147
  case "checkbox":
144
148
  control = (
145
149
  <input type="checkbox" {...shared} {...register(field.name)} className="h-4 w-4 rounded-sm border-border accent-accent" />
@@ -198,7 +202,7 @@ export function ContractForm<TSchema extends z.ZodType<Record<string, unknown>,
198
202
  break;
199
203
  default: {
200
204
  const type =
201
- field.kind === "email" ? "email" : field.kind === "url" ? "url" : field.kind === "date" ? "date" : field.kind === "datetime" ? "datetime-local" : "text";
205
+ kind === "email" ? "email" : kind === "url" ? "url" : kind === "date" ? "date" : kind === "datetime" ? "datetime-local" : "text";
202
206
  control = (
203
207
  <input
204
208
  type={type}
package/src/index.ts CHANGED
@@ -22,6 +22,8 @@ export {
22
22
  type FetchLike,
23
23
  } from "./fetch-contract.js";
24
24
  export { failureOf, isAccessDenied, messageOf, statusOf } from "./failures.js";
25
+ // What a generated screen test imports of the core — so a front product declares `@ogygie/ui` alone, never the core (lot 4 M2 validation, 2026-10-18).
26
+ export { OgygieFailure, type OgygieError } from "@ogygie/core/errors";
25
27
  export {
26
28
  failedQuery,
27
29
  idleMutation,