@stapel/listings-react 0.11.0 → 0.13.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 (79) hide show
  1. package/CHANGELOG.md +212 -0
  2. package/dist/api/types.d.ts +10 -0
  3. package/dist/api/types.d.ts.map +1 -1
  4. package/dist/api/types.js.map +1 -1
  5. package/dist/default/ListingCard.d.ts +2 -2
  6. package/dist/default/ListingCard.d.ts.map +1 -1
  7. package/dist/default/ListingCard.js +8 -2
  8. package/dist/default/ListingCard.js.map +1 -1
  9. package/dist/default/ListingComposerPage.d.ts +59 -0
  10. package/dist/default/ListingComposerPage.d.ts.map +1 -1
  11. package/dist/default/ListingComposerPage.js +103 -12
  12. package/dist/default/ListingComposerPage.js.map +1 -1
  13. package/dist/default/ListingDetailPane.d.ts +2 -2
  14. package/dist/default/ListingDetailPane.d.ts.map +1 -1
  15. package/dist/default/ListingDetailPane.js +6 -1
  16. package/dist/default/ListingDetailPane.js.map +1 -1
  17. package/dist/default/ListingSerpCard.d.ts +2 -2
  18. package/dist/default/ListingSerpCard.d.ts.map +1 -1
  19. package/dist/default/ListingSerpCard.js +7 -2
  20. package/dist/default/ListingSerpCard.js.map +1 -1
  21. package/dist/default/index.d.ts +2 -2
  22. package/dist/default/index.d.ts.map +1 -1
  23. package/dist/default/index.js +1 -1
  24. package/dist/default/index.js.map +1 -1
  25. package/dist/default/types.d.ts +21 -0
  26. package/dist/default/types.d.ts.map +1 -1
  27. package/dist/headless/ListingComposer.d.ts +11 -0
  28. package/dist/headless/ListingComposer.d.ts.map +1 -1
  29. package/dist/headless/ListingComposer.js +18 -1
  30. package/dist/headless/ListingComposer.js.map +1 -1
  31. package/dist/headless/ListingDetail.d.ts +16 -1
  32. package/dist/headless/ListingDetail.d.ts.map +1 -1
  33. package/dist/headless/ListingDetail.js +13 -4
  34. package/dist/headless/ListingDetail.js.map +1 -1
  35. package/dist/i18n/es.d.ts.map +1 -1
  36. package/dist/i18n/es.js +4 -0
  37. package/dist/i18n/es.js.map +1 -1
  38. package/dist/i18n/keys.d.ts +10 -0
  39. package/dist/i18n/keys.d.ts.map +1 -1
  40. package/dist/i18n/keys.js +16 -0
  41. package/dist/i18n/keys.js.map +1 -1
  42. package/dist/i18n/ru.d.ts.map +1 -1
  43. package/dist/i18n/ru.js +4 -0
  44. package/dist/i18n/ru.js.map +1 -1
  45. package/dist/index.d.ts +1 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/model/features.d.ts +90 -20
  49. package/dist/model/features.d.ts.map +1 -1
  50. package/dist/model/features.js +148 -17
  51. package/dist/model/features.js.map +1 -1
  52. package/dist/model/validation.d.ts +12 -0
  53. package/dist/model/validation.d.ts.map +1 -1
  54. package/dist/model/validation.js +19 -0
  55. package/dist/model/validation.js.map +1 -1
  56. package/dist/nav/manifest.d.ts.map +1 -1
  57. package/dist/nav/manifest.js +2 -0
  58. package/dist/nav/manifest.js.map +1 -1
  59. package/llms.txt +1 -1
  60. package/manifest.json +6 -1
  61. package/nav-manifest.json +3 -1
  62. package/package.json +7 -7
  63. package/src/analytics/generated/events.json +1 -1
  64. package/src/api/types.ts +10 -0
  65. package/src/default/ListingCard.tsx +17 -4
  66. package/src/default/ListingComposerPage.tsx +221 -32
  67. package/src/default/ListingDetailPane.tsx +10 -6
  68. package/src/default/ListingSerpCard.tsx +13 -4
  69. package/src/default/index.ts +7 -2
  70. package/src/default/types.ts +22 -0
  71. package/src/headless/ListingComposer.tsx +28 -0
  72. package/src/headless/ListingDetail.tsx +37 -10
  73. package/src/i18n/es.ts +5 -0
  74. package/src/i18n/keys.ts +17 -0
  75. package/src/i18n/ru.ts +5 -0
  76. package/src/index.ts +1 -0
  77. package/src/model/features.ts +253 -35
  78. package/src/model/validation.ts +20 -0
  79. package/src/nav/manifest.ts +2 -0
