diff --git a/use-crystallize/skills/content-model/SKILL.md b/use-crystallize/skills/content-model/SKILL.md index d89f189..697cdf1 100644 --- a/use-crystallize/skills/content-model/SKILL.md +++ b/use-crystallize/skills/content-model/SKILL.md @@ -116,7 +116,7 @@ See [Shapes Reference](references/shapes.md) and [Content Modelling Guide](refer ### "I need controlled options" -- **Selection** → Dropdown/checkboxes with predefined options +- **Selection** → Dropdown/checkboxes with predefined options. Every option needs `key` and `value`; also set `label` (optional, but good practice — the App UI displays it; default: same text as `value`) - **Switch** → Boolean flag - **Datetime** → Date/timestamp (type: `datetime`) - **Location** → Geographic coordinates @@ -484,8 +484,8 @@ Shape: Vase (product) "config": { "selection": { "options": [ - { "key": "plant", "value": "Plant" }, - { "key": "vase", "value": "Vase" } + { "key": "plant", "value": "Plant", "label": "Plant" }, + { "key": "vase", "value": "Vase", "label": "Vase" } ] } } @@ -555,10 +555,10 @@ Shape: Vase (product) "config": { "selection": { "options": [ - { "key": "low", "value": "Low Light" }, - { "key": "medium", "value": "Medium Light" }, - { "key": "bright", "value": "Bright Light" }, - { "key": "direct", "value": "Direct Sunlight" } + { "key": "low", "value": "Low Light", "label": "Low Light" }, + { "key": "medium", "value": "Medium Light", "label": "Medium Light" }, + { "key": "bright", "value": "Bright Light", "label": "Bright Light" }, + { "key": "direct", "value": "Direct Sunlight", "label": "Direct Sunlight" } ] } } @@ -570,10 +570,10 @@ Shape: Vase (product) "config": { "selection": { "options": [ - { "key": "small", "value": "Small (under 12\")" }, - { "key": "medium", "value": "Medium (12-24\")" }, - { "key": "large", "value": "Large (24-48\")" }, - { "key": "xl", "value": "Extra Large (48\"+)" } + { "key": "small", "value": "Small (under 12\")", "label": "Small (under 12\")" }, + { "key": "medium", "value": "Medium (12-24\")", "label": "Medium (12-24\")" }, + { "key": "large", "value": "Large (24-48\")", "label": "Large (24-48\")" }, + { "key": "xl", "value": "Extra Large (48\"+)", "label": "Extra Large (48\"+)" } ] } } @@ -920,8 +920,8 @@ Components can reference pieces (via `type: "piece"`) and shapes (via `itemRelat "config": { "selection": { "options": [ - { "key": "black", "value": "Black" }, - { "key": "white", "value": "White" } + { "key": "black", "value": "Black", "label": "Black" }, + { "key": "white", "value": "White", "label": "White" } ] } } diff --git a/use-crystallize/skills/content-model/references/components.md b/use-crystallize/skills/content-model/references/components.md index f01b398..7e8849f 100644 --- a/use-crystallize/skills/content-model/references/components.md +++ b/use-crystallize/skills/content-model/references/components.md @@ -92,7 +92,8 @@ for a mapping to an industry standard — one build stored the ETIM feature code - **Radio/Enum pattern**: min=1, max=1, required → exactly one selection, renders as radio buttons or dropdown - **Checkboxes pattern**: min=0, max=N → optional multi-select, renders as checkboxes, can be null Use when the options are a fixed, small set that don't need their own content. If options need enrichment (images, descriptions), use Item Relations instead (Semantic Bridge pattern). - - **API option structure**: `{ key: "red", value: "Red", isPreselected?: Boolean }` — `key` is used in queries/filters, `value` is what editors see + - **API option structure**: `{ key: "red", value: "Red", label: "Red", isPreselected?: Boolean }` — `key` is used in queries/filters, `value` is the option's value, `label` is what the App UI displays to editors + - **Set `label` on every option** when creating or updating a selection component. It is optional, but good practice: the App UI displays it. Default it to the same text as `value`. Supported by the Core API (Next and legacy) and mass operations. - **Switch** → true/false toggle. Use for: "Featured", "On Sale", "Available in store", "Organic certified". - **Datetime** → date with optional time (type: `datetime`). Use for: launch date, preorder availability, expiration, event scheduling. - **Location** → latitude/longitude. Use for: store locator, pickup points, product origin. @@ -264,7 +265,7 @@ When building a "Product Type" selector where each type (Smartphone, Laptop, Hea { "intent": "piece/create", "identifier": "smartphone-spec", "name": "Smartphone Spec", "components": [ { "id": "screen-size", "name": "Screen Size", "type": "numeric", "config": { "numeric": { "units": ["inch"] } } }, { "id": "storage", "name": "Storage", "type": "numeric", "config": { "numeric": { "units": ["GB", "TB"] } } }, - { "id": "os", "name": "Operating System", "type": "selection", "config": { "selection": { "options": [{ "key": "ios", "value": "iOS" }, { "key": "android", "value": "Android" }] } } } + { "id": "os", "name": "Operating System", "type": "selection", "config": { "selection": { "options": [{ "key": "ios", "value": "iOS", "label": "iOS" }, { "key": "android", "value": "Android", "label": "Android" }] } } } ] } { "intent": "piece/create", "identifier": "laptop-spec", "name": "Laptop Spec", "components": [ { "id": "screen-size", "name": "Screen Size", "type": "numeric", "config": { "numeric": { "units": ["inch"] } } }, diff --git a/use-crystallize/skills/content-model/references/create-shape-api.md b/use-crystallize/skills/content-model/references/create-shape-api.md index 06c91ee..d4b5e52 100644 --- a/use-crystallize/skills/content-model/references/create-shape-api.md +++ b/use-crystallize/skills/content-model/references/create-shape-api.md @@ -252,7 +252,8 @@ config: { selection: { options: { // REQUIRED — at least one option key: String! // REQUIRED — API value (e.g. "red") - value: String! // REQUIRED — display label (e.g. "Red") + value: String! // REQUIRED — option value (e.g. "Red") + label: String // optional, but set it — the text the App UI shows for the option (e.g. "Red") isPreselected?: Boolean }[] required?: Boolean @@ -264,7 +265,7 @@ config: { } ``` -**`options` is required** (non-nullable array). Each option requires `key` (the API identifier) and `value` (the display label). +**`options` is required** (non-nullable array). Each option requires `key` (the API identifier) and `value`. `label` is optional, but it is good practice to set it on every option — it is the text the App UI displays to editors. Use the same human-readable text as `value` unless the user asks for something different. `label` is accepted by the Core API (Next and legacy) and by mass operations. --- @@ -502,9 +503,9 @@ mutation CreateProductShape { config: { selection: { options: [ - { key: "gloss", value: "Gloss" } - { key: "satin", value: "Satin" } - { key: "matte", value: "Matte" } + { key: "gloss", value: "Gloss", label: "Gloss" } + { key: "satin", value: "Satin", label: "Satin" } + { key: "matte", value: "Matte", label: "Matte" } ] discoverable: true } diff --git a/use-crystallize/skills/content-model/references/design-patterns.md b/use-crystallize/skills/content-model/references/design-patterns.md index d3eed92..fb11d45 100644 --- a/use-crystallize/skills/content-model/references/design-patterns.md +++ b/use-crystallize/skills/content-model/references/design-patterns.md @@ -249,9 +249,9 @@ Parent Product "config": { "selection": { "options": [ - { "key": "g", "value": "grams" }, - { "key": "ml", "value": "milliliters" }, - { "key": "pcs", "value": "pieces" } + { "key": "g", "value": "grams", "label": "grams" }, + { "key": "ml", "value": "milliliters", "label": "milliliters" }, + { "key": "pcs", "value": "pieces", "label": "pieces" } ] } } @@ -450,10 +450,10 @@ The classification (role/meaning) can be a **Selection** (simple label) or an ** "config": { "selection": { "options": [ - { "key": "writer", "value": "Writer" }, - { "key": "illustrator", "value": "Illustrator" }, - { "key": "editor", "value": "Editor" }, - { "key": "translator", "value": "Translator" } + { "key": "writer", "value": "Writer", "label": "Writer" }, + { "key": "illustrator", "value": "Illustrator", "label": "Illustrator" }, + { "key": "editor", "value": "Editor", "label": "Editor" }, + { "key": "translator", "value": "Translator", "label": "Translator" } ] } } diff --git a/use-crystallize/skills/content-model/references/page-builder-pattern.md b/use-crystallize/skills/content-model/references/page-builder-pattern.md index e7be694..ee3c98b 100644 --- a/use-crystallize/skills/content-model/references/page-builder-pattern.md +++ b/use-crystallize/skills/content-model/references/page-builder-pattern.md @@ -101,8 +101,8 @@ Every block piece embeds the `layout` piece as a component. This gives editors p "config": { "selection": { "options": [ - { "key": "stretch", "value": "Stretch" }, - { "key": "contain", "value": "Contain" } + { "key": "stretch", "value": "Stretch", "label": "Stretch" }, + { "key": "contain", "value": "Contain", "label": "Contain" } ] } } @@ -113,11 +113,11 @@ Every block piece embeds the `layout` piece as a component. This gives editors p "config": { "selection": { "options": [ - { "key": "light", "value": "Light" }, - { "key": "dark", "value": "Dark" }, - { "key": "muted", "value": "Muted" }, - { "key": "pastel", "value": "Pastel" }, - { "key": "vivid", "value": "Vivid" } + { "key": "light", "value": "Light", "label": "Light" }, + { "key": "dark", "value": "Dark", "label": "Dark" }, + { "key": "muted", "value": "Muted", "label": "Muted" }, + { "key": "pastel", "value": "Pastel", "label": "Pastel" }, + { "key": "vivid", "value": "Vivid", "label": "Vivid" } ] } } diff --git a/use-crystallize/skills/mass-operations/references/limits.md b/use-crystallize/skills/mass-operations/references/limits.md index 63ae962..6eabd1b 100644 --- a/use-crystallize/skills/mass-operations/references/limits.md +++ b/use-crystallize/skills/mass-operations/references/limits.md @@ -207,7 +207,7 @@ Minimums and shape rules, not maximums. - `componentChoice` requires **≥ 2** choices; `componentMultipleChoice` **≥ 1**; `contentChunk` **≥ 1** component. - `contentChunk` with `repeatable: false` accepts exactly **1** chunk. -- `selection` needs ≥ 1 option, keys unique. +- `selection` needs ≥ 1 option, keys unique. `label` is optional, but set it on every option as good practice (the App UI displays it), normally the same as its `value`. - `product/*` requires a **non-empty `variants`** array; `pricelist/*` a non-empty `priceVariants`; `item/flow/stage/addItems` a non-empty `items`. - Component identifiers must be **unique within a component list**.