@stapel/attributes-react 0.1.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 (74) hide show
  1. package/README.md +123 -0
  2. package/dist/default/FeatureBadges.d.ts +33 -0
  3. package/dist/default/FeatureBadges.d.ts.map +1 -0
  4. package/dist/default/FeatureBadges.js +56 -0
  5. package/dist/default/FeatureBadges.js.map +1 -0
  6. package/dist/default/FeatureFields.d.ts +52 -0
  7. package/dist/default/FeatureFields.d.ts.map +1 -0
  8. package/dist/default/FeatureFields.js +60 -0
  9. package/dist/default/FeatureFields.js.map +1 -0
  10. package/dist/default/editors.d.ts +24 -0
  11. package/dist/default/editors.d.ts.map +1 -0
  12. package/dist/default/editors.js +354 -0
  13. package/dist/default/editors.js.map +1 -0
  14. package/dist/default/index.d.ts +27 -0
  15. package/dist/default/index.d.ts.map +1 -0
  16. package/dist/default/index.js +25 -0
  17. package/dist/default/index.js.map +1 -0
  18. package/dist/dto.d.ts +40 -0
  19. package/dist/dto.d.ts.map +1 -0
  20. package/dist/dto.js +64 -0
  21. package/dist/dto.js.map +1 -0
  22. package/dist/errors.d.ts +57 -0
  23. package/dist/errors.d.ts.map +1 -0
  24. package/dist/errors.js +98 -0
  25. package/dist/errors.js.map +1 -0
  26. package/dist/format.d.ts +46 -0
  27. package/dist/format.d.ts.map +1 -0
  28. package/dist/format.js +159 -0
  29. package/dist/format.js.map +1 -0
  30. package/dist/i18n/es.d.ts +13 -0
  31. package/dist/i18n/es.d.ts.map +1 -0
  32. package/dist/i18n/es.js +36 -0
  33. package/dist/i18n/es.js.map +1 -0
  34. package/dist/i18n/keys.d.ts +56 -0
  35. package/dist/i18n/keys.d.ts.map +1 -0
  36. package/dist/i18n/keys.js +80 -0
  37. package/dist/i18n/keys.js.map +1 -0
  38. package/dist/i18n/ru.d.ts +19 -0
  39. package/dist/i18n/ru.d.ts.map +1 -0
  40. package/dist/i18n/ru.js +42 -0
  41. package/dist/i18n/ru.js.map +1 -0
  42. package/dist/index.d.ts +58 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +54 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/registry.d.ts +122 -0
  47. package/dist/registry.d.ts.map +1 -0
  48. package/dist/registry.js +82 -0
  49. package/dist/registry.js.map +1 -0
  50. package/dist/types.d.ts +134 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +35 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/validate.d.ts +88 -0
  55. package/dist/validate.d.ts.map +1 -0
  56. package/dist/validate.js +410 -0
  57. package/dist/validate.js.map +1 -0
  58. package/manifest.json +96 -0
  59. package/package.json +107 -0
  60. package/src/default/FeatureBadges.tsx +123 -0
  61. package/src/default/FeatureFields.tsx +140 -0
  62. package/src/default/editors.tsx +578 -0
  63. package/src/default/index.ts +34 -0
  64. package/src/dto.ts +78 -0
  65. package/src/errors.ts +127 -0
  66. package/src/format.ts +210 -0
  67. package/src/i18n/es.ts +41 -0
  68. package/src/i18n/keys.ts +89 -0
  69. package/src/i18n/ru.ts +48 -0
  70. package/src/index.ts +98 -0
  71. package/src/registry.ts +167 -0
  72. package/src/types.ts +166 -0
  73. package/src/validate.ts +507 -0
  74. package/tsconfig.json +26 -0