@@ -1,31 +1,156 @@
1
- /** Keys that belong to the DAO envelope rather than to the type's config. */
1
+ import { featureType } from "@stapel/attributes-react";
2
+ /**
3
+ * Keys that belong to the DAO envelope rather than to the type's config.
4
+ *
5
+ * `labels` is deliberately NOT one of them, even though this module now reads
6
+ * it: `ref_select` and `ref_hierarchical_select` resolve their vocabulary
7
+ * terms from `config.labels` (attributes-react's `refLabels` reads the value
8
+ * envelope first and the config second, and this split hands the formatter a
9
+ * bare `{type, value}`), so envelope-ing the key would blank every term those
10
+ * two types print. For `select` the key is simply inert — its formatter reads
11
+ * `options` and nothing else — so carrying it costs a reference.
12
+ */
2
13
  const ENVELOPE = new Set(["slug", "value", "name", "order", "title", "badge"]);
3
- /** The two types whose stored `value` is an option key rather than the thing
4
- * itself. `hierarchical_select` is deliberately absent: its formatter joins
5
- * the path with " / " and never consults an option table at all. */
14
+ /** The type whose stored `value` is a flat list of option keys rather than the
15
+ * things themselves, and whose copy therefore has to be repaired pairwise.
16
+ * `ref_select` is absent because it repairs itself: its `labels` snapshot has
17
+ * always been mandatory (no display package can reach a vocabulary term). */
6
18
  const OPTION_VALUED = new Set(["select"]);
19
+ /**
20
+ * The type whose copy lives in a TREE on the category rather than in a flat
21
+ * table: `hierarchical_select` stores a path of option keys and
22
+ * `formatFeatureValue` walks `config.options` level by level to name each
23
+ * step, so a row without that tree prints "passenger / sedan" — the storage
24
+ * keys — exactly as a table-less `select` prints `b-u`.
25
+ *
26
+ * It is kept apart from {@link OPTION_VALUED} because the two repairs are not
27
+ * the same repair: a flat positional `labels` list cannot describe a tree, so
28
+ * there is nothing to merge and the category's tree is adopted whole or not at
29
+ * all. `formatFeatureValue` already keeps a step the tree does not contain as
30
+ * its raw value, so an adopted tree can only add copy, never blank one out.
31
+ */
32
+ const TREE_VALUED = new Set(["hierarchical_select"]);
7
33
  /** The canon's `FeatureDef.translate` vocabulary — three values, closed. */
8
34
  function isTranslateMode(value) {
9
35
  return value === "all" || value === "title" || value === "none";
10
36
  }