@@ -0,0 +1,354 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The antd BUILTIN value editors — one per value type `stapel_attributes`
4
+ * ships (`types/`: ten of them).
5
+ *
6
+ * ── Where these sit in the resolution ladder ───────────────────────────────
7
+ *
8
+ * explicit `registerValueEditor(type, …)` ← a host's, always wins
9
+ * → this table ← the skin's default
10
+ * → `<UnsupportedValueEditor/>` ← loud, never silent
11
+ *
12
+ * ── These are NOT forms-react's widgets, and the differences are the point ─
13
+ *
14
+ * Both packages draw "the ten types", and it would be easy to assume one is a
15
+ * copy of the other. They are not: forms-react keys on `FormField.kind` (the
16
+ * admin CONFIG form) while this keys on `config.type` (the VALUE), and three
17
+ * of the ten have a genuinely different value shape on this axis:
18
+ *
19
+ * - **`date` is a Unix timestamp (integer)**, not an ISO string
20
+ * (`types/date/dto.py`: `value: Optional[int] # Unix timestamp`, and
21
+ * `validate_dto` refuses a non-int outright). The control is still a
22
+ * native input — dayjs for one widget is not worth a runtime dependency —
23
+ * but it converts in both directions.
24
+ * - **`hex_color` is an OBJECT** `{simple, hex?, label?}` where `simple` is
25
+ * REQUIRED and drawn from a closed vocabulary of eighteen colour
26
+ * categories (`types/hex_color/constants.py`). A bare `#RRGGBB` string
27
+ * fails validation, so the editor is a category picker with an optional
28
+ * exact-colour swatch, not a bare `ColorPicker`.
29
+ * - **`select` is always a LIST**, even when `maxSelected: 1`
30
+ * (`types/select/dto.py`: `value: List[str]`). A single choice is a
31
+ * one-element array, and `Segmented`'s scalar is wrapped on the way out.
32
+ *
33
+ * `convertible_unit` is the fourth object-valued type (`{value, unit}`), and
34
+ * the editor must NOT convert anything itself: the server converts the number
35
+ * from the submitted unit into the family's base unit before validating.
36
+ */
37
+ import { useMemo } from "react";
38
+ import { Cascader, ColorPicker, Flex, Input, InputNumber, Segmented, Select, Switch, Typography, } from "antd";
39
+ import { useT } from "@stapel/core";
40
+ import { featureConfig, featureName } from "../types.js";
41
+ import { SIMPLE_COLORS } from "../validate.js";
42
+ import { ATTRIBUTES_I18N_KEYS } from "../i18n/keys.js";
43
+ /** At or below this many choices a single-select renders as a `Segmented` —
44
+ * the profiles-react / forms-react threshold, kept identical on purpose. */
45
+ const SEGMENTED_MAX_OPTIONS = 4;
46
+ /**
47
+ * antd's `status` prop under `exactOptionalPropertyTypes` does not accept
48
+ * `undefined` — it wants the key ABSENT. Spread this instead of passing
49
+ * `status={error ? "error" : undefined}`.
50
+ */
51
+ function errorStatus(error) {
52
+ return error ? { status: "error" } : {};
53
+ }
54
+ function str(value) {
55
+ return typeof value === "string" ? value : value === null || value === undefined ? "" : String(value);
56
+ }
57
+ function numberish(value) {
58
+ if (typeof value === "number" && Number.isFinite(value))
59
+ return value;
60
+ if (typeof value === "string" && value.trim().length > 0) {
61
+ const parsed = Number(value);
62
+ if (Number.isFinite(parsed))
63
+ return parsed;
64
+ }
65
+ return undefined;
66
+ }
67
+ function configOf(props) {
68
+ return featureConfig(props.feature);
69
+ }
70
+ /** `{value, label}` choices from either option shape the engine allows, with
71
+ * labels resolved through the host's catalogue when `translatable_options`
72
+ * is on (its default). */
73
+ function useChoices(config) {
74
+ const t = useT();
75
+ return useMemo(() => {
76
+ const raw = config["options"];
77
+ if (!Array.isArray(raw))
78
+ return [];
79
+ const translatable = config["translatable_options"] !== false;
80
+ return raw.map((option) => {
81
+ if (option !== null && typeof option === "object") {
82
+ const entry = option;
83
+ const value = str(entry.value);
84
+ const label = str(entry.label) || value;
85
+ return { value, label: translatable && label !== value ? t(label) : label };
86
+ }
87
+ return { value: str(option), label: str(option) };
88
+ });
89
+ }, [config, t]);
90
+ }
91
+ // ── string ───────────────────────────────────────────────────────────────────
92
+ /** `string` → `Input`, or `Input.TextArea` when `config.multiline` is set. */
93
+ const StringEditor = (props) => {
94
+ const cfg = configOf(props);
95
+ const placeholder = str(cfg["placeholder"]);
96
+ // `config.maxLength` is deliberately NOT passed to the control as a hard
97
+ // cap: the engine counts Unicode CODE POINTS and the DOM's `maxlength`
98
+ // counts UTF-16 code units, so a hard cap would stop a person two emoji
99
+ // short of the real limit with no explanation. The mirror reports the
100
+ // actual limit, in the actual unit, when it is actually exceeded.
101
+ const common = {
102
+ id: props.id,
103
+ value: str(props.value),
104
+ disabled: props.disabled === true,
105
+ ...errorStatus(props.error),
106
+ ...(placeholder.length > 0 ? { placeholder } : {}),
107
+ };
108
+ return cfg["multiline"] === true ? (_jsx(Input.TextArea, { ...common, autoSize: { minRows: 3, maxRows: 8 }, onChange: (event) => props.onChange(event.target.value) })) : (_jsx(Input, { ...common, onChange: (event) => props.onChange(event.target.value) }));
109
+ };
110
+ // ── int / float ──────────────────────────────────────────────────────────────
111
+ function makeNumberEditor(isInt) {
112
+ const Editor = (props) => {
113
+ const cfg = configOf(props);
114
+ const min = numberish(cfg["min"]);
115
+ const max = numberish(cfg["max"]);
116
+ // `int`'s `precision` is a DISPLAY hint upstream (it defaults to 1 and
117
+ // means "significant step", not "decimal places"), so an integer control
118
+ // pins 0 decimals rather than reading it — reading it would let an `int`
119
+ // field accept `1.0` and then silently truncate server-side.
120
+ const precision = isInt ? 0 : numberish(cfg["precision"]);
121
+ const placeholder = str(cfg["placeholder"]);
122
+ return (_jsx(InputNumber, { id: props.id, style: { width: "100%" }, value: numberish(props.value) ?? null, disabled: props.disabled === true, ...errorStatus(props.error), ...(min !== undefined ? { min } : {}), ...(max !== undefined ? { max } : {}), ...(precision !== undefined ? { precision } : {}), ...(isInt ? { step: 1 } : {}), ...(placeholder.length > 0 ? { placeholder } : {}), ...(str(cfg["prefix"]).length > 0 ? { prefix: str(cfg["prefix"]) } : {}), ...(str(cfg["postfix"]).length > 0 ? { suffix: str(cfg["postfix"]) } : {}), onChange: (next) => props.onChange(next ?? undefined) }));
123
+ };
124
+ Editor.displayName = isInt ? "IntValueEditor" : "FloatValueEditor";
125
+ return Editor;
126
+ }
127
+ // ── bool ─────────────────────────────────────────────────────────────────────
128
+ const BoolEditor = (props) => {
129
+ const t = useT();
130
+ const cfg = configOf(props);
131
+ const on = props.value === true;
132
+ const trueLabel = str(cfg["trueLabel"]) || t(ATTRIBUTES_I18N_KEYS.boolYes);
133
+ const falseLabel = str(cfg["falseLabel"]) || t(ATTRIBUTES_I18N_KEYS.boolNo);
134
+ return (_jsxs(Flex, { align: "center", gap: 8, children: [_jsx(Switch, { id: props.id, checked: on, disabled: props.disabled === true, onChange: (checked) => props.onChange(checked) }), _jsx(Typography.Text, { type: "secondary", children: on ? trueLabel : falseLabel })] }));
135
+ };
136
+ // ── select ───────────────────────────────────────────────────────────────────
137
+ /**
138
+ * `select` → `Segmented` for a small single choice, `Select` otherwise.
139
+ *
140
+ * The value is a LIST on both branches. `maxSelected` absent means UNLIMITED
141
+ * (the engine's own default); reading an absent key as 1 would silently turn
142
+ * every unconfigured select into a single-choice control.
143
+ */
144
+ const SelectEditor = (props) => {
145
+ const t = useT();
146
+ const cfg = configOf(props);
147
+ const choices = useChoices(cfg);
148
+ const maxSelected = numberish(cfg["maxSelected"]);
149
+ const multiple = maxSelected === undefined || maxSelected > 1;
150
+ const current = Array.isArray(props.value) ? props.value.map(str) : [];
151
+ if (!multiple &&
152
+ cfg["uiStyle"] !== "dropdown" &&
153
+ choices.length > 0 &&
154
+ choices.length <= SEGMENTED_MAX_OPTIONS) {
155
+ return (_jsx(Segmented, { id: props.id, "aria-label": featureName(props.feature), options: [...choices], value: current[0] ?? "", disabled: props.disabled === true, onChange: (next) => props.onChange(next.length > 0 ? [next] : undefined) }));
156
+ }
157
+ return (_jsx(Select, { id: props.id, style: { width: "100%" }, options: [...choices], disabled: props.disabled === true, ...errorStatus(props.error), placeholder: t(ATTRIBUTES_I18N_KEYS.selectPlaceholder), mode: "multiple", ...(maxSelected !== undefined ? { maxCount: maxSelected } : {}), value: current, onChange: (next) => props.onChange(next.length > 0 ? [...next] : undefined) }));
158
+ };
159
+ // ── date ─────────────────────────────────────────────────────────────────────
160
+ /** `precision` → the native input type whose value converts cleanly to and
161
+ * from the Unix timestamp the engine stores. */
162
+ const DATE_INPUT_TYPE = {
163
+ month: "month",
164
+ date: "date",
165
+ datetime: "datetime-local",
166
+ };
167
+ function pad(n) {
168
+ return String(n).padStart(2, "0");
169
+ }
170
+ /** Unix seconds → the string a native input of this precision displays,
171
+ * in the VIEWER's time zone (which is what the person typed it in). */
172
+ export function timestampToInputValue(seconds, precision) {
173
+ const d = new Date(seconds * 1000);
174
+ const ymd = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
175
+ if (precision === "month")
176
+ return ymd.slice(0, 7);
177
+ if (precision === "datetime")
178
+ return `${ymd}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
179
+ return ymd;
180
+ }
181
+ /**
182
+ * The inverse. Takes no `precision`: a native input's value already says
183
+ * which shape it is (`2010`, `2010-06`, `2010-06-15`, `2010-06-15T14:30`), so
184
+ * reading the config here would only create a way for the two to disagree.
185
+ *
186
+ * Returns `undefined` for an empty or unparseable input rather than 0 — `0`
187
+ * is 1970, a real timestamp, and the one value that must never be produced by
188
+ * "the person cleared the field".
189
+ */
190
+ export function inputValueToTimestamp(text) {
191
+ if (text.length === 0)
192
+ return undefined;
193
+ const match = /^(\d{4})(?:-(\d{2}))?(?:-(\d{2}))?(?:T(\d{2}):(\d{2}))?$/.exec(text);
194
+ if (match === null)
195
+ return undefined;
196
+ const [, year, month, day, hour, minute] = match;
197
+ const date = new Date(Number(year), month === undefined ? 0 : Number(month) - 1, day === undefined ? 1 : Number(day), hour === undefined ? 0 : Number(hour), minute === undefined ? 0 : Number(minute));
198
+ const seconds = Math.floor(date.getTime() / 1000);
199
+ return Number.isFinite(seconds) ? seconds : undefined;
200
+ }
201
+ const DateEditor = (props) => {
202
+ const cfg = configOf(props);
203
+ const precision = str(cfg["precision"]) || "date";
204
+ const current = numberish(props.value);
205
+ // "Year only" is a number, not a date: a date input would force a month and
206
+ // a day the admin explicitly said they do not want. The value on the wire
207
+ // is still a timestamp — January 1st of that year, local time.
208
+ if (precision === "year") {
209
+ return (_jsx(InputNumber, { id: props.id, style: { width: "100%" }, value: current === undefined ? null : new Date(current * 1000).getFullYear(), disabled: props.disabled === true, ...errorStatus(props.error), step: 1, precision: 0, onChange: (next) => props.onChange(next === null || next === undefined
210
+ ? undefined
211
+ : Math.floor(new Date(next, 0, 1).getTime() / 1000)) }));
212
+ }
213
+ const min = numberish(cfg["minDate"]);
214
+ const max = numberish(cfg["maxDate"]);
215
+ return (_jsx(Input, { id: props.id, type: DATE_INPUT_TYPE[precision] ?? "date", value: current === undefined ? "" : timestampToInputValue(current, precision), disabled: props.disabled === true, ...errorStatus(props.error), ...(min !== undefined ? { min: timestampToInputValue(min, precision) } : {}), ...(max !== undefined ? { max: timestampToInputValue(max, precision) } : {}), onChange: (event) => props.onChange(inputValueToTimestamp(event.target.value)) }));
216
+ };
217
+ // ── header ───────────────────────────────────────────────────────────────────
218
+ /**
219
+ * `header` → a caption, and NOT a control.
220
+ *
221
+ * It never calls `onChange`: the engine regenerates a header's DAO from its
222
+ * config and the batch validator skips headers entirely, so a header that
223
+ * could hold a value would only ever produce a refused submit.
224
+ * `config.style` is `l` (larger) or `m`.
225
+ */
226
+ const HeaderEditor = (props) => {
227
+ const level = str(configOf(props)["style"]) === "m" ? 4 : 3;
228
+ return (_jsx(Typography.Title, { level: level, style: { marginBottom: 0 }, children: featureName(props.feature) }));
229
+ };
230
+ // ── hex_color ────────────────────────────────────────────────────────────────
231
+ /**
232
+ * `hex_color` → a colour CATEGORY picker, plus an exact swatch when the config
233
+ * allows a custom colour.
234
+ *
235
+ * The value is `{simple, hex?}`. `simple` is required and must be one of the
236
+ * engine's eighteen categories; when the config lists options, `simple` must
237
+ * additionally be one of THOSE unless `allowCustom`. `hex` is optional and
238
+ * only meaningful as a refinement of the category — which is why the picker
239
+ * comes first and the swatch second, rather than the other way round.
240
+ */
241
+ const HexColorEditor = (props) => {
242
+ const t = useT();
243
+ const cfg = configOf(props);
244
+ const current = props.value !== null && typeof props.value === "object"
245
+ ? props.value
246
+ : {};
247
+ const simple = str(current.simple);
248
+ const hex = str(current.hex);
249
+ const allowCustom = cfg["allowCustom"] === true;
250
+ const options = useMemo(() => {
251
+ const raw = cfg["options"];
252
+ const declared = Array.isArray(raw)
253
+ ? raw
254
+ .map((option) => option !== null && typeof option === "object"
255
+ ? str(option.simple)
256
+ : str(option))
257
+ .filter((code) => code.length > 0)
258
+ : [];
259
+ const source = declared.length > 0 && !allowCustom ? declared : SIMPLE_COLORS;
260
+ return source.map((code) => ({ value: code, label: code }));
261
+ }, [cfg, allowCustom]);
262
+ const emit = (nextSimple, nextHex) => {
263
+ if (nextSimple.length === 0) {
264
+ props.onChange(undefined);
265
+ return;
266
+ }
267
+ props.onChange({ simple: nextSimple, ...(nextHex.length > 0 ? { hex: nextHex } : {}) });
268
+ };
269
+ return (_jsxs(Flex, { gap: 8, align: "center", children: [_jsx(Select, { id: props.id, style: { flex: 1 }, options: options, disabled: props.disabled === true, ...errorStatus(props.error), placeholder: t(ATTRIBUTES_I18N_KEYS.selectPlaceholder), ...(simple.length > 0 ? { value: simple } : {}), onChange: (next) => emit(next, hex) }), allowCustom && (
270
+ // antd's ColorPicker renders no labelable control and accepts no
271
+ // `id`, so it is the SECONDARY control here and the labelled one is
272
+ // the category select above.
273
+ _jsx(ColorPicker, { disabled: props.disabled === true, format: "hex", ...(hex.length > 0 ? { value: hex } : {}), onChange: (color) => emit(simple, color.toHexString()), showText: true }))] }));
274
+ };
275
+ function toCascaderOptions(raw, t, translatable) {
276
+ if (!Array.isArray(raw))
277
+ return [];
278
+ return raw.map((option) => {
279
+ if (option === null || typeof option !== "object") {
280
+ return { value: str(option), label: str(option) };
281
+ }
282
+ const entry = option;
283
+ const value = str(entry.value);
284
+ const rawLabel = str(entry.label) || value;
285
+ const children = toCascaderOptions(entry.children, t, translatable);
286
+ return {
287
+ value,
288
+ label: translatable && rawLabel !== value ? t(rawLabel) : rawLabel,
289
+ ...(children.length > 0 ? { children } : {}),
290
+ };
291
+ });
292
+ }
293
+ /** `hierarchical_select` → `Cascader`. The answer is the path array of
294
+ * `value`s from root to the chosen node, which is exactly what the engine
295
+ * stores and validates level by level. */
296
+ const HierarchicalSelectEditor = (props) => {
297
+ const t = useT();
298
+ const cfg = configOf(props);
299
+ const options = useMemo(() => toCascaderOptions(cfg["options"], t, cfg["translatable_options"] !== false), [cfg, t]);
300
+ const value = Array.isArray(props.value) ? props.value.map(str) : undefined;
301
+ return (_jsx(Cascader, { id: props.id, style: { width: "100%" }, options: options, disabled: props.disabled === true, ...errorStatus(props.error), placeholder: t(ATTRIBUTES_I18N_KEYS.selectPlaceholder), changeOnSelect: true, ...(value ? { value } : {}), onChange: (next) => props.onChange(Array.isArray(next) && next.length > 0 ? next.map(str) : undefined) }));
302
+ };
303
+ // ── convertible_unit ─────────────────────────────────────────────────────────
304
+ /**
305
+ * `convertible_unit` → a number beside the unit it is expressed in.
306
+ *
307
+ * The wire DTO is `{type, value, unit}`: the number AS TYPED, tagged with
308
+ * which of the config's `unit_m` (metric) / `unit_i` (imperial) codes it is
309
+ * in. The server converts to the family's base unit before validating, so
310
+ * the editor must send the unit and must NOT convert anything itself — the
311
+ * conversion table lives in Python.
312
+ */
313
+ const ConvertibleUnitEditor = (props) => {
314
+ const cfg = configOf(props);
315
+ const units = [str(cfg["unit_m"]), str(cfg["unit_i"])].filter((code) => code.length > 0);
316
+ const current = props.value !== null && typeof props.value === "object"
317
+ ? props.value
318
+ : {};
319
+ const unit = str(current.unit) || units[0] || "";
320
+ const amount = numberish(current.value);
321
+ const precision = numberish(cfg["precision"]);
322
+ const emit = (nextAmount, nextUnit) => {
323
+ if (nextAmount === undefined) {
324
+ props.onChange(undefined);
325
+ return;
326
+ }
327
+ props.onChange({
328
+ value: nextAmount,
329
+ ...(nextUnit.length > 0 ? { unit: nextUnit } : {}),
330
+ });
331
+ };
332
+ return (_jsxs(Flex, { gap: 8, children: [_jsx(InputNumber, { id: props.id, style: { flex: 1 }, value: amount ?? null, disabled: props.disabled === true, ...errorStatus(props.error), ...(precision !== undefined ? { precision } : {}), ...(str(cfg["prefix"]).length > 0 ? { prefix: str(cfg["prefix"]) } : {}), onChange: (next) => emit(next ?? undefined, unit) }), units.length > 0 && (_jsx(Select, { style: { width: 96 }, disabled: props.disabled === true, ...errorStatus(props.error), value: unit, options: units.map((code) => ({ value: code, label: code })), onChange: (next) => emit(amount, next) }))] }));
333
+ };
334
+ /**
335
+ * The skin's builtin editor per value type — the second rung of the ladder.
336
+ * A type absent from this table has no default drawing and reaches
337
+ * `<UnsupportedValueEditor/>`.
338
+ */
339
+ export const BUILTIN_VALUE_EDITORS = {
340
+ string: StringEditor,
341
+ int: makeNumberEditor(true),
342
+ float: makeNumberEditor(false),
343
+ bool: BoolEditor,
344
+ select: SelectEditor,
345
+ date: DateEditor,
346
+ header: HeaderEditor,
347
+ hex_color: HexColorEditor,
348
+ hierarchical_select: HierarchicalSelectEditor,
349
+ convertible_unit: ConvertibleUnitEditor,
350
+ };
351
+ /** The types this skin can draw — handed to `unsupportedTypes` so the
352
+ * headless half can judge renderability without importing the skin. */
353
+ export const BUILTIN_VALUE_EDITOR_TYPES = Object.keys(BUILTIN_VALUE_EDITORS).sort();
354
+ //# sourceMappingURL=editors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editors.js","sourceRoot":"","sources":["../../src/default/editors.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `@stapel/attributes-react/default` — the antd skin: the ten builtin value
3
+ * editors, the form rows that run the resolution ladder, and the display
4
+ * components.
5
+ *
6
+ * A separate entry point (the convention every pair's `/default` follows) so
7
+ * a consumer rendering its own controls over the registry and the mirror
8
+ * never pulls `antd` into their bundle. `BUILTIN_VALUE_EDITOR_TYPES` is the
9
+ * bridge in the other direction: the headless half judges renderability from
10
+ * that array without importing anything in here.
11
+ *
12
+ * ```tsx
13
+ * import { unsupportedTypeGate, toFeaturesDto } from "@stapel/attributes-react";
14
+ * import { BUILTIN_VALUE_EDITOR_TYPES, FeatureFields } from "@stapel/attributes-react/default";
15
+ *
16
+ * const gate = unsupportedTypeGate(features, BUILTIN_VALUE_EDITOR_TYPES);
17
+ * <FeatureFields features={features} values={values} onChange={setValue} errors={errors} />;
18
+ * <Button disabled={!gate.available}>…</Button>
19
+ * ```
20
+ */
21
+ export { BUILTIN_VALUE_EDITORS, BUILTIN_VALUE_EDITOR_TYPES } from "./editors.js";
22
+ export { inputValueToTimestamp, timestampToInputValue } from "./editors.js";
23
+ export { FeatureFields, UnsupportedValueEditor, featureControlId, } from "./FeatureFields.js";
24
+ export type { FeatureFieldsProps, FeatureRowProps, UnsupportedValueEditorProps, } from "./FeatureFields.js";
25
+ export { FeatureBadges, FeatureValueList } from "./FeatureBadges.js";
26
+ export type { FeatureDisplayProps } from "./FeatureBadges.js";
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/default/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `@stapel/attributes-react/default` — the antd skin: the ten builtin value
3
+ * editors, the form rows that run the resolution ladder, and the display
4
+ * components.
5
+ *
6
+ * A separate entry point (the convention every pair's `/default` follows) so
7
+ * a consumer rendering its own controls over the registry and the mirror
8
+ * never pulls `antd` into their bundle. `BUILTIN_VALUE_EDITOR_TYPES` is the
9
+ * bridge in the other direction: the headless half judges renderability from
10
+ * that array without importing anything in here.
11
+ *
12
+ * ```tsx
13
+ * import { unsupportedTypeGate, toFeaturesDto } from "@stapel/attributes-react";
14
+ * import { BUILTIN_VALUE_EDITOR_TYPES, FeatureFields } from "@stapel/attributes-react/default";
15
+ *
16
+ * const gate = unsupportedTypeGate(features, BUILTIN_VALUE_EDITOR_TYPES);
17
+ * <FeatureFields features={features} values={values} onChange={setValue} errors={errors} />;
18
+ * <Button disabled={!gate.available}>…</Button>
19
+ * ```
20
+ */
21
+ export { BUILTIN_VALUE_EDITORS, BUILTIN_VALUE_EDITOR_TYPES } from "./editors.js";
22
+ export { inputValueToTimestamp, timestampToInputValue } from "./editors.js";
23
+ export { FeatureFields, UnsupportedValueEditor, featureControlId, } from "./FeatureFields.js";
24
+ export { FeatureBadges, FeatureValueList } from "./FeatureBadges.js";
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/default/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAM5B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/dto.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The `{slug: {type, value}}` envelope — in and out.
3
+ *
4
+ * A composer holds plain values keyed by slug (that is what an editor's
5
+ * `onChange` produces); the wire wants each one tagged with its type, because
6
+ * the server resolves the type handler from the DTO's `type` discriminator.
7
+ * The tag comes from the FEATURE's config, never from the editor: the engine
8
+ * itself overrides whatever the client sent (`dto_data = {**dto_data, 'type':
9
+ * config.type}` — `validation.py`), so a client that guessed differently
10
+ * would be sending a field the server throws away.
11
+ */
12
+ import type { FeatureDef, FeaturesDto } from "./types.js";
13
+ /**
14
+ * Values keyed by slug → the `features_draft` payload.
15
+ *
16
+ * Three deliberate behaviours:
17
+ *
18
+ * - A feature with no declared type is DROPPED. It could not be edited (no
19
+ * editor resolves) and it cannot be tagged, so sending it would produce a
20
+ * row the server cannot route. `unsupportedTypes` is what tells a person
21
+ * it exists; silently sending a broken row would not.
22
+ * - `header` is DROPPED. The engine regenerates a header's DAO from its
23
+ * config and rejects an answer to one outright.
24
+ * - A blank value is DROPPED rather than sent as `null`. "Not answered" and
25
+ * "answered with nothing" are the same thing to the engine's empty check,
26
+ * and omitting the key keeps a draft's payload the size of what was
27
+ * actually filled in.
28
+ *
29
+ * `convertible_unit` is the one type whose editor emits an OBJECT rather than
30
+ * a scalar (`{value, unit}`), because its DTO genuinely carries the unit the
31
+ * number was typed in. Extra keys on that object ride along beside `value`.
32
+ */
33
+ export declare function toFeaturesDto(features: readonly FeatureDef[], values: Readonly<Record<string, unknown>>): FeaturesDto;
34
+ /**
35
+ * The reverse: a `features_draft` payload → the plain `{slug: value}` map a
36
+ * composer's editors read. Round-trips `convertible_unit` back into the
37
+ * `{value, unit}` object its editor holds.
38
+ */
39
+ export declare function fromFeaturesDto(dto: FeaturesDto): Readonly<Record<string, unknown>>;
40
+ //# sourceMappingURL=dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dto.d.ts","sourceRoot":"","sources":["../src/dto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAC;AAI3E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,WAAW,CAmBb;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAanF"}
package/dist/dto.js ADDED
@@ -0,0 +1,64 @@
1
+ import { featureType } from "./types.js";
2
+ import { isBlank } from "./validate.js";
3
+ /**
4
+ * Values keyed by slug → the `features_draft` payload.
5
+ *
6
+ * Three deliberate behaviours:
7
+ *
8
+ * - A feature with no declared type is DROPPED. It could not be edited (no
9
+ * editor resolves) and it cannot be tagged, so sending it would produce a
10
+ * row the server cannot route. `unsupportedTypes` is what tells a person
11
+ * it exists; silently sending a broken row would not.
12
+ * - `header` is DROPPED. The engine regenerates a header's DAO from its
13
+ * config and rejects an answer to one outright.
14
+ * - A blank value is DROPPED rather than sent as `null`. "Not answered" and
15
+ * "answered with nothing" are the same thing to the engine's empty check,
16
+ * and omitting the key keeps a draft's payload the size of what was
17
+ * actually filled in.
18
+ *
19
+ * `convertible_unit` is the one type whose editor emits an OBJECT rather than
20
+ * a scalar (`{value, unit}`), because its DTO genuinely carries the unit the
21
+ * number was typed in. Extra keys on that object ride along beside `value`.
22
+ */
23
+ export function toFeaturesDto(features, values) {
24
+ const out = {};
25
+ for (const feature of features) {
26
+ const type = featureType(feature);
27
+ if (type === undefined || type === "header")
28
+ continue;
29
+ const value = values[feature.slug];
30
+ if (isBlank(value))
31
+ continue;
32
+ if (type === "convertible_unit" && value !== null && typeof value === "object") {
33
+ const entry = value;
34
+ out[feature.slug] = {
35
+ type,
36
+ value: entry.value,
37
+ ...(entry.unit === undefined || entry.unit === null ? {} : { unit: entry.unit }),
38
+ };
39
+ continue;
40
+ }
41
+ out[feature.slug] = { type, value };
42
+ }
43
+ return out;
44
+ }
45
+ /**
46
+ * The reverse: a `features_draft` payload → the plain `{slug: value}` map a
47
+ * composer's editors read. Round-trips `convertible_unit` back into the
48
+ * `{value, unit}` object its editor holds.
49
+ */
50
+ export function fromFeaturesDto(dto) {
51
+ const out = {};
52
+ for (const [slug, entry] of Object.entries(dto)) {
53
+ if (entry.type === "convertible_unit") {
54
+ out[slug] = {
55
+ value: entry.value,
56
+ ...(entry["unit"] === undefined ? {} : { unit: entry["unit"] }),
57
+ };
58
+ continue;
59
+ }
60
+ out[slug] = entry.value;
61
+ }
62
+ return out;
63
+ }
64
+ //# sourceMappingURL=dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dto.js","sourceRoot":"","sources":["../src/dto.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa,CAC3B,QAA+B,EAC/B,MAAyC;IAEzC,MAAM,GAAG,GAAoC,EAAE,CAAC;IAChD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ;YAAE,SAAS;QACtD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,OAAO,CAAC,KAAK,CAAC;YAAE,SAAS;QAC7B,IAAI,IAAI,KAAK,kBAAkB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/E,MAAM,KAAK,GAAG,KAA4C,CAAC;YAC3D,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG;gBAClB,IAAI;gBACJ,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;aACjF,CAAC;YACF,SAAS;QACX,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAgB;IAC9C,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,GAAG;gBACV,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;aAChE,CAAC;YACF,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The error vocabulary, mirrored — and the one step that turns a server
3
+ * verdict into refusals sitting on the controls that caused them.
4
+ *
5
+ * Both halves come straight from `stapel_attributes.errors`: the machine code
6
+ * (`ValidationErrorCode`) and the localizable key it maps to
7
+ * (`ERROR_CODE_TO_KEY`). Nothing here invents copy: a "too long" caught by
8
+ * the client mirror and a "too long" caught by the server render the SAME
9
+ * sentence from the SAME key, because they ARE the same key. The alternative
10
+ * — pair-invented wording for the local half — gives a person two sentences
11
+ * for one problem and makes the local one a lie the moment the backend's rule
12
+ * moves.
13
+ *
14
+ * The keys themselves are owned by stapel-attributes and registered with
15
+ * stapel-core (`register_service_errors(ATTRIBUTES_ERRORS)`), so a host that
16
+ * already has a pair's generated error bundle has their copy; the fallback
17
+ * English lives in this package's own i18n bundle for a host that does not.
18
+ */
19
+ import type { FlowError } from "@stapel/core";
20
+ import type { FeatureValidationResult, ValidationBatchResult, ValidationErrorCode } from "./types.js";
21
+ /**
22
+ * Every `ValidationErrorCode` the engine defines, sorted.
23
+ *
24
+ * Pinned byte-for-byte against `stapel-attributes/tests/golden/
25
+ * error_codes.json` — the corpus the engine generates from its own enum and
26
+ * asserts from both Python and TypeScript. A code added upstream and not here
27
+ * turns `test/contract.test.ts` red.
28
+ */
29
+ export declare const VALIDATION_ERROR_CODES: readonly ValidationErrorCode[];
30
+ /**
31
+ * `ValidationErrorCode` → localizable key, mirroring
32
+ * `stapel_attributes.errors.ERROR_CODE_TO_KEY` exactly — including the three
33
+ * codes that deliberately collapse onto one key (`duplicate_slug` reports as
34
+ * an unknown type; `min_greater_than_max` and `empty_options` are both
35
+ * invalid config). Collapsing them differently here would make the client
36
+ * claim a distinction the server does not draw.
37
+ */
38
+ export declare const ERROR_CODE_TO_KEY: Readonly<Record<ValidationErrorCode, string>>;
39
+ /** The key a result should render from: what the server said, else the one
40
+ * its code maps to. The server sends `localizable_error` already — this only
41
+ * covers the mirror's rows and a server that ever omits it. */
42
+ export declare function resultErrorKey(result: FeatureValidationResult): string | undefined;
43
+ /**
44
+ * A batch verdict, split into per-control refusals keyed by feature slug.
45
+ *
46
+ * `params.field` is added on the way out. The engine's own params are
47
+ * `{feature, slug}` (`validation.py`) and the fleet's `useFieldError`
48
+ * convention routes on `field` — so without this a perfectly well-formed
49
+ * server refusal lands in a page-level banner instead of under the control
50
+ * whose value caused it, which is the difference between "something is wrong"
51
+ * and "this box is wrong".
52
+ *
53
+ * `ref_value` rides along in params too: `error.400.feature_below_minimum`
54
+ * interpolates the limit, and the limit is what `ref_value` carries.
55
+ */
56
+ export declare function featureErrorsBySlug(batch: ValidationBatchResult): Readonly<Record<string, FlowError>>;
57
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,mBAAmB,EAgBhE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAgB3E,CAAC;AAEF;;+DAE+D;AAC/D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,uBAAuB,GAC9B,MAAM,GAAG,SAAS,CAKpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,GAC3B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAsBrC"}