37
+ function categoryDefs(source) {
38
+ const defs = source.categoryFeatures;
39
+ if (defs === undefined || defs.length === 0)
40
+ return undefined;
41
+ const index = new Map();
42
+ for (const def of defs) {
43
+ // First wins: a duplicate slug in a category is a catalogue defect, and
44
+ // silently preferring the last one would make the copy depend on the
45
+ // order the endpoint happened to serialize.
46
+ if (typeof def.slug === "string" && def.slug.length > 0 && !index.has(def.slug)) {
47
+ index.set(def.slug, def);
48
+ }
49
+ }
50
+ return index.size === 0 ? undefined : index;
51
+ }
11
52
  /**
12
- * The identity option table for a stored `select` — see the module header.
53
+ * The category's definition OF THIS ROW, or `undefined`.
54
+ *
55
+ * Same slug and same value type, or it is not a definition of this row — see
56
+ * the module header on why a mismatch is ignored rather than forced.
57
+ */
58
+ function categoryDefFor(dao, defs) {
59
+ if (defs === undefined)
60
+ return undefined;
61
+ const def = defs.get(dao.slug);
62
+ if (def === undefined)
63
+ return undefined;
64
+ return featureType(def) === dao.type ? def : undefined;
65
+ }
66
+ /** A category def's declared option list, when it declares one. */
67
+ function declaredOptions(def) {
68
+ const raw = def?.config?.["options"];
69
+ return Array.isArray(raw) ? raw : undefined;
70
+ }
71
+ /** One entry of an option list → its `(value, label)` pair, when it is one. */
72
+ function optionPair(entry) {
73
+ if (entry === null || typeof entry !== "object")
74
+ return undefined;
75
+ const option = entry;
76
+ if (typeof option.value !== "string" || option.value.length === 0)
77
+ return undefined;
78
+ return {
79
+ value: option.value,
80
+ label: typeof option.label === "string" && option.label.length > 0 ? option.label : option.value,
81
+ };
82
+ }
83
+ /**
84
+ * The option table a stored `select` needs and does not carry — see the
85
+ * module header. The category's table underneath, the row's own `labels`
86
+ * snapshot on top, the values themselves as the floor.
87
+ *
88
+ * The alignment rule is the engine's own (`labels if len(labels) ==
89
+ * len(codes) else codes`): a snapshot of a different length than `value` is a
90
+ * snapshot of some other value list, and pairing the two anyway would print
91
+ * one option's copy against another option's value — worse than a slug,
92
+ * because it does not LOOK wrong. So a length mismatch drops the whole
93
+ * snapshot rather than pairing the overlap, and the row falls back to the
94
+ * category (or to identity). Within a usable snapshot, a missing or empty
95
+ * entry falls back to whatever the category, then the value itself, offers for
96
+ * that one pair.
13
97
  *
14
98
  * Returns `undefined` when there is nothing to add (another type, a config
15
- * that already carries a table, a value that is not a list of strings), so the
16
- * common path allocates nothing and a DAO that DOES carry options is left
17
- * exactly as it arrived.
99
+ * that already carries a table, a value that is not a list of strings and no
100
+ * category table either), so the common path allocates nothing and a DAO that
101
+ * DOES carry options is left exactly as it arrived — a stored table is a
102
+ * write-time snapshot of the whole question, which is a stronger statement
103
+ * about this listing than either the per-value snapshot or today's category.
18
104
  */
19
- function synthesizedOptions(dao, config) {
105
+ function selectOptions(dao, config, categoryDef) {
20
106
  if (typeof dao.type !== "string" || !OPTION_VALUED.has(dao.type))
21
107
  return undefined;
22
108
  if (Array.isArray(config["options"]))
23
109
  return undefined;
24
- const raw = Array.isArray(dao.value) ? dao.value : [dao.value];
25
- const values = raw.filter((item) => typeof item === "string");
26
- if (values.length === 0)
110
+ const raw = Array.isArray(dao.value)
111
+ ? dao.value
112
+ : [dao.value];
113
+ const snapshot = dao.labels;
114
+ const labels = Array.isArray(snapshot) && snapshot.length === raw.length
115
+ ? snapshot
116
+ : undefined;
117
+ // A Map so the three rungs can overwrite one another by value instead of
118
+ // the reader having to scan a list that carries the same value twice —
119
+ // `labelOf` takes the FIRST match, so a duplicate would make the losing
120
+ // rung win.
121
+ const table = new Map();
122
+ for (const entry of declaredOptions(categoryDef) ?? []) {
123
+ const pair = optionPair(entry);
124
+ if (pair !== undefined)
125
+ table.set(pair.value, pair.label);
126
+ }
127
+ raw.forEach((value, index) => {
128
+ if (typeof value !== "string")
129
+ return;
130
+ const label = labels?.[index];
131
+ if (typeof label === "string" && label.length > 0)
132
+ table.set(value, label);
133
+ else if (!table.has(value))
134
+ table.set(value, value);
135
+ });
136
+ if (table.size === 0)
27
137
  return undefined;
28
- return values.map((value) => ({ value, label: value }));
138
+ return [...table].map(([value, label]) => ({ value, label }));
139
+ }
140
+ /**
141
+ * The category's option TREE, adopted whole for a `hierarchical_select` that
142
+ * stored none — see {@link TREE_VALUED}.
143
+ *
144
+ * Nothing is merged and nothing is rewritten: the tree is the category's
145
+ * structure, and this projection has no per-level snapshot with which to
146
+ * disagree about it.
147
+ */
148
+ function adoptedTree(dao, config, categoryDef) {
149
+ if (typeof dao.type !== "string" || !TREE_VALUED.has(dao.type))
150
+ return undefined;
151
+ if (Array.isArray(config["options"]))
152
+ return undefined;
153
+ return declaredOptions(categoryDef);
29
154
  }
30
155
  /**
31
156
  * One DAO row → the definition/value pair the display half consumes.
@@ -35,7 +160,11 @@ function synthesizedOptions(dao, config) {
35
160
  * is a malformed record, and a synthesized index would key a badge to a
36
161
  * position that changes whenever the category does.
37
162
  */
38
- export function featureFromDao(dao) {
163
+ export function featureFromDao(dao, source = {}) {
164
+ return featureView(dao, categoryDefs(source));
165
+ }
166
+ /** The work of {@link featureFromDao}, against an already-built index. */
167
+ function featureView(dao, defs) {
39
168
  if (typeof dao.slug !== "string" || dao.slug.length === 0)
40
169
  return undefined;
41
170
  const config = {};
@@ -43,7 +172,8 @@ export function featureFromDao(dao) {
43
172
  if (!ENVELOPE.has(key))
44
173
  config[key] = value;
45
174
  }
46
- const options = synthesizedOptions(dao, config);
175
+ const categoryDef = categoryDefFor(dao, defs);
176
+ const options = selectOptions(dao, config, categoryDef) ?? adoptedTree(dao, config, categoryDef);
47
177
  if (options !== undefined)
48
178
  config["options"] = options;
49
179
  const feature = {
@@ -65,10 +195,11 @@ export function featureFromDao(dao) {
65
195
  * rows are dropped HERE, in one place, and counted by {@link
66
196
  * unreadableFeatureCount} so a skin can say how many rather than pretend the
67
197
  * listing had fewer attributes. */
68
- export function featuresFromDaoList(daos) {
198
+ export function featuresFromDaoList(daos, source = {}) {
199
+ const defs = categoryDefs(source);
69
200
  const out = [];
70
201
  for (const dao of daos ?? []) {
71
- const view = featureFromDao(dao);
202
+ const view = featureView(dao, defs);
72
203
  if (view !== undefined)
73
204
  out.push(view);
74
205
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/model/features.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/model/features.ts"],"names":[],"mappings":"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"}
@@ -75,6 +75,18 @@ export declare const IMAGES_FIELD = "images";
75
75
  export declare const CATEGORY_FIELD = "category_id";
76
76
  /** The coordinate pair, as one control: a latitude alone is not a place. */
77
77
  export declare const LOCATION_FIELD = "location";
78
+ /**
79
+ * The composer's OWN controls, in the order the draft declares them.
80
+ *
81
+ * The mirror is a `Record`, and a record has no order worth trusting — its
82
+ * feature refusals happen to come first because of a spread. "Which field is
83
+ * the first unsatisfied one?" is a question a person asks about a FORM, so the
84
+ * answer is written down as a list rather than read off an object: the
85
+ * category (nothing else can be answered until it is chosen), then the
86
+ * listing's own fields, then — appended by the caller — the category's
87
+ * features in the order the schema declares them.
88
+ */
89
+ export declare const LISTING_FIELD_ORDER: readonly string[];
78
90
  /**
79
91
  * The listing-level half of the mirror: everything that is not a feature
80
92
  * value. Returns refusals keyed by control, empty when nothing is wrong.
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/model/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,cAAc,EAAoB,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;2EACuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;qEAGiE;IACjE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;oEAGgE;IAChE,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;CACzC;AAED,eAAO,MAAM,oBAAoB,EAAE,kBAMlC,CAAC;AAEF;;4EAE4E;AAC5E,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAC5C,4EAA4E;AAC5E,eAAO,MAAM,cAAc,aAAa,CAAC;AAiCzC;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,kBAAkB,GACzB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAmDrC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,kBAAkB,GACzB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAKrC;AAED;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAElE;AAQD,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GACtB;IACE,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CAC3D,GACD;IACE;iEAC6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;CAChC,CAAC;AAEN;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAoB9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,GACd,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAiBrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,qBAAqB,GAC3B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAErC;AAED;qEACqE;AACrE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,qBAAqB,GAC3B,SAAS,uBAAuB,EAAE,CAEpC"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/model/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,cAAc,EAAoB,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;2EACuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;qEAGiE;IACjE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;oEAGgE;IAChE,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;CACzC;AAED,eAAO,MAAM,oBAAoB,EAAE,kBAMlC,CAAC;AAEF;;4EAE4E;AAC5E,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAC5C,4EAA4E;AAC5E,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOhD,CAAC;AAiCF;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,kBAAkB,GACzB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAmDrC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,kBAAkB,GACzB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAKrC;AAED;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAElE;AAQD,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GACtB;IACE,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CAC3D,GACD;IACE;iEAC6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;CAChC,CAAC;AAEN;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAoB9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,GACd,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAiBrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,qBAAqB,GAC3B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAErC;AAED;qEACqE;AACrE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,qBAAqB,GAC3B,SAAS,uBAAuB,EAAE,CAEpC"}
@@ -55,6 +55,25 @@ export const IMAGES_FIELD = "images";
55
55
  export const CATEGORY_FIELD = "category_id";
56
56
  /** The coordinate pair, as one control: a latitude alone is not a place. */
57
57
  export const LOCATION_FIELD = "location";
58
+ /**
59
+ * The composer's OWN controls, in the order the draft declares them.
60
+ *
61
+ * The mirror is a `Record`, and a record has no order worth trusting — its
62
+ * feature refusals happen to come first because of a spread. "Which field is
63
+ * the first unsatisfied one?" is a question a person asks about a FORM, so the
64
+ * answer is written down as a list rather than read off an object: the
65
+ * category (nothing else can be answered until it is chosen), then the
66
+ * listing's own fields, then — appended by the caller — the category's
67
+ * features in the order the schema declares them.
68
+ */
69
+ export const LISTING_FIELD_ORDER = [
70
+ CATEGORY_FIELD,
71
+ TITLE_FIELD,
72
+ DESCRIPTION_FIELD,
73
+ PRICE_FIELD,
74
+ LOCATION_FIELD,
75
+ IMAGES_FIELD,
76
+ ];
58
77
  /**
59
78
  * The API's own field names → the control that holds them.
60
79
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/model/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/model/validation.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/nav/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C;;iEAEiE;AACjE,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAE9C,eAAO,MAAM,UAAU,EAAE,SAAS,QAAQ,EAkDzC,CAAC"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/nav/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C;;iEAEiE;AACjE,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAE9C,eAAO,MAAM,UAAU,EAAE,SAAS,QAAQ,EAoDzC,CAAC"}
@@ -18,6 +18,7 @@ export const navEntries = [
18
18
  {
19
19
  id: "listings.compose",
20
20
  labelKey: "listings.nav.compose",
21
+ shortLabelKey: "listings.nav.compose.short",
21
22
  icon: "PlusOutlined",
22
23
  route: { path: "/new" },
23
24
  component: { export: "ListingComposerPage", subpath: "default" },
@@ -31,6 +32,7 @@ export const navEntries = [
31
32
  // Relative path: a child of the container's `/account` layout route.
32
33
  id: "listings.mine",
33
34
  labelKey: "listings.nav.mine",
35
+ shortLabelKey: "listings.nav.mine.short",
34
36
  icon: "ProfileOutlined",
35
37
  route: { path: "listings" },
36
38
  component: { export: "MyListingsPane", subpath: "default" },
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/nav/manifest.ts"],"names":[],"mappings":"AAyCA;;iEAEiE;AACjE,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC;AAE9C,MAAM,CAAC,MAAM,UAAU,GAAwB;IAC7C;QACE,EAAE,EAAE,iBAAiB;QACrB,QAAQ,EAAE,qBAAqB;QAC/B,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,SAAS,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE;QAC9D,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QAC3B,kBAAkB,EAAE,KAAK;QACzB,YAAY,EAAE,KAAK;QACnB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,QAAQ,EAAE,sBAAsB;QAChC,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACvB,SAAS,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,SAAS,EAAE;QAChE,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QAC3B,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;IACD;QACE,qEAAqE;QACrE,EAAE,EAAE,eAAe;QACnB,QAAQ,EAAE,mBAAmB;QAC7B,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;QAC3B,SAAS,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE;QAC3D,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;QAC1D,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,QAAQ,EAAE,wBAAwB;QAClC,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC5B,SAAS,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE;QAC1D,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;QAC1D,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;CACF,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/nav/manifest.ts"],"names":[],"mappings":"AAyCA;;iEAEiE;AACjE,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC;AAE9C,MAAM,CAAC,MAAM,UAAU,GAAwB;IAC7C;QACE,EAAE,EAAE,iBAAiB;QACrB,QAAQ,EAAE,qBAAqB;QAC/B,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,SAAS,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE;QAC9D,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QAC3B,kBAAkB,EAAE,KAAK;QACzB,YAAY,EAAE,KAAK;QACnB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,QAAQ,EAAE,sBAAsB;QAChC,aAAa,EAAE,4BAA4B;QAC3C,IAAI,EAAE,cAAc;QACpB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACvB,SAAS,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,SAAS,EAAE;QAChE,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QAC3B,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;IACD;QACE,qEAAqE;QACrE,EAAE,EAAE,eAAe;QACnB,QAAQ,EAAE,mBAAmB;QAC7B,aAAa,EAAE,yBAAyB;QACxC,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;QAC3B,SAAS,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE;QAC3D,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;QAC1D,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,QAAQ,EAAE,wBAAwB;QAClC,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC5B,SAAS,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE;QAC1D,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;QAC1D,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,EAAE;KACV;CACF,CAAC"}
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @stapel/listings-react 0.11.0
1
+ # @stapel/listings-react 0.13.0
2
2
 
3
3
  Headless React flow pair for stapel-listings (contract >=0.10 <0.11) — business + state, zero visual opinion.
4
4
  Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
3
3
  "package": "@stapel/listings-react",
4
- "version": "0.11.0",
4
+ "version": "0.13.0",
5
5
  "backend": {
6
6
  "module": "stapel-listings",
7
7
  "contract": ">=0.10 <0.11"
@@ -921,6 +921,7 @@
921
921
  "listings.compose.details_empty",
922
922
  "listings.compose.details_failed",
923
923
  "listings.compose.details_loading",
924
+ "listings.compose.details_no_category",
924
925
  "listings.compose.edit_title",
925
926
  "listings.compose.geo_incomplete",
926
927
  "listings.compose.invalid_summary",
@@ -938,6 +939,7 @@
938
939
  "listings.compose.save",
939
940
  "listings.compose.saved",
940
941
  "listings.compose.saving",
942
+ "listings.compose.show_first_missing",
941
943
  "listings.compose.stock",
942
944
  "listings.compose.title_label",
943
945
  "listings.compose.title_too_long",
@@ -998,9 +1000,11 @@
998
1000
  "listings.moderation.rejected",
999
1001
  "listings.moderation.rejected_still_live",
1000
1002
  "listings.nav.compose",
1003
+ "listings.nav.compose.short",
1001
1004
  "listings.nav.detail",
1002
1005
  "listings.nav.favorites",
1003
1006
  "listings.nav.mine",
1007
+ "listings.nav.mine.short",
1004
1008
  "listings.page.indicator",
1005
1009
  "listings.page.next",
1006
1010
  "listings.page.prev",
@@ -1123,6 +1127,7 @@
1123
1127
  "FavoriteToggleResponse",
1124
1128
  "FavoritesBag",
1125
1129
  "FeatureConfig",
1130
+ "FeatureCopySource",
1126
1131
  "FeatureDef",
1127
1132
  "FeatureValueDto",
1128
1133
  "FlowEndpoint",
package/nav-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@stapel/listings-react",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "entries": [
5
5
  {
6
6
  "id": "listings.detail",
@@ -24,6 +24,7 @@
24
24
  {
25
25
  "id": "listings.compose",
26
26
  "labelKey": "listings.nav.compose",
27
+ "shortLabelKey": "listings.nav.compose.short",
27
28
  "icon": "PlusOutlined",
28
29
  "route": {
29
30
  "path": "/new"
@@ -43,6 +44,7 @@
43
44
  {
44
45
  "id": "listings.mine",
45
46
  "labelKey": "listings.nav.mine",
47
+ "shortLabelKey": "listings.nav.mine.short",
46
48
  "icon": "ProfileOutlined",
47
49
  "route": {
48
50
  "path": "listings"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stapel/listings-react",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Headless React pair for stapel-listings: a typed client over the draft twin, the composer that turns a category schema into a submittable listing, and the owner's dashboard. Two independent axes are rendered as two — lifecycle `status` decides visibility and `moderation_status` decides nothing about it, so an edit to a live listing stays live and says 'under review' instead of vanishing. Feature values are drawn and mirrored by @stapel/attributes-react; photos arrive as an injected upload bag whose `refs` ARE `images_draft` and whose `settled` gates the submit; a publish refusal is routed onto the control that caused it by slug. Zero visual opinion in the main entry; an opt-in /default subpath ships the antd skin.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -48,9 +48,9 @@
48
48
  ],
49
49
  "size-limit": [
50
50
  {
51
- "name": "index — the headless pair (client + status axes + draft model + hooks): no antd. Raised 11 -> 12 KB for the elevation gate (useElevatableMandateGate + core's useElevation): the anonymous arm can now mint an identity for a named action instead of refusing, and that is a state hook the gate did not previously carry. Raised 11.5 -> 12 KB for envelopeFieldErrors and its API-field -> control table: a save-draft/create 400 names its field in the envelope rather than in a publish batch, and without the table the refusal had nowhere to land — which is how one over-precise coordinate painted two unreadable banners and left every control clean. Thirty-six bytes of routing table is what a legible refusal costs",
51
+ "name": "index — the headless pair (client + status axes + draft model + hooks): no antd. Raised 11 -> 12 KB for the elevation gate (useElevatableMandateGate + core's useElevation): the anonymous arm can now mint an identity for a named action instead of refusing, and that is a state hook the gate did not previously carry. Raised 11.5 -> 12 KB for envelopeFieldErrors and its API-field -> control table: a save-draft/create 400 names its field in the envelope rather than in a publish batch, and without the table the refusal had nowhere to land — which is how one over-precise coordinate painted two unreadable banners and left every control clean. Thirty-six bytes of routing table is what a legible refusal costs. Raised 12 -> 13 KB for two seams the mobile wave needed in the HEADLESS half: the category-feature copy source in model/features.ts (the option table a stored select does not carry, so a published listing prints \"Second-hand\" and not \"b-u\"), and firstUnsatisfied (the field a \"10 required details are still empty\" count actually points at, in the order the form asks). Both are model, not skin: a headless host renders its own controls and needs the same two answers",
52
52
  "path": "dist/index.js",
53
- "limit": "12 KB"
53
+ "limit": "13 KB"
54
54
  },
55
55
  {
56
56
  "name": "default — the antd skin (three cards, detail, composer, dashboard, the named slots and the delete confirmation) must stay out of the main bundle. Raised 17 -> 19 KB for the mobile wave: <ListingSerpCard> (photo strip + price-first block + action rail), <ListingFeedCard> and <FeedGrid> are two more card surfaces on the same shared target/favourite/photo parts, not three copies of one",
@@ -102,13 +102,13 @@
102
102
  "size-limit": "^11.2.0",
103
103
  "typescript": "^5.8.3",
104
104
  "vitest": "^3.2.4",
105
- "@stapel/attributes-react": "^0.5.0",
106
- "@stapel/core": "^0.21.0",
107
- "@stapel/currencies-react": "^0.2.0",
105
+ "@stapel/attributes-react": "^0.7.0",
106
+ "@stapel/core": "^0.22.0",
107
+ "@stapel/currencies-react": "^0.3.0",
108
108
  "@stapel/image": "^0.4.2",
109
109
  "@stapel/showcase": "^0.3.0",
110
110
  "@stapel/tokens": "^0.6.0",
111
- "@stapel/tokens-antd": "^0.10.0"
111
+ "@stapel/tokens-antd": "^0.11.0"
112
112
  },
113
113
  "engines": {
114
114
  "node": ">=22"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$generated": "by scripts/gen-events.mjs — do not edit; drift-gated (pnpm gen:events:check)",
3
3
  "package": "@stapel/listings-react",
4
- "version": "0.11.0",
4
+ "version": "0.13.0",
5
5
  "defined": [],
6
6
  "flows": []
7
7
  }
package/src/api/types.ts CHANGED
@@ -176,6 +176,16 @@ export interface ListingFeatureDao {
176
176
  * can lack it and a JSONField will pass that through. */
177
177
  readonly type?: ListingFeatureType;
178
178
  readonly value?: unknown;
179
+ /**
180
+ * The write-time LABEL SNAPSHOT: the copy each entry of `value` had when the
181
+ * listing was stored, positionally aligned with it, one entry per value.
182
+ * `ref_select`/`ref_hierarchical_select` have always carried it (their codes
183
+ * name vocabulary terms no display package can reach) and `select` carries
184
+ * it from the release that snapshots option copy — so it is OPTIONAL, and a
185
+ * row stored before that one has no key at all. `model/features.ts` reads
186
+ * it, and says what a row without it falls back to.
187
+ */
188
+ readonly labels?: readonly string[];
179
189
  /** Display name or translation key; falls back to the slug. */
180
190
  readonly name?: string | null;
181
191
  readonly order?: number | null;
@@ -82,6 +82,7 @@ import { spacing } from "@stapel/tokens";
82
82
  import { FeatureBadges } from "@stapel/attributes-react/default";
83
83
  import type { ListingCard as ListingCardData } from "../api/types.js";
84
84
  import { asFeatureDaoList, featuresDtoFromDaoList, featuresFromDaoList } from "../model/features.js";
85
+ import type { FeatureCopySource } from "../model/features.js";
85
86
  import { lifecycleCaption } from "../model/status.js";
86
87
  import { useFavoriteToggle } from "../headless/Favorites.js";
87
88
  import { LISTINGS_I18N_KEYS } from "../i18n/keys.js";
@@ -89,7 +90,7 @@ import { HeartIcon } from "./icons.js";
89
90
  import { SignInLink } from "./SignInLink.js";
90
91
  import { ListingPhoto } from "./ListingPhoto.js";
91
92
  import { ListingPrice } from "./ListingPrice.js";
92
- import type { ThemeModeProp } from "./types.js";
93
+ import type { CategoryFeaturesProp, ThemeModeProp } from "./types.js";
93
94
 
94
95
  /**
95
96
  * How the card opens — ONE of three, and the type says so.
@@ -195,7 +196,10 @@ const BUTTON_TARGET_STYLE: CSSProperties = {
195
196
  cursor: "pointer",
196
197
  };
197
198
 
198
- export interface ListingCardBaseProps extends ThemeModeProp, SignInCtaProp {
199
+ export interface ListingCardBaseProps
200
+ extends ThemeModeProp,
201
+ SignInCtaProp,
202
+ CategoryFeaturesProp {
199
203
  readonly listing: ListingCardData;
200
204
  /** See {@link ListingCardBlockedReason}. Default `"text"`. */
201
205
  readonly blockedReason?: ListingCardBlockedReason;
@@ -309,7 +313,14 @@ export function ListingCard(props: ListingCardProps): ReactElement {
309
313
  const { token } = antdTheme.useToken();
310
314
 
311
315
  const badgeDaos = asFeatureDaoList(listing.features_badges);
312
- const badgeFeatures = featuresFromDaoList(badgeDaos);
316
+ // The category's own option table, when the surface has it: a stored
317
+ // `select` carries no table of its own, so without this a badge prints the
318
+ // storage slug. Absent on a mixed grid, which is why it is optional.
319
+ const copy: FeatureCopySource =
320
+ props.categoryFeatures !== undefined
321
+ ? { categoryFeatures: props.categoryFeatures }
322
+ : {};
323
+ const badgeFeatures = featuresFromDaoList(badgeDaos, copy);
313
324
  const badgeValues = featuresDtoFromDaoList(badgeDaos);
314
325
  const titleDaos = asFeatureDaoList(listing.features_title);
315
326
 
@@ -370,7 +381,9 @@ export function ListingCard(props: ListingCardProps): ReactElement {
370
381
  {titleDaos.length > 0 ? (
371
382
  <Typography.Text type="secondary" ellipsis>
372
383
  <FeatureBadges
373
- features={featuresFromDaoList(titleDaos).map((view) => view.feature)}
384
+ features={featuresFromDaoList(titleDaos, copy).map(
385
+ (view) => view.feature
386
+ )}
374
387
  values={featuresDtoFromDaoList(titleDaos)}
375
388
  />
376
389
  </Typography.Text>