@polyxd/a2ui 0.1.1 → 0.2.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/catalog/catalog.json +1408 -78
- package/dist/mapping.d.ts +1 -1
- package/dist/mapping.js +11 -0
- package/dist/mapping.js.map +1 -1
- package/package.json +2 -2
package/catalog/catalog.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"title": "Polyxd catalog",
|
|
6
6
|
"description": "Polyxd semantic components as an A2UI v1.0 catalog. Every component is a faithful projection of the Polyxd component with the same name and props. Generated from @polyxd/spec components/*.json by @polyxd/a2ui (npm run build:catalog).",
|
|
7
7
|
"catalogId": "https://polyxd.com/catalog/0.1/a2ui",
|
|
8
|
-
"instructions": "# Polyxd catalog for A2UI\n\nSemantic components for just-in-time interfaces. The renderer maps each one onto its own native, design-system components and tokens. Pick components by meaning, not by look. Never send colours, sizes or fonts.\n\n## Rules for every surface\n\n1. The top-level component has `\"id\": \"root\"`. Children are referenced by id (flat adjacency list), never nested inline.\n2. Data always comes from the host through JSON Pointer bindings `{\"path\": \"/...\"}`. Never invent data or pre-format numbers and dates into strings. Set `format` instead.\n3. Inside a templated list (`Collection.items`), relative paths such as `{\"path\": \"title\"}` resolve against the current item. Absolute paths start with `/`.\n4. Actions are declared capability intents: `{\"event\": {\"name\": \"transfer.confirm\", \"context\": {...}}}`. Use `{\"functionCall\": {\"call\": \"dismiss\" | \"back\" | \"next\"}}` for navigation the renderer handles itself.\n5. At most one primary action is visible at a time. A Form's submit and a Steps finish count as primary.\n6. Destructive or consequential actions go through `Confirm`.\n7. Components carry their own roles and names. Use `accessibility` only to add to them.\n\n## Components\n\n### Action\n\nA button that triggers a host capability.\n\n- **Use when:**\n - Anything the user can do that isn't typing or choosing\n- **Don't use when:**\n - Navigating between views: use Views\n - Confirming something destructive: wrap in Confirm\n- **Rendering:**\n - At most one primary action visible at a time\n - danger tone uses color.action.danger.*\n- **Accessibility** (role: button):\n - Label describes the outcome\n - Target at least size.target.min\n - Disabled actions explain why nearby\n- **Agents:** Activate by label.\n\n### ActionBar\n\nThe set of actions for a surface or section; the renderer places it where that platform expects.\n\n- **Use when:**\n - Two or more actions that apply to the whole surface or section\n- **Don't use when:**\n - A single action inline with content: use Action directly\n- **Rendering:**\n - Web: bottom of the section, primary last on desktop and first on mobile stacks\n - iOS/Android: toolbar or bottom bar on compact screens\n- **Accessibility** (role: toolbar / group):\n - Order in the accessibility tree is order of importance\n- **Agents:** Actions are listed together.\n\n### Card\n\nOne self-contained entity (an account, an order, a place), optionally actionable as a whole.\n\n- **Use when:**\n - Items in a Collection that each represent an entity\n - A single entity summary in a larger surface\n- **Don't use when:**\n - Plain grouping: use Group\n - Tabular data with many attributes: use Table\n- **Rendering:**\n - If 'action' is set, the whole card opens it; controls in children (e.g. a habit's done Toggle) sit above that target and act on their own\n - Uses surface.raised and radius.default\n - 'progress' renders a progress bar with its label or percentage\n- **Accessibility** (role: article (or link/button when it has an action)):\n - Title is the accessible name\n - When actionable, the title is the card's one link; controls inside it (a Toggle, an Action) stay separate targets with their own names\n- **Agents:** Activate the card by its title; use controls inside it by their own labels.\n\n### Chart\n\nA visual summary of data, always paired with a text summary.\n\n- **Use when:**\n - A trend, comparison, share or spread matters more than exact values\n- **Don't use when:**\n - Exact values matter most: use Table or Metric\n - A single number: use Metric\n- **Rendering:**\n - trend → line, comparison → bar, composition → stacked bar (pie only for ≤ 4 parts), distribution → histogram\n - Series colors use color.data.categorical.N in order\n- **Accessibility** (role: img (figure) with the summary as description, plus a data-table alternative):\n - 'summary' states the takeaway in words\n - Series are distinguishable without color (labels, markers)\n - The underlying data is available as a table\n- **Agents:** Reads the summary, and the data through the table alternative.\n\n### Choice\n\nPick one or several options from a known set. The renderer chooses the control.\n\n- **Use when:**\n - Any choice from a known set of options\n- **Don't use when:**\n - On/off setting: use Toggle\n - Picking between rich entities by comparing attributes: use Comparison\n- **Rendering:**\n - single, 2–4 short options → segmented control or radios\n - single, 5–10 → radios (or select on compact screens)\n - single, > 10 → searchable select\n - multiple, ≤ 10 → checkboxes; > 10 → searchable multi-select\n - Option order comes from host data or remembers the last order used\n- **Accessibility** (role: radiogroup / group of checkboxes / listbox / combobox (depends on rendering)):\n - Visible group label\n - Every option has a text label\n- **Agents:** Select options by label.\n\n### Collection\n\nA list of items from host data, each rendered with the same template.\n\n- **Use when:**\n - Browsing a set of similar entities\n - Search results\n- **Don't use when:**\n - Attributes compared across items: use Table or Comparison\n - Choosing an option in a form: use Choice\n- **Rendering:**\n - Long lists are virtualized by the renderer\n - Items keep their order from host data\n - grid: 2 columns on phones, more as width allows; list: one item per row\n - auto: grid when the item template is a Card with media, otherwise list\n - 'timeline' marks each item on a line, newest first, for activity feeds\n- **Accessibility** (role: list / listitem (listbox when selectable)):\n - Announces the item count\n - An empty state is provided\n- **Agents:** Items are enumerated with their titles; each item exposes its own actions.\n\n### Comparison\n\nCompare a few options across the same attributes, and choose one.\n\n- **Use when:**\n - Choosing between 2–4 plans, products, routes or offers\n- **Don't use when:**\n - More than ~5 items: use Table with sorting\n - No decision needed: use Table\n- **Rendering:**\n - Wide: items as columns; compact: one card per item with the same attribute order\n - Best values per attribute are marked when 'better' is set\n - Exactly one item may be recommended; its badge carries recommendedReason\n - Attributes with the same group sit under one heading\n - Boolean values render as a check or a dash with text alternatives ('Included' / 'Not included')\n - On compact surfaces the recommended item comes first\n- **Accessibility** (role: table (items as columns on wide screens) or list of cards):\n - Attribute names are headers\n - 'better' is conveyed in text, not only color\n- **Agents:** Reads attributes per item; choose actions are named with the item title.\n\n### Confirm\n\nAsks the user to confirm a consequential or destructive action, showing what will happen.\n\n- **Use when:**\n - Moving money, deleting data, sending on someone's behalf, anything irreversible\n- **Don't use when:**\n - Routine reversible actions (prefer undo)\n - Information only: use Status\n- **Rendering:**\n - destructive uses color.action.danger.*\n - Capabilities with high risk level must use Confirm (enforced by the verifier)\n - the consequence sits directly above the confirm button\n - amount and subject lead the dialog when set\n - consequences render as an icon list, two columns on wide surfaces\n- **Accessibility** (role: alertdialog):\n - Focus starts on the least destructive option\n - Confirm label repeats the action verb\n - Escape cancels\n- **Agents:** Reads title and consequence; confirm and cancel are named buttons.\n\n### DateInput\n\nA date, time, date-time or date range.\n\n- **Use when:**\n - Any date or time entry\n- **Don't use when:**\n - Relative choices like 'This month / Last month': use Choice\n- **Rendering:**\n - Memorable dates (birthdays) use separate day/month/year fields; near dates use a calendar\n- **Accessibility** (role: group of spinbuttons or a date picker dialog):\n - Typing the date is always possible, not only picking from a calendar\n- **Agents:** Fill by label with an ISO date.\n\n### DetailList\n\nLabel/value pairs describing one thing (a summary, a receipt, a review step).\n\n- **Use when:**\n - Reviewing before submitting\n - Showing the attributes of one entity\n - Receipts\n - Fees, prices and totals before someone commits (variant 'receipt')\n- **Don't use when:**\n - Many entities with the same attributes: use Table\n - Comparing entities: use Comparison\n- **Rendering:**\n - Keeps the item order stable across generations (keys are remembered)\n - receipt: values right-aligned in tabular figures, the total row emphasised; people read amounts from the right\n - 'grid' lays fields out in columns by width, label above value\n- **Accessibility** (role: list of term/definition pairs (dl)):\n - Label and value are programmatically associated\n- **Agents:** Read each label with its value.\n\n### Disclosure\n\nProgressive disclosure: secondary content hidden behind a toggle.\n\n- **Use when:**\n - Details most people don't need (fees breakdown, advanced options, help text)\n- **Don't use when:**\n - Content everyone needs to complete the task\n - Primary navigation\n- **Rendering:**\n - Never hide required inputs or the primary action inside a closed Disclosure\n- **Accessibility** (role: button (aria-expanded) + region):\n - Summary is a button with expanded state\n - Hidden content is not in the tab order while closed\n- **Agents:** Expand by the summary text; state is exposed as expanded/collapsed.\n\n### FilterPanel\n\nFilters for a list of results, with the result count.\n\n- **Use when:**\n - Browsing results people narrow by several attributes\n - More than two filters, or filters that take space (ranges, long lists)\n- **Don't use when:**\n - One or two quick filters: put a Choice (chips) above the results\n - Filling in information: use Form\n- **Rendering:**\n - Wide: filters in a sidebar beside the results\n - Compact: a 'Filters · n' button opens a bottom sheet whose action says 'Show n results'\n - Active filters show as removable chips above the results\n - Filters apply as they change (no separate Apply on wide)\n- **Accessibility** (role: region (filters) plus the results):\n - The result count is announced politely when it changes\n - Each active filter can be removed with a named button ('Remove filter: Desk')\n- **Agents:** Set filter inputs by label; read the result count; remove filters by their Remove buttons.\n\n### Form\n\nCollects inputs and submits them together.\n\n- **Use when:**\n - Any set of inputs that are submitted together\n- **Don't use when:**\n - Settings that apply immediately: use Toggles with actions\n - Several distinct stages: use Steps\n- **Rendering:**\n - One column; labels above fields\n - Submit is the primary action; cancel is secondary\n - Submit context is built from the form's input bindings\n - 'horizontal' becomes stacked on compact surfaces\n - 'aside' sits beside the form on wide surfaces; on compact ones it comes first, before the fields, so people read what they are agreeing to\n- **Accessibility** (role: form):\n - Submit is a real submit button\n - On submit errors, focus moves to an error summary that links to each field\n- **Agents:** Fill fields by label, then activate the submit button by its label.\n\n### Group\n\nVisually groups closely related items without a heading (proximity).\n\n- **Use when:**\n - A few items that belong together (a key figure and its caption, several metrics)\n- **Don't use when:**\n - The group needs a heading: use Section\n - Choosing between items: use Choice or Comparison\n- **Rendering:**\n - 'inline' collapses to a stack below the compact breakpoint\n - Gap uses space.stack.default or space.inline.default\n- **Accessibility** (role: group):\n - Has an accessible name when it contains interactive items\n- **Agents:** Treated as one unit when its label is present.\n\n### Media\n\nAn image supplied by the host.\n\n- **Use when:**\n - Photos or illustrations that help identify something (a product, a place, a person)\n- **Don't use when:**\n - Decoration with no information\n - Icons for actions (renderer supplies those)\n- **Rendering:**\n - Images never convey information that is not also in text\n- **Accessibility** (role: img):\n - Has alt text unless decorative (then hidden from assistive technology)\n- **Agents:** Reads the alt text.\n\n### Metric\n\nA key figure with a label, and optionally its change.\n\n- **Use when:**\n - One to four headline numbers the user asked about\n- **Don't use when:**\n - Many numbers: use Table or DetailList\n - Trends over time: use Chart\n- **Rendering:**\n - Value uses type.numeric.display\n - Change uses color.data.positive / negative according to 'favorable'\n- **Accessibility** (role: group (label + value)):\n - Change direction is conveyed in text as well as color\n - Screen readers read label, value and change as one sentence\n- **Agents:** Read label and value.\n\n### Navigation\n\nThe product's main navigation.\n\n- **Use when:**\n - Software with sections people move between (B2B apps, dashboards)\n - Only when the host doesn't already provide navigation\n- **Don't use when:**\n - Steps of one task: use Steps\n - Sections of one record: use Views\n - A surface embedded in a host that has its own navigation\n- **Rendering:**\n - Wide: a side navigation with grouped items\n - Compact: a menu button that opens the navigation\n - Badges sit at the end of their item\n- **Accessibility** (role: navigation):\n - The current item carries aria-current=\"page\"\n - Badges say what they count ('12 overdue')\n- **Agents:** Move between sections by activating items by their labels.\n\n### RangeInput\n\nA number, or a range between two numbers, within known bounds.\n\n- **Use when:**\n - Approximate values within a range (budget cap, volume)\n - A price or date range for filtering (mode 'range')\n- **Don't use when:**\n - Exact values: use TextInput with kind 'number' or 'currency'\n- **Rendering:**\n - Shows min, max and the current formatted value\n - mode 'range' shows two thumbs and min/max fields that stay in sync\n- **Accessibility** (role: slider):\n - Current value is shown as text\n - Keyboard arrows change the value by step\n- **Agents:** Set the value directly by label.\n\n### Section\n\nA titled region of the surface that groups related content under a heading.\n\n- **Use when:**\n - The surface has two or more distinct topics (e.g. 'Recipient' and 'Amount')\n - Content would otherwise exceed one screen and needs signposting\n- **Don't use when:**\n - Only one topic: put content directly under the root\n - Visual grouping without a heading: use Group\n- **Rendering:**\n - Heading level follows nesting depth, never chosen by the model\n - Spacing between sections uses space.stack.section\n- **Accessibility** (role: region (with heading)):\n - Title is rendered as a real heading; nesting depth sets the heading level\n - Title is the region's accessible name\n- **Agents:** Navigate by heading; the title names the region.\n\n### Status\n\nFeedback about state: info, success, warning, error, empty or loading.\n\n- **Use when:**\n - Results of an action\n - Empty collections\n - Errors with a way to recover\n - Loading states\n - 'undo': after a reversible action ran, say what happened and offer Undo instead of asking first\n- **Don't use when:**\n - Validation errors on a field: inputs show their own errors\n - Confirmation before acting: use Confirm\n- **Rendering:**\n - error and warning use color.status.* tokens and an icon\n - empty states explain why and what to do next\n - loading shows a skeleton when layout is known, otherwise a progress indicator\n - 'undo' renders as a snackbar at the bottom of the surface, announced politely, with the Undo action\n - Empty states may carry an ActionBar: one primary and one secondary action\n - 'inline' renders a bordered notice with its action on the right\n- **Accessibility** (role: status or alert (live region)):\n - success/info/loading are polite live regions; error is assertive\n - Meaning is in text, not only color or icon\n- **Agents:** Reads the title and message; the recovery action is exposed.\n\n### Steps\n\nA task split into ordered steps with visible progress.\n\n- **Use when:**\n - Tasks with dependent stages or too many inputs for one view (checkout, onboarding)\n- **Don't use when:**\n - Independent views: use Views\n - Under ~6 inputs: a single Form\n- **Rendering:**\n - Renderer provides Back (ui.back) and Next (ui.next); the last step shows 'finish'\n - Each step validates before moving on\n- **Accessibility** (role: group with step progress (aria-current on the current step)):\n - Current step and total are announced\n - Back never loses entered data\n- **Agents:** Reads 'step N of M'; next/back are exposed as buttons.\n\n### Table\n\nTabular data: many items sharing the same attributes.\n\n- **Use when:**\n - Scanning or comparing many rows by several attributes\n - Records people scan, sort, select and act on in bulk (B2B lists)\n- **Don't use when:**\n - One entity: use DetailList\n - A few entities where the user must choose: use Comparison\n- **Rendering:**\n - On compact screens, rows become stacked cards with label/value pairs\n - Alignment follows the column format, never chosen by the model\n - Numbers and currency are right-aligned with tabular figures; 'status' renders as a tag using 'tones'\n - On compact surfaces the table becomes a list of rows: the entity, the key fields in one line, and the status\n - Selection replaces the toolbar with the bulk-action bar while rows are selected\n - Paging shows rows per page, the range and the total\n- **Accessibility** (role: table with caption and column headers):\n - Has a caption\n - Column headers are real header cells\n - Numeric columns are right-aligned by format\n - Sortable headers carry aria-sort and say what sorting does\n - The select-all checkbox is mixed when some rows are selected\n - The bulk-action bar names how many rows are selected, announced politely\n - Each row's action menu is named after its row\n- **Agents:** Read by row and column headers; rows with rowAction are activatable. Sort by activating a column header; select rows by their checkboxes; act in bulk from the bar that appears.\n\n### Text\n\nA run of text.\n\n- **Use when:**\n - Explanations, instructions, messages\n- **Don't use when:**\n - Headings: use Section title\n - Label/value pairs: use DetailList\n - Key figures: use Metric\n- **Rendering:**\n - 'supporting' uses color.text.muted\n - No inline styling; emphasis comes from structure\n- **Accessibility** (role: text):\n - Body text is at least 16px (type.body.default)\n - Line length is capped by measure.max\n- **Agents:** Read as text.\n\n### TextInput\n\nA single text-like value: text, number, email, phone, currency, search or long text.\n\n- **Use when:**\n - Free-form values the user types\n- **Don't use when:**\n - A value from a known set: use Choice\n - Dates: use DateInput\n - Secrets (passwords, card numbers): not generated; hosts provide their own secure flows\n- **Rendering:**\n - Width suggests expected length\n - Errors appear after the user leaves the field or submits, not while typing\n - kind 'search' renders as a pill search field with an icon; the label stays as its accessible name\n - size 'hero' renders a large centred amount with the currency symbol dimmed\n- **Accessibility** (role: textbox / searchbox / spinbutton):\n - Visible label, never placeholder-only\n - Help and errors are associated with the field\n - Kind sets the right keyboard and autocomplete\n- **Agents:** Fill by label.\n\n### Toggle\n\nAn on/off setting.\n\n- **Use when:**\n - Settings that take effect immediately\n - A single yes/no inside a form\n- **Don't use when:**\n - Choosing between named options: use Choice\n- **Rendering:**\n - With 'action' it renders as a switch; inside a Form without action, as a checkbox\n- **Accessibility** (role: switch (immediate) / checkbox (in a form)):\n - Label says what 'on' means\n- **Agents:** Toggle by label; state is exposed as on/off.\n\n### Views\n\nSwitch between alternative views of the same subject (tabs).\n\n- **Use when:**\n - 2–6 peer views of the same data (Overview / Transactions / Settings)\n- **Don't use when:**\n - Sequential steps: use Steps\n - Filtering one list: use Choice\n- **Rendering:**\n - More than 4 views on compact screens become a menu or scrollable tabs\n - Counts sit beside their labels and are part of the tab's accessible name\n- **Accessibility** (role: tablist / tab / tabpanel):\n - Each tab has a visible label\n - Arrow keys move between tabs\n- **Agents:** Select a view by its label.\n",
|
|
8
|
+
"instructions": "# Polyxd catalog for A2UI\n\nSemantic components for just-in-time interfaces. The renderer maps each one onto its own native, design-system components and tokens. Pick components by meaning, not by look. Never send colours, sizes or fonts.\n\n## Rules for every surface\n\n1. The top-level component has `\"id\": \"root\"`. Children are referenced by id (flat adjacency list), never nested inline.\n2. Data always comes from the host through JSON Pointer bindings `{\"path\": \"/...\"}`. Never invent data or pre-format numbers and dates into strings. Set `format` instead.\n3. Inside a templated list (`Collection.items`), relative paths such as `{\"path\": \"title\"}` resolve against the current item. Absolute paths start with `/`.\n4. Actions are declared capability intents: `{\"event\": {\"name\": \"transfer.confirm\", \"context\": {...}}}`. Use `{\"functionCall\": {\"call\": \"dismiss\" | \"back\" | \"next\"}}` for navigation the renderer handles itself.\n5. At most one primary action is visible at a time. A Form's submit and a Steps finish count as primary.\n6. Destructive or consequential actions go through `Confirm`.\n7. Components carry their own roles and names. Use `accessibility` only to add to them.\n\n## Components\n\n### Action\n\nA button that triggers a host capability.\n\n- **Use when:**\n - Anything the user can do that isn't typing or choosing\n- **Don't use when:**\n - Navigating between views: use Views\n - Confirming something destructive: wrap in Confirm\n- **Rendering:**\n - At most one primary action visible at a time\n - danger tone uses color.action.danger.*\n - 'description' sits under the label in type.body.small, muted; the button's accessible description\n - ui.copy is handled by the renderer: it copies 'copy' (or the context's 'text') and announces 'Copied' politely\n- **Accessibility** (role: button):\n - Label describes the outcome\n - Target at least size.target.min\n - Disabled actions explain why nearby\n- **Agents:** Activate by label.\n\n### ActionBar\n\nThe set of actions for a surface or section; the renderer places it where that platform expects.\n\n- **Use when:**\n - Two or more actions that apply to the whole surface or section\n- **Don't use when:**\n - A single action inline with content: use Action directly\n- **Rendering:**\n - Web: bottom of the section, primary last on desktop and first on mobile stacks\n - iOS/Android: toolbar or bottom bar on compact screens\n- **Accessibility** (role: toolbar / group):\n - Order in the accessibility tree is order of importance\n- **Agents:** Actions are listed together.\n\n### ActionMenu\n\nSecondary actions behind one control: an overflow menu, a dropdown, a split button or a context menu.\n\n- **Use when:**\n - Three or more secondary actions on a row, a card or a page header\n - One usual action with rarer alternatives (split: 'Save' with 'Save as draft')\n - Actions that belong to the thing under the pointer (context)\n- **Don't use when:**\n - One or two actions: use Action or ActionBar, where they are visible\n - The main thing to do on the surface: never hidden in a menu\n - Navigation between views: use Views or Navigation\n- **Rendering:**\n - The menu uses color.surface.overlay with elevation.overlay and radius.default; items are size.control.default tall with space.inset.default\n - A danger-toned Action shows in color.status.danger.emphasis after a divider\n - The overflow control is an icon-only button at size.target.min with the label as its accessible name; a dropdown shows the label with a chevron\n - A split's two parts share one outline; the menu part is at least size.target.min wide\n- **Accessibility** (role: a menu button (aria-haspopup, aria-expanded) opening a menu of menuitems; a split's main part is a plain button):\n - Every action is reachable by keyboard: arrows move, Enter activates, Escape closes and returns focus\n - An overflow control is named for what it holds ('More actions for Acme Corp'), never just '…'\n - A context menu's actions are also reachable another way (an overflow control), since right-click and long-press aren't discoverable\n- **Agents:** Opens the menu by its name and activates an action by its label.\n\n### Card\n\nOne self-contained entity (an account, an order, a place), optionally actionable as a whole.\n\n- **Use when:**\n - Items in a Collection that each represent an entity\n - A single entity summary in a larger surface\n- **Don't use when:**\n - Plain grouping: use Group\n - Tabular data with many attributes: use Table\n- **Rendering:**\n - If 'action' is set, the whole card opens it; controls in children (e.g. a habit's done Toggle) sit above that target and act on their own\n - Uses surface.raised and radius.default\n - 'progress' renders a progress bar with its label or percentage\n- **Accessibility** (role: article (or link/button when it has an action)):\n - Title is the accessible name\n - When actionable, the title is the card's one link; controls inside it (a Toggle, an Action) stay separate targets with their own names\n- **Agents:** Activate the card by its title; use controls inside it by their own labels.\n\n### Chart\n\nA visual summary of data, always paired with a text summary.\n\n- **Use when:**\n - A trend, comparison, share or spread matters more than exact values\n- **Don't use when:**\n - Exact values matter most: use Table or Metric\n - A single number: use Metric\n- **Rendering:**\n - trend → line, comparison → bar, composition → stacked bar (pie only for ≤ 4 parts), distribution → histogram\n - relationship → scatter (x is a measure too), flow → stacked flows from each x value to each series, hierarchy → treemap of the first series, matrix → heatmap of x values by series, range → bars from the first series to the second\n - Series colors use color.data.categorical.N in order; a matrix shades one color by value and prints the value in each cell\n- **Accessibility** (role: img (figure) with the summary as description, plus a data-table alternative):\n - 'summary' states the takeaway in words\n - Series are distinguishable without color (labels, markers)\n - The underlying data is available as a table\n- **Agents:** Reads the summary, and the data through the table alternative.\n\n### Choice\n\nPick one or several options from a known set. The renderer chooses the control.\n\n- **Use when:**\n - Any choice from a known set of options\n- **Don't use when:**\n - On/off setting: use Toggle\n - Picking between rich entities by comparing attributes: use Comparison\n- **Rendering:**\n - single, 2–4 short options → segmented control or radios\n - single, 5–10 → radios (or select on compact screens)\n - single, > 10 → searchable select\n - multiple, ≤ 10 → checkboxes; > 10 → searchable multi-select\n - Option order comes from host data or remembers the last order used\n- **Accessibility** (role: radiogroup / group of checkboxes / listbox / combobox (depends on rendering)):\n - Visible group label\n - Every option has a text label\n- **Agents:** Select options by label.\n\n### Code\n\nCode, a command or preformatted text, shown as written and copyable.\n\n- **Use when:**\n - A command to run, a snippet to paste, an identifier to copy\n - Structured text whose spacing matters\n- **Don't use when:**\n - Prose: use Text\n - Something the person types: use TextInput\n- **Rendering:**\n - type.mono at type.body.small on color.surface.subtle, with radius.control\n - Overflow scrolls sideways unless wrap is set; never clipped\n - The copy control sits in the top-right corner and says 'Copied' for two seconds after use\n- **Accessibility** (role: region named by the label, holding a code element; the copy control is a button named 'Copy <label>'):\n - Text is real text: selectable and read by screen readers line by line\n - Copying is announced ('Copied')\n - A secret is masked with the same length, with a 'Show' control\n- **Agents:** Reads the text verbatim; can activate Copy.\n\n### CodeInput\n\nA one-time code or PIN, typed into one box per character.\n\n- **Use when:**\n - A verification code from email or SMS\n - A PIN or a short recovery code\n- **Don't use when:**\n - A password: the host's own sign-in flow, never a generated screen\n - Any text longer than twelve characters: use TextInput\n- **Rendering:**\n - Boxes are size.control.large squares with radius.control, type.heading.small, centred, in type.mono\n - The active box shows color.border.focus; a filled box shows color.border.strong\n - Boxes are grouped in threes or fours by a wider gap past six characters\n- **Accessibility** (role: a group named by the label; one text input per character, each named 'Digit N of M'):\n - Typing moves focus forward; Backspace moves it back; pasting the whole code fills every box\n - The numeric kind opens the numeric keyboard and accepts autofill of one-time codes\n - Errors are said against the group, not one box\n- **Agents:** Reads the label and length; enters the code.\n\n### Collection\n\nA list of items from host data, each rendered with the same template.\n\n- **Use when:**\n - Browsing a set of similar entities\n - Search results\n- **Don't use when:**\n - Attributes compared across items: use Table or Comparison\n - Choosing an option in a form: use Choice\n- **Rendering:**\n - Long lists are virtualized by the renderer\n - Items keep their order from host data\n - grid: 2 columns on phones, more as width allows; list: one item per row\n - auto: grid when the item template is a Card with media, otherwise list\n - 'timeline' marks each item on a line, newest first, for activity feeds\n - 'carousel' scrolls horizontally with snap points, Previous and Next buttons and an 'N of M' readout; every item stays reachable by keyboard\n - 'calendar' is a month grid with the items on their days; Previous and Next move a month at a time\n - Paging shows items per page, the range and the total, as a Table does\n - Selection shows the bulk-action bar, naming how many items are selected, while any are\n - reorderable: a drag handle per item, plus Move up / Move down buttons; the new order is written to 'order'\n- **Accessibility** (role: list / listitem (listbox when selectable)):\n - Announces the item count\n - An empty state is provided\n- **Agents:** Items are enumerated with their titles; each item exposes its own actions.\n\n### ColorInput\n\nPick a colour: from swatches the host offers, or any colour.\n\n- **Use when:**\n - A colour for a label, a tag, a calendar, a theme\n - Choosing from a set of brand colours\n- **Don't use when:**\n - A choice that happens to be shown as colours (a plan, a size): use Choice\n- **Rendering:**\n - Swatches are size.control.default squares with radius.control and a 1px color.border.default ring; the chosen one shows color.border.focus\n - The free picker is the platform's, with the text value beside it in type.mono\n- **Accessibility** (role: swatches are a radiogroup of radios named by their labels; the free picker is a native color input plus a text field for the value):\n - Every swatch has a name; colour alone is never the only identification\n - The value is editable as text, so it can be typed and read\n - The chosen colour is shown beside its text value\n- **Agents:** Reads the swatch names; picks one by name or types a value.\n\n### Comparison\n\nCompare a few options across the same attributes, and choose one.\n\n- **Use when:**\n - Choosing between 2–4 plans, products, routes or offers\n- **Don't use when:**\n - More than ~5 items: use Table with sorting\n - No decision needed: use Table\n- **Rendering:**\n - Wide: items as columns; compact: one card per item with the same attribute order\n - Best values per attribute are marked when 'better' is set\n - Exactly one item may be recommended; its badge carries recommendedReason\n - Attributes with the same group sit under one heading\n - Boolean values render as a check or a dash with text alternatives ('Included' / 'Not included')\n - On compact surfaces the recommended item comes first\n- **Accessibility** (role: table (items as columns on wide screens) or list of cards):\n - Attribute names are headers\n - 'better' is conveyed in text, not only color\n- **Agents:** Reads attributes per item; choose actions are named with the item title.\n\n### Confirm\n\nAsks the user to confirm a consequential or destructive action, showing what will happen.\n\n- **Use when:**\n - Moving money, deleting data, sending on someone's behalf, anything irreversible\n- **Don't use when:**\n - Routine reversible actions (prefer undo)\n - Information only: use Status\n- **Rendering:**\n - destructive uses color.action.danger.*\n - Capabilities with high risk level must use Confirm (enforced by the verifier)\n - the consequence sits directly above the confirm button\n - amount and subject lead the dialog when set\n - consequences render as an icon list, two columns on wide surfaces\n- **Accessibility** (role: alertdialog):\n - Focus starts on the least destructive option\n - Confirm label repeats the action verb\n - Escape cancels\n- **Agents:** Reads title and consequence; confirm and cancel are named buttons.\n\n### DateInput\n\nA date, time, date-time or date range.\n\n- **Use when:**\n - Any date or time entry\n- **Don't use when:**\n - Relative choices like 'This month / Last month': use Choice\n- **Rendering:**\n - Memorable dates (birthdays) use separate day/month/year fields; near dates use a calendar\n - 'month' and 'year' take only that part; the year field is typed, four digits\n - multiple: each chosen date becomes a chip with a remove control; the field adds another\n- **Accessibility** (role: group of spinbuttons or a date picker dialog):\n - Typing the date is always possible, not only picking from a calendar\n- **Agents:** Fill by label with an ISO date.\n\n### DetailList\n\nLabel/value pairs describing one thing (a summary, a receipt, a review step).\n\n- **Use when:**\n - Reviewing before submitting\n - Showing the attributes of one entity\n - Receipts\n - Fees, prices and totals before someone commits (variant 'receipt')\n- **Don't use when:**\n - Many entities with the same attributes: use Table\n - Comparing entities: use Comparison\n- **Rendering:**\n - Keeps the item order stable across generations (keys are remembered)\n - receipt: values right-aligned in tabular figures, the total row emphasised; people read amounts from the right\n - 'grid' lays fields out in columns by width, label above value\n - rowAction: each row ends with a 'Change' link whose accessible name includes the row's label; the total row has none\n- **Accessibility** (role: list of term/definition pairs (dl)):\n - Label and value are programmatically associated\n- **Agents:** Read each label with its value.\n\n### Disclosure\n\nProgressive disclosure: secondary content hidden behind a toggle.\n\n- **Use when:**\n - Details most people don't need (fees breakdown, advanced options, help text)\n- **Don't use when:**\n - Content everyone needs to complete the task\n - Primary navigation\n- **Rendering:**\n - Never hide required inputs or the primary action inside a closed Disclosure\n- **Accessibility** (role: button (aria-expanded) + region):\n - Summary is a button with expanded state\n - Hidden content is not in the tab order while closed\n- **Agents:** Expand by the summary text; state is exposed as expanded/collapsed.\n\n### FileInput\n\nChoose or drop files to attach or upload.\n\n- **Use when:**\n - Attaching a document, a receipt, a photo\n - Importing a file the product reads\n- **Don't use when:**\n - Taking a photo with the camera: the host's own flow\n - Pasting text: use TextInput\n- **Rendering:**\n - A dashed drop zone on color.surface.subtle with radius.control, the chooser control inside it\n - Each chosen file shows name, size and a remove control; a progress bar while the host uploads\n - Refusals use color.status.danger text under the zone\n- **Accessibility** (role: a native file input, labelled; the drop zone is a large target for the same input):\n - Keyboard opens the chooser; drag-and-drop is an addition, never the only way\n - Chosen files are listed as text with a 'Remove <name>' button each\n - Type and size limits are said before choosing and in any refusal\n- **Agents:** Reads the label and limits; attaches files through the host.\n\n### FilterPanel\n\nFilters for a list of results, with the result count.\n\n- **Use when:**\n - Browsing results people narrow by several attributes\n - More than two filters, or filters that take space (ranges, long lists)\n- **Don't use when:**\n - One or two quick filters: put a Choice (chips) above the results\n - Filling in information: use Form\n- **Rendering:**\n - Wide: filters in a sidebar beside the results\n - Compact: a 'Filters · n' button opens a bottom sheet whose action says 'Show n results'\n - Active filters show as removable chips above the results\n - Filters apply as they change (no separate Apply on wide)\n- **Accessibility** (role: region (filters) plus the results):\n - The result count is announced politely when it changes\n - Each active filter can be removed with a named button ('Remove filter: Desk')\n- **Agents:** Set filter inputs by label; read the result count; remove filters by their Remove buttons.\n\n### Form\n\nCollects inputs and submits them together.\n\n- **Use when:**\n - Any set of inputs that are submitted together\n- **Don't use when:**\n - Settings that apply immediately: use Toggles with actions\n - Several distinct stages: use Steps\n- **Rendering:**\n - One column; labels above fields\n - Submit is the primary action; cancel is secondary\n - Submit context is built from the form's input bindings\n - 'horizontal' becomes stacked on compact surfaces\n - 'aside' sits beside the form on wide surfaces; on compact ones it comes first, before the fields, so people read what they are agreeing to\n- **Accessibility** (role: form):\n - Submit is a real submit button\n - On submit errors, focus moves to an error summary that links to each field\n- **Agents:** Fill fields by label, then activate the submit button by its label.\n\n### Group\n\nVisually groups closely related items without a heading (proximity).\n\n- **Use when:**\n - A few items that belong together (a key figure and its caption, several metrics)\n- **Don't use when:**\n - The group needs a heading: use Section\n - Choosing between items: use Choice or Comparison\n- **Rendering:**\n - 'inline' collapses to a stack below the compact breakpoint\n - Gap uses space.stack.default or space.inline.default\n- **Accessibility** (role: group):\n - Has an accessible name when it contains interactive items\n- **Agents:** Treated as one unit when its label is present.\n\n### Identity\n\nA person, team or organisation: picture, name and details, or several of them together.\n\n- **Use when:**\n - Who something belongs to, was sent by or is assigned to\n - The recipient on a payment, the owner on a record, the members on a team\n - A list of people where the face helps recognition\n- **Don't use when:**\n - Choosing a person from a list: use Choice with avatarPath\n - A person's full record: use Card or DetailList\n- **Rendering:**\n - Initials come from the name's first letters, on a neutral surface with color.text.default; a pack may derive a stable colour from the name\n - Sizes: small 24px, default 40px, large 64px; the name uses type.body.default or type.heading.small for large\n - A group overlaps pictures by a quarter, with a '+N' tag for the rest\n - Images are never stretched; missing images fall back to initials, never to a broken image\n- **Accessibility** (role: group named by the name; the picture is decorative and the name is text):\n - The name is real text, never only an image or initials\n - A group's accessible name lists the first names and how many more\n - With an action, the whole element is one button or link named by the name\n- **Agents:** Reads the name and detail; a group exposes every member's name.\n\n### Media\n\nAn image, video, audio clip, gallery or QR code supplied by the host.\n\n- **Use when:**\n - Photos or illustrations that help identify something (a product, a place, a person)\n - A recording people play, or a code they scan\n- **Don't use when:**\n - Decoration with no information\n - Icons for actions (renderer supplies those)\n- **Rendering:**\n - Images never convey information that is not also in text\n - 'video' shows 'poster' until played; 'audio' is a compact player; both put 'transcript' under a disclosure\n - 'gallery' is a grid of the items' images, each with its own alt text\n - 'qr' is drawn on a canvas at a size that scans from a phone, with the alt as its accessible name\n- **Accessibility** (role: img (video / audio players, list for a gallery)):\n - Has alt text unless decorative (then hidden from assistive technology)\n - Video and audio have native controls and offer a transcript\n - A QR code's alt says what scanning it does\n- **Agents:** Reads the alt text; a gallery's images by their own alt text; a QR code's value.\n\n### Metric\n\nA key figure with a label, and optionally its change.\n\n- **Use when:**\n - One to four headline numbers the user asked about\n- **Don't use when:**\n - Many numbers: use Table or DetailList\n - Trends over time: use Chart\n- **Rendering:**\n - Value uses type.numeric.display\n - Change uses color.data.positive / negative according to 'favorable'\n- **Accessibility** (role: group (label + value)):\n - Change direction is conveyed in text as well as color\n - Screen readers read label, value and change as one sentence\n- **Agents:** Read label and value.\n\n### Navigation\n\nThe product's main navigation.\n\n- **Use when:**\n - Software with sections people move between (B2B apps, dashboards)\n - Only when the host doesn't already provide navigation\n- **Don't use when:**\n - Steps of one task: use Steps\n - Sections of one record: use Views\n - A surface embedded in a host that has its own navigation\n- **Rendering:**\n - Wide: a side navigation with grouped items\n - Compact: a menu button that opens the navigation\n - Badges sit at the end of their item\n - 'breadcrumb' is an ordered trail ending with the current item (aria-current=\"page\"), never behind a menu button\n - 'nested' shows each group as an expandable section; the group holding the current item starts open\n - 'toc' lists the page's sections as anchors, the section in view highlighted\n - 'local' lays the items out as tabs, the current one marked\n- **Accessibility** (role: navigation):\n - The current item carries aria-current=\"page\"\n - Badges say what they count ('12 overdue')\n- **Agents:** Move between sections by activating items by their labels.\n\n### Panel\n\nContent over the current view: a dialog, a drawer, a bottom sheet or a popover, opened from an action and dismissed to return.\n\n- **Use when:**\n - A short task on top of the page: edit one thing, pick one thing, see one record\n - Detail the person asked for that shouldn't replace where they are\n - A small set of options next to the control that opened them (popover)\n- **Don't use when:**\n - Confirming a consequential action: use Confirm, which is a dialog with the right words and order\n - A whole flow of several steps: use Steps on its own surface\n - Passing feedback: use Status\n- **Rendering:**\n - A backdrop of color.surface.inverse at opacity.overlay for modal kinds\n - dialog: max 560px on desktop, full width with space.inset.default on phones; drawer: 420px from the end edge; sheet: from the bottom with radius.large on the top corners; popover: color.surface.overlay with elevation.overlay and an arrow\n - The title is type.heading.medium with the close control at the end of the header\n - The action bar sits in a footer; on phones it is fixed to the bottom, full width\n - Motion uses motion.duration.default and motion.easing.standard; reduced motion fades instead\n- **Accessibility** (role: dialog (aria-modal for dialog, drawer and sheet) named by the title; popover is a non-modal dialog):\n - Focus moves into the panel on open and back to the opener on close\n - Tab stays inside a modal panel; Escape dismisses a dismissible one\n - The page behind a modal panel is inert\n - A sheet can be dismissed by dragging down as well as by the close control\n- **Agents:** Opens, reads the content and closes it by name; the footer actions are exposed like any ActionBar.\n\n### Progress\n\nHow far along something is, or how much of a bounded amount is used: a bar, a ring or a meter.\n\n- **Use when:**\n - A task that takes time, with a known share done\n - How much of a quota, budget or capacity is used\n - Progress towards a goal (pages read, steps walked)\n- **Don't use when:**\n - A number the person came to see: use Metric\n - Steps of a task the person moves through: use Steps\n - A short wait with nothing to measure: Status 'loading'\n- **Rendering:**\n - The track uses color.surface.subtle; the fill uses color.action.primary.background, or color.status.<tone>.emphasis for a toned meter\n - Height is size.control.small / 3 for a bar; a ring is size.control.default across\n - Readout in tabular figures, type.body.small, after the label\n - The bar's length means the fraction: never used for an amount with no bound\n- **Accessibility** (role: progressbar (bar, ring) or meter, named by the label, with aria-valuenow, aria-valuemin, aria-valuemax and aria-valuetext):\n - The readout is real text next to the graphic, never only the fill\n - A meter's tone is also said in text ('nearly full'), not only shown by colour\n - Indeterminate progress has no value attributes and is announced as busy\n- **Agents:** Reads label, value and max as text.\n\n### RangeInput\n\nA number, or a range between two numbers, within known bounds.\n\n- **Use when:**\n - Approximate values within a range (budget cap, volume)\n - A price or date range for filtering (mode 'range')\n- **Don't use when:**\n - Exact values: use TextInput with kind 'number' or 'currency'\n- **Rendering:**\n - Shows min, max and the current formatted value\n - mode 'range' shows two thumbs and min/max fields that stay in sync\n- **Accessibility** (role: slider):\n - Current value is shown as text\n - Keyboard arrows change the value by step\n- **Agents:** Set the value directly by label.\n\n### Rating\n\nA score out of N: given by the person, or shown as others gave it.\n\n- **Use when:**\n - Asking how something went, out of five\n - Showing a product's or place's rating with the count behind it\n- **Don't use when:**\n - A number within bounds that isn't a score: use RangeInput\n - Yes or no: use Toggle or Choice\n- **Rendering:**\n - Filled shapes use color.status.warning.emphasis; empty ones use color.border.default\n - The readout ('4.6') is shown after the shapes in tabular figures, with the count in color.text.muted\n - A rating that can be given shows the label above, like every input\n- **Accessibility** (role: radiogroup of radios named '1 star' to 'N stars' when it can be given; an image named '4.6 out of 5' when read-only):\n - Every star is a real control at size.target.min when the person can rate\n - The current value is announced; half values are said as such\n - Read-only ratings carry the score as text, not only as filled shapes\n- **Agents:** Reads the score and the count; sets a score by choosing '<n> stars'.\n\n### Section\n\nA titled region of the surface that groups related content under a heading.\n\n- **Use when:**\n - The surface has two or more distinct topics (e.g. 'Recipient' and 'Amount')\n - Content would otherwise exceed one screen and needs signposting\n- **Don't use when:**\n - Only one topic: put content directly under the root\n - Visual grouping without a heading: use Group\n- **Rendering:**\n - Heading level follows nesting depth, never chosen by the model\n - Spacing between sections uses space.stack.section\n- **Accessibility** (role: region (with heading)):\n - Title is rendered as a real heading; nesting depth sets the heading level\n - Title is the region's accessible name\n- **Agents:** Navigate by heading; the title names the region.\n\n### Status\n\nFeedback about state: info, success, warning, error, empty or loading.\n\n- **Use when:**\n - Results of an action\n - Empty collections\n - Errors with a way to recover\n - Loading states\n - 'undo': after a reversible action ran, say what happened and offer Undo instead of asking first\n- **Don't use when:**\n - Validation errors on a field: inputs show their own errors\n - Confirmation before acting: use Confirm\n- **Rendering:**\n - error and warning use color.status.* tokens and an icon\n - empty states explain why and what to do next\n - loading shows a skeleton when layout is known, otherwise a progress indicator\n - 'undo' renders as a snackbar at the bottom of the surface, announced politely, with the Undo action\n - Empty states may carry an ActionBar: one primary and one secondary action\n - 'inline' renders a bordered notice with its action on the right\n- **Accessibility** (role: status or alert (live region)):\n - success/info/loading are polite live regions; error is assertive\n - Meaning is in text, not only color or icon\n- **Agents:** Reads the title and message; the recovery action is exposed.\n\n### Steps\n\nA task split into ordered steps with visible progress.\n\n- **Use when:**\n - Tasks with dependent stages or too many inputs for one view (checkout, onboarding)\n- **Don't use when:**\n - Independent views: use Views\n - Under ~6 inputs: a single Form\n- **Rendering:**\n - Renderer provides Back (ui.back) and Next (ui.next); the last step shows 'finish'\n - Each step validates before moving on\n - 'tasklist' is a list of tasks with a status tag each (GOV.UK task list); a task opens its content in place, and 'finish' follows the list, saying how many are done\n - 'guide' shows every step's title and content in a numbered list, with 'finish' after the last\n- **Accessibility** (role: group with step progress (aria-current on the current step)):\n - Current step and total are announced\n - Back never loses entered data\n- **Agents:** Reads 'step N of M'; next/back are exposed as buttons.\n\n### Table\n\nTabular data: many items sharing the same attributes.\n\n- **Use when:**\n - Scanning or comparing many rows by several attributes\n - Records people scan, sort, select and act on in bulk (B2B lists)\n- **Don't use when:**\n - One entity: use DetailList\n - A few entities where the user must choose: use Comparison\n- **Rendering:**\n - On compact screens, rows become stacked cards with label/value pairs\n - Alignment follows the column format, never chosen by the model\n - Numbers and currency are right-aligned with tabular figures; 'status' renders as a tag using 'tones'\n - On compact surfaces the table becomes a list of rows: the entity, the key fields in one line, and the status\n - Selection replaces the toolbar with the bulk-action bar while rows are selected\n - Paging shows rows per page, the range and the total\n - expandable: each row starts with a toggle (aria-expanded) named after the row; the open row's 'detail' spans the table beneath it\n- **Accessibility** (role: table with caption and column headers):\n - Has a caption\n - Column headers are real header cells\n - Numeric columns are right-aligned by format\n - Sortable headers carry aria-sort and say what sorting does\n - The select-all checkbox is mixed when some rows are selected\n - The bulk-action bar names how many rows are selected, announced politely\n - Each row's action menu is named after its row\n- **Agents:** Read by row and column headers; rows with rowAction are activatable. Sort by activating a column header; select rows by their checkboxes; act in bulk from the bar that appears.\n\n### Tag\n\nA short label, status or count attached to something else.\n\n- **Use when:**\n - The state of a record, next to its name: 'Past due', 'Draft', 'Live'\n - A category or label a thing carries\n - How many of something, on a navigation item or a section heading\n - Chosen items a person can take off again\n- **Don't use when:**\n - A whole sentence of feedback: use Status\n - Something the person switches on or off: use Toggle\n - A metric the person came for: use Metric\n- **Rendering:**\n - status uses color.status.<tone>.background and .foreground; label and count use neutral tokens\n - count is set in tabular figures\n - A tag never wraps: long labels are truncated with the full text on hover and in the accessible name\n - Fits inline with text and in a Card header; radius.small unless the pack sets a pill\n- **Accessibility** (role: text; for 'count', the label is the accessible name of the number; for a removable tag, a button named 'Remove <label>'):\n - Tone is conveyed by the label, never only by colour\n - A count reads as '<label>: <count>' to a screen reader\n - The remove control is at least size.target.min and named for what it removes\n- **Agents:** Reads label, tone and count; can activate the remove control by its name.\n\n### Text\n\nA run of text.\n\n- **Use when:**\n - Explanations, instructions, messages\n- **Don't use when:**\n - Headings: use Section title\n - Label/value pairs: use DetailList\n - Key figures: use Metric\n- **Rendering:**\n - 'supporting' uses color.text.muted\n - No inline styling; emphasis comes from structure\n - 'rich' renders only the four markup forms, as real elements; anything else, including HTML, is shown as typed, and only http, https, mailto and tel links are live\n - 'list' renders a ul or ol; entries are shown as text, or by 'itemPath' when they are objects\n - 'quote' is a blockquote, the cite on its own line after it\n - format 'color' shows a swatch of the value beside it; 'bytes' shows a size like 1.2 MB\n- **Accessibility** (role: text):\n - Body text is at least 16px (type.body.default)\n - Line length is capped by measure.max\n- **Agents:** Read as text.\n\n### TextInput\n\nA single text-like value: text, number, email, phone, currency, search or long text.\n\n- **Use when:**\n - Free-form values the user types\n- **Don't use when:**\n - A value from a known set: use Choice\n - Dates: use DateInput\n - Secrets (passwords, card numbers): not generated; hosts provide their own secure flows\n- **Rendering:**\n - Width suggests expected length\n - Errors appear after the user leaves the field or submits, not while typing\n - kind 'search' renders as a pill search field with an icon; the label stays as its accessible name\n - size 'hero' renders a large centred amount with the currency symbol dimmed\n - 'suggestions' and 'mentions' are comboboxes: the list opens as you type, arrow keys move through it, Enter takes an option, Escape closes it\n - 'richtext' is an editable area with Bold, Italic and List controls; the value is text with **bold**, *italic* and '- ' items\n - 'tags' shows each value as a chip with a remove control; Enter or a comma adds what was typed, Backspace in an empty field removes the last chip; the value is a list of strings\n - 'code' uses type.numeric (monospace) and turns off autocorrect, autocapitalize and spellcheck\n - 'masked' fills the mask's literal characters as you type and stores the text as shown\n - 'inline' renders the value as text with an Edit control; Enter saves, Escape restores the previous value\n- **Accessibility** (role: textbox / searchbox / spinbutton):\n - Visible label, never placeholder-only\n - Help and errors are associated with the field\n - Kind sets the right keyboard and autocomplete\n- **Agents:** Fill by label.\n\n### Toggle\n\nAn on/off setting.\n\n- **Use when:**\n - Settings that take effect immediately\n - A single yes/no inside a form\n- **Don't use when:**\n - Choosing between named options: use Choice\n- **Rendering:**\n - With 'action' it renders as a switch; inside a Form without action, as a checkbox\n- **Accessibility** (role: switch (immediate) / checkbox (in a form)):\n - Label says what 'on' means\n- **Agents:** Toggle by label; state is exposed as on/off.\n\n### Tree\n\nA hierarchy people expand, browse and pick from: folders, an org chart, nested categories.\n\n- **Use when:**\n - Things that contain things: folders and files, an organisation, nested categories\n - Picking a place in a hierarchy (move to folder, choose a category)\n- **Don't use when:**\n - A flat list, however long: use Collection or Table\n - Nested navigation of the product itself: use Navigation\n - Progressive disclosure of one section: use Disclosure\n- **Rendering:**\n - Indent per level uses space.inline.default; the expander is a chevron at size.target.min\n - Leaves have no expander and align with siblings' labels\n - Selection uses color.selection.background; the focused node shows color.border.focus\n - Beyond 200 nodes the renderer virtualises rows\n- **Accessibility** (role: tree with treeitem nodes; aria-expanded on nodes with children, aria-selected when selectable):\n - Arrow keys move and expand; Home and End jump; typing jumps to a label\n - Level and position are exposed (aria-level, aria-setsize, aria-posinset)\n - Expanded state is announced; selection is announced\n- **Agents:** Reads every node by label and level; expands a node by name and selects or activates one by name.\n\n### Views\n\nSwitch between alternative views of the same subject (tabs).\n\n- **Use when:**\n - 2–6 peer views of the same data (Overview / Transactions / Settings)\n- **Don't use when:**\n - Sequential steps: use Steps\n - Filtering one list: use Choice\n- **Rendering:**\n - More than 4 views on compact screens become a menu or scrollable tabs\n - Counts sit beside their labels and are part of the tab's accessible name\n- **Accessibility** (role: tablist / tab / tabpanel):\n - Each tab has a visible label\n - Arrow keys move between tabs\n- **Agents:** Select a view by its label.\n",
|
|
9
9
|
"components": {
|
|
10
10
|
"Action": {
|
|
11
11
|
"type": "object",
|
|
@@ -42,6 +42,14 @@
|
|
|
42
42
|
},
|
|
43
43
|
"disabled": {
|
|
44
44
|
"$ref": "common_types.json#/$defs/DynamicBoolean"
|
|
45
|
+
},
|
|
46
|
+
"description": {
|
|
47
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
48
|
+
"description": "A second line under the label saying what the action does, for menu-like actions"
|
|
49
|
+
},
|
|
50
|
+
"copy": {
|
|
51
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
52
|
+
"description": "For the renderer action ui.copy: the text put on the clipboard; otherwise the action context's 'text' is copied"
|
|
45
53
|
}
|
|
46
54
|
},
|
|
47
55
|
"required": [
|
|
@@ -96,6 +104,61 @@
|
|
|
96
104
|
}
|
|
97
105
|
}
|
|
98
106
|
},
|
|
107
|
+
"ActionMenu": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"description": "Secondary actions behind one control: an overflow menu, a dropdown, a split button or a context menu.",
|
|
110
|
+
"properties": {
|
|
111
|
+
"component": {
|
|
112
|
+
"const": "ActionMenu"
|
|
113
|
+
},
|
|
114
|
+
"visible": {
|
|
115
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
116
|
+
"description": "Hide the component when false"
|
|
117
|
+
},
|
|
118
|
+
"label": {
|
|
119
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
120
|
+
"description": "The control's name: 'More actions' for an overflow, or the verb for a dropdown ('Export')"
|
|
121
|
+
},
|
|
122
|
+
"kind": {
|
|
123
|
+
"enum": [
|
|
124
|
+
"overflow",
|
|
125
|
+
"dropdown",
|
|
126
|
+
"split",
|
|
127
|
+
"context"
|
|
128
|
+
],
|
|
129
|
+
"default": "overflow",
|
|
130
|
+
"description": "'overflow' is the '…' control; 'dropdown' is a labelled button that opens the menu; 'split' pairs a primary action with a menu of alternatives; 'context' opens on right-click or long-press of the component it belongs to"
|
|
131
|
+
},
|
|
132
|
+
"children": {
|
|
133
|
+
"$ref": "common_types.json#/$defs/ChildList",
|
|
134
|
+
"type": "array",
|
|
135
|
+
"minItems": 1,
|
|
136
|
+
"description": "The Actions in the menu, in order; a danger-toned one goes last and is separated"
|
|
137
|
+
},
|
|
138
|
+
"primary": {
|
|
139
|
+
"$ref": "common_types.json#/$defs/ComponentId",
|
|
140
|
+
"description": "For 'split': the Action that runs when the main part is pressed"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"required": [
|
|
144
|
+
"component",
|
|
145
|
+
"label",
|
|
146
|
+
"children"
|
|
147
|
+
],
|
|
148
|
+
"allowedChildren": [
|
|
149
|
+
"Action"
|
|
150
|
+
],
|
|
151
|
+
"metadata": {
|
|
152
|
+
"extensions": {
|
|
153
|
+
"com_polyxd": {
|
|
154
|
+
"category": "action",
|
|
155
|
+
"target": "custom",
|
|
156
|
+
"basicAnalog": "Column of Button",
|
|
157
|
+
"why": "A column of buttons is not a menu: it loses the single trigger, its accessible name, the split primary and the context kind."
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
99
162
|
"Card": {
|
|
100
163
|
"type": "object",
|
|
101
164
|
"description": "One self-contained entity (an account, an order, a place), optionally actionable as a whole.",
|
|
@@ -186,11 +249,17 @@
|
|
|
186
249
|
"allowedChildren": [
|
|
187
250
|
"Action",
|
|
188
251
|
"ActionBar",
|
|
252
|
+
"ActionMenu",
|
|
253
|
+
"Code",
|
|
189
254
|
"DetailList",
|
|
190
255
|
"Group",
|
|
256
|
+
"Identity",
|
|
191
257
|
"Media",
|
|
192
258
|
"Metric",
|
|
259
|
+
"Progress",
|
|
260
|
+
"Rating",
|
|
193
261
|
"Status",
|
|
262
|
+
"Tag",
|
|
194
263
|
"Text",
|
|
195
264
|
"Toggle"
|
|
196
265
|
],
|
|
@@ -221,9 +290,14 @@
|
|
|
221
290
|
"trend",
|
|
222
291
|
"comparison",
|
|
223
292
|
"composition",
|
|
224
|
-
"distribution"
|
|
293
|
+
"distribution",
|
|
294
|
+
"relationship",
|
|
295
|
+
"flow",
|
|
296
|
+
"hierarchy",
|
|
297
|
+
"matrix",
|
|
298
|
+
"range"
|
|
225
299
|
],
|
|
226
|
-
"description": "What the chart should communicate; the renderer picks the chart type"
|
|
300
|
+
"description": "What the chart should communicate; the renderer picks the chart type. 'relationship' between two measures; 'flow' of amounts from each x value into the series; 'hierarchy' of parts by size; 'matrix' of x values against series; 'range' from the first series to the second"
|
|
227
301
|
},
|
|
228
302
|
"data": {
|
|
229
303
|
"type": "object",
|
|
@@ -278,7 +352,9 @@
|
|
|
278
352
|
"time",
|
|
279
353
|
"datetime",
|
|
280
354
|
"relativeTime",
|
|
281
|
-
"duration"
|
|
355
|
+
"duration",
|
|
356
|
+
"color",
|
|
357
|
+
"bytes"
|
|
282
358
|
]
|
|
283
359
|
},
|
|
284
360
|
"currency": {
|
|
@@ -337,7 +413,9 @@
|
|
|
337
413
|
"time",
|
|
338
414
|
"datetime",
|
|
339
415
|
"relativeTime",
|
|
340
|
-
"duration"
|
|
416
|
+
"duration",
|
|
417
|
+
"color",
|
|
418
|
+
"bytes"
|
|
341
419
|
]
|
|
342
420
|
},
|
|
343
421
|
"currency": {
|
|
@@ -517,6 +595,132 @@
|
|
|
517
595
|
}
|
|
518
596
|
}
|
|
519
597
|
},
|
|
598
|
+
"Code": {
|
|
599
|
+
"type": "object",
|
|
600
|
+
"description": "Code, a command or preformatted text, shown as written and copyable.",
|
|
601
|
+
"properties": {
|
|
602
|
+
"component": {
|
|
603
|
+
"const": "Code"
|
|
604
|
+
},
|
|
605
|
+
"visible": {
|
|
606
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
607
|
+
"description": "Hide the component when false"
|
|
608
|
+
},
|
|
609
|
+
"text": {
|
|
610
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
611
|
+
"description": "The code itself, usually bound to host data (an API key, a command, a snippet)"
|
|
612
|
+
},
|
|
613
|
+
"label": {
|
|
614
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
615
|
+
"description": "What it is, shown above: 'Install', 'Your API key'"
|
|
616
|
+
},
|
|
617
|
+
"language": {
|
|
618
|
+
"type": "string",
|
|
619
|
+
"description": "A language name for highlighting, when the renderer has it: 'bash', 'json', 'ts'"
|
|
620
|
+
},
|
|
621
|
+
"copyable": {
|
|
622
|
+
"type": "boolean",
|
|
623
|
+
"default": true,
|
|
624
|
+
"description": "A Copy control beside it"
|
|
625
|
+
},
|
|
626
|
+
"wrap": {
|
|
627
|
+
"type": "boolean",
|
|
628
|
+
"default": false,
|
|
629
|
+
"description": "Wrap long lines instead of scrolling sideways"
|
|
630
|
+
},
|
|
631
|
+
"secret": {
|
|
632
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
633
|
+
"default": false,
|
|
634
|
+
"description": "Masked until revealed: a key shown once"
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
"required": [
|
|
638
|
+
"component",
|
|
639
|
+
"text"
|
|
640
|
+
],
|
|
641
|
+
"metadata": {
|
|
642
|
+
"extensions": {
|
|
643
|
+
"com_polyxd": {
|
|
644
|
+
"category": "content",
|
|
645
|
+
"target": "custom",
|
|
646
|
+
"basicAnalog": "Text",
|
|
647
|
+
"why": "Text loses preformatting, the language, the copy control and the secret mask."
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
"CodeInput": {
|
|
653
|
+
"type": "object",
|
|
654
|
+
"description": "A one-time code or PIN, typed into one box per character.",
|
|
655
|
+
"properties": {
|
|
656
|
+
"component": {
|
|
657
|
+
"const": "CodeInput"
|
|
658
|
+
},
|
|
659
|
+
"visible": {
|
|
660
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
661
|
+
"description": "Hide the component when false"
|
|
662
|
+
},
|
|
663
|
+
"label": {
|
|
664
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
665
|
+
"description": "'Enter the code we emailed you'"
|
|
666
|
+
},
|
|
667
|
+
"value": {
|
|
668
|
+
"type": "object",
|
|
669
|
+
"required": [
|
|
670
|
+
"path"
|
|
671
|
+
],
|
|
672
|
+
"properties": {
|
|
673
|
+
"path": {
|
|
674
|
+
"type": "string",
|
|
675
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
676
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
"additionalProperties": false,
|
|
680
|
+
"description": "The code so far in host data, as a string"
|
|
681
|
+
},
|
|
682
|
+
"length": {
|
|
683
|
+
"type": "integer",
|
|
684
|
+
"minimum": 4,
|
|
685
|
+
"maximum": 12,
|
|
686
|
+
"default": 6
|
|
687
|
+
},
|
|
688
|
+
"kind": {
|
|
689
|
+
"enum": [
|
|
690
|
+
"numeric",
|
|
691
|
+
"alphanumeric"
|
|
692
|
+
],
|
|
693
|
+
"default": "numeric"
|
|
694
|
+
},
|
|
695
|
+
"help": {
|
|
696
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
697
|
+
"description": "Where the code came from and how long it lasts"
|
|
698
|
+
},
|
|
699
|
+
"required": {
|
|
700
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
701
|
+
"default": true
|
|
702
|
+
},
|
|
703
|
+
"action": {
|
|
704
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
705
|
+
"description": "Runs when every character is in, so the person needn't press a button; context binds to value"
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
"required": [
|
|
709
|
+
"component",
|
|
710
|
+
"label",
|
|
711
|
+
"value"
|
|
712
|
+
],
|
|
713
|
+
"metadata": {
|
|
714
|
+
"extensions": {
|
|
715
|
+
"com_polyxd": {
|
|
716
|
+
"category": "input",
|
|
717
|
+
"target": "custom",
|
|
718
|
+
"basicAnalog": "TextField",
|
|
719
|
+
"why": "TextField loses the one-box-per-character entry, the length, the numeric kind and the complete action."
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
},
|
|
520
724
|
"Collection": {
|
|
521
725
|
"type": "object",
|
|
522
726
|
"description": "A list of items from host data, each rendered with the same template.",
|
|
@@ -569,10 +773,97 @@
|
|
|
569
773
|
"auto",
|
|
570
774
|
"list",
|
|
571
775
|
"grid",
|
|
572
|
-
"timeline"
|
|
776
|
+
"timeline",
|
|
777
|
+
"carousel",
|
|
778
|
+
"calendar"
|
|
573
779
|
],
|
|
574
780
|
"default": "auto",
|
|
575
|
-
"description": "'grid' for visual items (products, books); 'list' for rows; 'timeline' for dated activity; 'auto' lets the renderer choose from the item template"
|
|
781
|
+
"description": "'grid' for visual items (products, books); 'list' for rows; 'timeline' for dated activity; 'carousel' for a row people page through; 'calendar' places items on a month grid by 'datePath'; 'auto' lets the renderer choose from the item template"
|
|
782
|
+
},
|
|
783
|
+
"datePath": {
|
|
784
|
+
"type": "string",
|
|
785
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
786
|
+
"description": "For 'calendar': relative path in each item to the ISO date that places it"
|
|
787
|
+
},
|
|
788
|
+
"page": {
|
|
789
|
+
"type": "object",
|
|
790
|
+
"properties": {
|
|
791
|
+
"index": {
|
|
792
|
+
"type": "object",
|
|
793
|
+
"required": [
|
|
794
|
+
"path"
|
|
795
|
+
],
|
|
796
|
+
"properties": {
|
|
797
|
+
"path": {
|
|
798
|
+
"type": "string",
|
|
799
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
800
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
801
|
+
}
|
|
802
|
+
},
|
|
803
|
+
"additionalProperties": false,
|
|
804
|
+
"description": "1-based page number in host data"
|
|
805
|
+
},
|
|
806
|
+
"size": {
|
|
807
|
+
"type": "object",
|
|
808
|
+
"required": [
|
|
809
|
+
"path"
|
|
810
|
+
],
|
|
811
|
+
"properties": {
|
|
812
|
+
"path": {
|
|
813
|
+
"type": "string",
|
|
814
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
815
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
816
|
+
}
|
|
817
|
+
},
|
|
818
|
+
"additionalProperties": false,
|
|
819
|
+
"description": "A value read from (and, for inputs, written to) host data. Data always comes from the host; the model never invents it."
|
|
820
|
+
},
|
|
821
|
+
"total": {
|
|
822
|
+
"type": "object",
|
|
823
|
+
"required": [
|
|
824
|
+
"path"
|
|
825
|
+
],
|
|
826
|
+
"properties": {
|
|
827
|
+
"path": {
|
|
828
|
+
"type": "string",
|
|
829
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
830
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
831
|
+
}
|
|
832
|
+
},
|
|
833
|
+
"additionalProperties": false,
|
|
834
|
+
"description": "Total number of items, all pages"
|
|
835
|
+
},
|
|
836
|
+
"action": {
|
|
837
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
838
|
+
"description": "Sent when someone changes page or page size"
|
|
839
|
+
}
|
|
840
|
+
},
|
|
841
|
+
"additionalProperties": false,
|
|
842
|
+
"description": "Paging state, owned by the host"
|
|
843
|
+
},
|
|
844
|
+
"bulkActions": {
|
|
845
|
+
"$ref": "common_types.json#/$defs/ComponentId",
|
|
846
|
+
"description": "ActionBar shown while items are selected (selection 'multiple')"
|
|
847
|
+
},
|
|
848
|
+
"reorderable": {
|
|
849
|
+
"type": "boolean",
|
|
850
|
+
"default": false,
|
|
851
|
+
"description": "People can drag items, or move them with the keyboard, into a new order"
|
|
852
|
+
},
|
|
853
|
+
"order": {
|
|
854
|
+
"type": "object",
|
|
855
|
+
"required": [
|
|
856
|
+
"path"
|
|
857
|
+
],
|
|
858
|
+
"properties": {
|
|
859
|
+
"path": {
|
|
860
|
+
"type": "string",
|
|
861
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
862
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
"additionalProperties": false,
|
|
866
|
+
"description": "Item values (ids) in the order people put them, written when reorderable"
|
|
576
867
|
}
|
|
577
868
|
},
|
|
578
869
|
"required": [
|
|
@@ -591,18 +882,21 @@
|
|
|
591
882
|
}
|
|
592
883
|
}
|
|
593
884
|
},
|
|
594
|
-
"
|
|
885
|
+
"ColorInput": {
|
|
595
886
|
"type": "object",
|
|
596
|
-
"description": "
|
|
887
|
+
"description": "Pick a colour: from swatches the host offers, or any colour.",
|
|
597
888
|
"properties": {
|
|
598
889
|
"component": {
|
|
599
|
-
"const": "
|
|
890
|
+
"const": "ColorInput"
|
|
600
891
|
},
|
|
601
892
|
"visible": {
|
|
602
893
|
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
603
894
|
"description": "Hide the component when false"
|
|
604
895
|
},
|
|
605
|
-
"
|
|
896
|
+
"label": {
|
|
897
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
898
|
+
},
|
|
899
|
+
"value": {
|
|
606
900
|
"type": "object",
|
|
607
901
|
"required": [
|
|
608
902
|
"path"
|
|
@@ -615,40 +909,181 @@
|
|
|
615
909
|
}
|
|
616
910
|
},
|
|
617
911
|
"additionalProperties": false,
|
|
618
|
-
"description": "
|
|
912
|
+
"description": "The colour in host data, as CSS text in the chosen format"
|
|
619
913
|
},
|
|
620
|
-
"
|
|
621
|
-
"
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
"
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
"
|
|
651
|
-
|
|
914
|
+
"swatches": {
|
|
915
|
+
"oneOf": [
|
|
916
|
+
{
|
|
917
|
+
"type": "array",
|
|
918
|
+
"minItems": 2,
|
|
919
|
+
"items": {
|
|
920
|
+
"type": "object",
|
|
921
|
+
"required": [
|
|
922
|
+
"value",
|
|
923
|
+
"label"
|
|
924
|
+
],
|
|
925
|
+
"properties": {
|
|
926
|
+
"value": {
|
|
927
|
+
"type": [
|
|
928
|
+
"string",
|
|
929
|
+
"number",
|
|
930
|
+
"boolean"
|
|
931
|
+
]
|
|
932
|
+
},
|
|
933
|
+
"label": {
|
|
934
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
935
|
+
},
|
|
936
|
+
"description": {
|
|
937
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
938
|
+
}
|
|
939
|
+
},
|
|
940
|
+
"additionalProperties": false
|
|
941
|
+
}
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
"type": "object",
|
|
945
|
+
"required": [
|
|
946
|
+
"path",
|
|
947
|
+
"valuePath",
|
|
948
|
+
"labelPath"
|
|
949
|
+
],
|
|
950
|
+
"properties": {
|
|
951
|
+
"path": {
|
|
952
|
+
"type": "string",
|
|
953
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
954
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
955
|
+
},
|
|
956
|
+
"valuePath": {
|
|
957
|
+
"type": "string",
|
|
958
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
959
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
960
|
+
},
|
|
961
|
+
"labelPath": {
|
|
962
|
+
"type": "string",
|
|
963
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
964
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
965
|
+
},
|
|
966
|
+
"descriptionPath": {
|
|
967
|
+
"type": "string",
|
|
968
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
969
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
970
|
+
},
|
|
971
|
+
"avatarPath": {
|
|
972
|
+
"type": "string",
|
|
973
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
974
|
+
"description": "Initials or a media reference per option: renders people and places with a face"
|
|
975
|
+
},
|
|
976
|
+
"imagePath": {
|
|
977
|
+
"type": "string",
|
|
978
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
979
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
980
|
+
},
|
|
981
|
+
"recentPath": {
|
|
982
|
+
"type": "string",
|
|
983
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
984
|
+
"description": "Boolean per option: shown in a 'Recent' row above the full list"
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
"additionalProperties": false
|
|
988
|
+
}
|
|
989
|
+
],
|
|
990
|
+
"description": "Named colours to pick from (value is the colour, label its name); without them the full picker shows"
|
|
991
|
+
},
|
|
992
|
+
"format": {
|
|
993
|
+
"enum": [
|
|
994
|
+
"hex",
|
|
995
|
+
"rgb",
|
|
996
|
+
"hsl"
|
|
997
|
+
],
|
|
998
|
+
"default": "hex"
|
|
999
|
+
},
|
|
1000
|
+
"alpha": {
|
|
1001
|
+
"type": "boolean",
|
|
1002
|
+
"default": false,
|
|
1003
|
+
"description": "Let the person set opacity too"
|
|
1004
|
+
},
|
|
1005
|
+
"help": {
|
|
1006
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
1007
|
+
},
|
|
1008
|
+
"required": {
|
|
1009
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
1010
|
+
"default": false
|
|
1011
|
+
}
|
|
1012
|
+
},
|
|
1013
|
+
"required": [
|
|
1014
|
+
"component",
|
|
1015
|
+
"label",
|
|
1016
|
+
"value"
|
|
1017
|
+
],
|
|
1018
|
+
"metadata": {
|
|
1019
|
+
"extensions": {
|
|
1020
|
+
"com_polyxd": {
|
|
1021
|
+
"category": "input",
|
|
1022
|
+
"target": "custom",
|
|
1023
|
+
"basicAnalog": "none",
|
|
1024
|
+
"why": "Basic has no colour input; swatches with names and the format would be lost."
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
1029
|
+
"Comparison": {
|
|
1030
|
+
"type": "object",
|
|
1031
|
+
"description": "Compare a few options across the same attributes, and choose one.",
|
|
1032
|
+
"properties": {
|
|
1033
|
+
"component": {
|
|
1034
|
+
"const": "Comparison"
|
|
1035
|
+
},
|
|
1036
|
+
"visible": {
|
|
1037
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
1038
|
+
"description": "Hide the component when false"
|
|
1039
|
+
},
|
|
1040
|
+
"items": {
|
|
1041
|
+
"type": "object",
|
|
1042
|
+
"required": [
|
|
1043
|
+
"path"
|
|
1044
|
+
],
|
|
1045
|
+
"properties": {
|
|
1046
|
+
"path": {
|
|
1047
|
+
"type": "string",
|
|
1048
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1049
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
1050
|
+
}
|
|
1051
|
+
},
|
|
1052
|
+
"additionalProperties": false,
|
|
1053
|
+
"description": "Array of options in host data (2–4 recommended)"
|
|
1054
|
+
},
|
|
1055
|
+
"itemTitle": {
|
|
1056
|
+
"type": "string",
|
|
1057
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1058
|
+
"description": "Relative path to each item's name"
|
|
1059
|
+
},
|
|
1060
|
+
"attributes": {
|
|
1061
|
+
"type": "array",
|
|
1062
|
+
"minItems": 1,
|
|
1063
|
+
"maxItems": 8,
|
|
1064
|
+
"items": {
|
|
1065
|
+
"type": "object",
|
|
1066
|
+
"required": [
|
|
1067
|
+
"key",
|
|
1068
|
+
"label",
|
|
1069
|
+
"path"
|
|
1070
|
+
],
|
|
1071
|
+
"properties": {
|
|
1072
|
+
"key": {
|
|
1073
|
+
"type": "string",
|
|
1074
|
+
"pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$",
|
|
1075
|
+
"description": "Stable semantic key (e.g. 'fee', 'recipient.name'). The same thing gets the same key across generations; interface memory uses it to keep placement, order and labels consistent."
|
|
1076
|
+
},
|
|
1077
|
+
"label": {
|
|
1078
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
1079
|
+
},
|
|
1080
|
+
"path": {
|
|
1081
|
+
"type": "string",
|
|
1082
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1083
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
1084
|
+
},
|
|
1085
|
+
"format": {
|
|
1086
|
+
"type": "object",
|
|
652
1087
|
"required": [
|
|
653
1088
|
"type"
|
|
654
1089
|
],
|
|
@@ -663,7 +1098,9 @@
|
|
|
663
1098
|
"time",
|
|
664
1099
|
"datetime",
|
|
665
1100
|
"relativeTime",
|
|
666
|
-
"duration"
|
|
1101
|
+
"duration",
|
|
1102
|
+
"color",
|
|
1103
|
+
"bytes"
|
|
667
1104
|
]
|
|
668
1105
|
},
|
|
669
1106
|
"currency": {
|
|
@@ -847,7 +1284,9 @@
|
|
|
847
1284
|
"time",
|
|
848
1285
|
"datetime",
|
|
849
1286
|
"relativeTime",
|
|
850
|
-
"duration"
|
|
1287
|
+
"duration",
|
|
1288
|
+
"color",
|
|
1289
|
+
"bytes"
|
|
851
1290
|
]
|
|
852
1291
|
},
|
|
853
1292
|
"currency": {
|
|
@@ -975,9 +1414,17 @@
|
|
|
975
1414
|
"date",
|
|
976
1415
|
"time",
|
|
977
1416
|
"datetime",
|
|
978
|
-
"dateRange"
|
|
1417
|
+
"dateRange",
|
|
1418
|
+
"month",
|
|
1419
|
+
"year"
|
|
979
1420
|
],
|
|
980
|
-
"default": "date"
|
|
1421
|
+
"default": "date",
|
|
1422
|
+
"description": "'month' stores YYYY-MM and 'year' stores YYYY"
|
|
1423
|
+
},
|
|
1424
|
+
"multiple": {
|
|
1425
|
+
"type": "boolean",
|
|
1426
|
+
"default": false,
|
|
1427
|
+
"description": "Several dates rather than one; the value is a list"
|
|
981
1428
|
},
|
|
982
1429
|
"min": {
|
|
983
1430
|
"$ref": "common_types.json#/$defs/DynamicString"
|
|
@@ -1057,7 +1504,9 @@
|
|
|
1057
1504
|
"time",
|
|
1058
1505
|
"datetime",
|
|
1059
1506
|
"relativeTime",
|
|
1060
|
-
"duration"
|
|
1507
|
+
"duration",
|
|
1508
|
+
"color",
|
|
1509
|
+
"bytes"
|
|
1061
1510
|
]
|
|
1062
1511
|
},
|
|
1063
1512
|
"currency": {
|
|
@@ -1099,6 +1548,10 @@
|
|
|
1099
1548
|
],
|
|
1100
1549
|
"default": "rows",
|
|
1101
1550
|
"description": "'grid' packs many short fields into columns (record pages); 'rows' keeps one per line"
|
|
1551
|
+
},
|
|
1552
|
+
"rowAction": {
|
|
1553
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
1554
|
+
"description": "Offered per row as a 'Change' link named after the row (GOV.UK summary list); the row's key is sent as 'key' with the context"
|
|
1102
1555
|
}
|
|
1103
1556
|
},
|
|
1104
1557
|
"required": [
|
|
@@ -1158,6 +1611,76 @@
|
|
|
1158
1611
|
}
|
|
1159
1612
|
}
|
|
1160
1613
|
},
|
|
1614
|
+
"FileInput": {
|
|
1615
|
+
"type": "object",
|
|
1616
|
+
"description": "Choose or drop files to attach or upload.",
|
|
1617
|
+
"properties": {
|
|
1618
|
+
"component": {
|
|
1619
|
+
"const": "FileInput"
|
|
1620
|
+
},
|
|
1621
|
+
"visible": {
|
|
1622
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
1623
|
+
"description": "Hide the component when false"
|
|
1624
|
+
},
|
|
1625
|
+
"label": {
|
|
1626
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
1627
|
+
},
|
|
1628
|
+
"value": {
|
|
1629
|
+
"type": "object",
|
|
1630
|
+
"required": [
|
|
1631
|
+
"path"
|
|
1632
|
+
],
|
|
1633
|
+
"properties": {
|
|
1634
|
+
"path": {
|
|
1635
|
+
"type": "string",
|
|
1636
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1637
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
1638
|
+
}
|
|
1639
|
+
},
|
|
1640
|
+
"additionalProperties": false,
|
|
1641
|
+
"description": "The chosen files in host data: a list of { name, size, type, ref }, written by the renderer; the host uploads them"
|
|
1642
|
+
},
|
|
1643
|
+
"accept": {
|
|
1644
|
+
"type": "array",
|
|
1645
|
+
"items": {
|
|
1646
|
+
"type": "string"
|
|
1647
|
+
},
|
|
1648
|
+
"description": "Allowed types as extensions or MIME types: ['.pdf', 'image/*']"
|
|
1649
|
+
},
|
|
1650
|
+
"multiple": {
|
|
1651
|
+
"type": "boolean",
|
|
1652
|
+
"default": false
|
|
1653
|
+
},
|
|
1654
|
+
"maxSize": {
|
|
1655
|
+
"type": "integer",
|
|
1656
|
+
"minimum": 1,
|
|
1657
|
+
"description": "Largest file, in bytes; the renderer refuses larger ones with a message"
|
|
1658
|
+
},
|
|
1659
|
+
"help": {
|
|
1660
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
1661
|
+
"description": "What to attach and why; the accepted types and size are said by the renderer"
|
|
1662
|
+
},
|
|
1663
|
+
"required": {
|
|
1664
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
1665
|
+
"default": false
|
|
1666
|
+
}
|
|
1667
|
+
},
|
|
1668
|
+
"required": [
|
|
1669
|
+
"component",
|
|
1670
|
+
"label",
|
|
1671
|
+
"value"
|
|
1672
|
+
],
|
|
1673
|
+
"metadata": {
|
|
1674
|
+
"extensions": {
|
|
1675
|
+
"com_polyxd": {
|
|
1676
|
+
"category": "input",
|
|
1677
|
+
"target": "custom",
|
|
1678
|
+
"basicAnalog": "none",
|
|
1679
|
+
"why": "Basic has no file input; the accepted types, size limit and multiple flag have no home."
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
},
|
|
1161
1684
|
"FilterPanel": {
|
|
1162
1685
|
"type": "object",
|
|
1163
1686
|
"description": "Filters for a list of results, with the result count.",
|
|
@@ -1211,8 +1734,10 @@
|
|
|
1211
1734
|
"allowedChildren": [
|
|
1212
1735
|
"Choice",
|
|
1213
1736
|
"Collection",
|
|
1737
|
+
"ColorInput",
|
|
1214
1738
|
"DateInput",
|
|
1215
1739
|
"RangeInput",
|
|
1740
|
+
"Rating",
|
|
1216
1741
|
"Table",
|
|
1217
1742
|
"TextInput",
|
|
1218
1743
|
"Toggle"
|
|
@@ -1353,35 +1878,128 @@
|
|
|
1353
1878
|
}
|
|
1354
1879
|
}
|
|
1355
1880
|
},
|
|
1356
|
-
"
|
|
1881
|
+
"Identity": {
|
|
1357
1882
|
"type": "object",
|
|
1358
|
-
"description": "
|
|
1883
|
+
"description": "A person, team or organisation: picture, name and details, or several of them together.",
|
|
1359
1884
|
"properties": {
|
|
1360
1885
|
"component": {
|
|
1361
|
-
"const": "
|
|
1886
|
+
"const": "Identity"
|
|
1362
1887
|
},
|
|
1363
1888
|
"visible": {
|
|
1364
1889
|
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
1365
1890
|
"description": "Hide the component when false"
|
|
1366
1891
|
},
|
|
1367
|
-
"
|
|
1892
|
+
"name": {
|
|
1893
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
1894
|
+
"description": "Always bound to host data: a name is never invented"
|
|
1895
|
+
},
|
|
1896
|
+
"detail": {
|
|
1897
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
1898
|
+
"description": "One line under the name: a role, an email, a team, a status"
|
|
1899
|
+
},
|
|
1900
|
+
"image": {
|
|
1901
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
1902
|
+
"description": "A media reference from host data, resolved by the host as Media's is; initials from the name are shown without one"
|
|
1903
|
+
},
|
|
1904
|
+
"kind": {
|
|
1905
|
+
"enum": [
|
|
1906
|
+
"person",
|
|
1907
|
+
"team",
|
|
1908
|
+
"organization"
|
|
1909
|
+
],
|
|
1910
|
+
"default": "person",
|
|
1911
|
+
"description": "A person's picture is round; a team's or organisation's is square"
|
|
1912
|
+
},
|
|
1913
|
+
"size": {
|
|
1914
|
+
"enum": [
|
|
1915
|
+
"small",
|
|
1916
|
+
"default",
|
|
1917
|
+
"large"
|
|
1918
|
+
],
|
|
1919
|
+
"default": "default"
|
|
1920
|
+
},
|
|
1921
|
+
"action": {
|
|
1922
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
1923
|
+
"description": "Activating the identity as a whole, e.g. open the person's record"
|
|
1924
|
+
},
|
|
1925
|
+
"group": {
|
|
1368
1926
|
"type": "object",
|
|
1369
1927
|
"required": [
|
|
1370
|
-
"path"
|
|
1928
|
+
"path",
|
|
1929
|
+
"namePath"
|
|
1371
1930
|
],
|
|
1372
1931
|
"properties": {
|
|
1373
1932
|
"path": {
|
|
1374
1933
|
"type": "string",
|
|
1375
1934
|
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1376
|
-
"description": "
|
|
1935
|
+
"description": "A list of people in host data, shown as overlapping pictures with a '+N' for the rest"
|
|
1936
|
+
},
|
|
1937
|
+
"namePath": {
|
|
1938
|
+
"type": "string",
|
|
1939
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1940
|
+
"description": "Relative to each entry"
|
|
1941
|
+
},
|
|
1942
|
+
"imagePath": {
|
|
1943
|
+
"type": "string",
|
|
1944
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1945
|
+
"description": "Relative to each entry"
|
|
1946
|
+
},
|
|
1947
|
+
"max": {
|
|
1948
|
+
"type": "integer",
|
|
1949
|
+
"minimum": 1,
|
|
1950
|
+
"maximum": 8,
|
|
1951
|
+
"default": 4,
|
|
1952
|
+
"description": "Pictures shown before '+N'"
|
|
1377
1953
|
}
|
|
1378
1954
|
},
|
|
1379
1955
|
"additionalProperties": false,
|
|
1380
|
-
"description": "
|
|
1956
|
+
"description": "Several identities as one element ('Rhea, Tom and 3 others'). name is then the group's accessible summary"
|
|
1957
|
+
}
|
|
1958
|
+
},
|
|
1959
|
+
"required": [
|
|
1960
|
+
"component",
|
|
1961
|
+
"name"
|
|
1962
|
+
],
|
|
1963
|
+
"metadata": {
|
|
1964
|
+
"extensions": {
|
|
1965
|
+
"com_polyxd": {
|
|
1966
|
+
"category": "content",
|
|
1967
|
+
"target": "custom",
|
|
1968
|
+
"basicAnalog": "Row of Image + Text",
|
|
1969
|
+
"why": "Row is layout; it loses the person/team kind, the initials fallback, the group's '+N' and the activation."
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
"Media": {
|
|
1975
|
+
"type": "object",
|
|
1976
|
+
"description": "An image, video, audio clip, gallery or QR code supplied by the host.",
|
|
1977
|
+
"properties": {
|
|
1978
|
+
"component": {
|
|
1979
|
+
"const": "Media"
|
|
1980
|
+
},
|
|
1981
|
+
"visible": {
|
|
1982
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
1983
|
+
"description": "Hide the component when false"
|
|
1984
|
+
},
|
|
1985
|
+
"src": {
|
|
1986
|
+
"type": "object",
|
|
1987
|
+
"required": [
|
|
1988
|
+
"path"
|
|
1989
|
+
],
|
|
1990
|
+
"properties": {
|
|
1991
|
+
"path": {
|
|
1992
|
+
"type": "string",
|
|
1993
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
1994
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
1995
|
+
}
|
|
1996
|
+
},
|
|
1997
|
+
"additionalProperties": false,
|
|
1998
|
+
"description": "Image, video or audio reference in host data; generated UI never contains URLs"
|
|
1381
1999
|
},
|
|
1382
2000
|
"alt": {
|
|
1383
2001
|
"$ref": "common_types.json#/$defs/DynamicString",
|
|
1384
|
-
"description": "Required unless decorative"
|
|
2002
|
+
"description": "Required unless decorative. For a gallery it names the set; for a QR code it says what the code opens"
|
|
1385
2003
|
},
|
|
1386
2004
|
"decorative": {
|
|
1387
2005
|
"type": "boolean",
|
|
@@ -1395,11 +2013,58 @@
|
|
|
1395
2013
|
"auto"
|
|
1396
2014
|
],
|
|
1397
2015
|
"default": "auto"
|
|
2016
|
+
},
|
|
2017
|
+
"kind": {
|
|
2018
|
+
"enum": [
|
|
2019
|
+
"image",
|
|
2020
|
+
"video",
|
|
2021
|
+
"audio",
|
|
2022
|
+
"gallery",
|
|
2023
|
+
"qr"
|
|
2024
|
+
],
|
|
2025
|
+
"default": "image",
|
|
2026
|
+
"description": "'video' and 'audio' play with native controls; 'gallery' is several images from 'items'; 'qr' encodes 'value' as a QR code"
|
|
2027
|
+
},
|
|
2028
|
+
"poster": {
|
|
2029
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2030
|
+
"description": "For 'video': media reference for the frame shown before play"
|
|
2031
|
+
},
|
|
2032
|
+
"transcript": {
|
|
2033
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2034
|
+
"description": "For 'video' and 'audio': the words, offered under the player"
|
|
2035
|
+
},
|
|
2036
|
+
"items": {
|
|
2037
|
+
"type": "object",
|
|
2038
|
+
"required": [
|
|
2039
|
+
"path"
|
|
2040
|
+
],
|
|
2041
|
+
"properties": {
|
|
2042
|
+
"path": {
|
|
2043
|
+
"type": "string",
|
|
2044
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
2045
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
2046
|
+
}
|
|
2047
|
+
},
|
|
2048
|
+
"additionalProperties": false,
|
|
2049
|
+
"description": "For 'gallery': array of images in host data"
|
|
2050
|
+
},
|
|
2051
|
+
"imagePath": {
|
|
2052
|
+
"type": "string",
|
|
2053
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
2054
|
+
"description": "For 'gallery': relative path in each item to its image reference"
|
|
2055
|
+
},
|
|
2056
|
+
"altPath": {
|
|
2057
|
+
"type": "string",
|
|
2058
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
2059
|
+
"description": "For 'gallery': relative path in each item to its alt text"
|
|
2060
|
+
},
|
|
2061
|
+
"value": {
|
|
2062
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2063
|
+
"description": "For 'qr': the text encoded, e.g. a payment link from host data"
|
|
1398
2064
|
}
|
|
1399
2065
|
},
|
|
1400
2066
|
"required": [
|
|
1401
|
-
"component"
|
|
1402
|
-
"src"
|
|
2067
|
+
"component"
|
|
1403
2068
|
],
|
|
1404
2069
|
"metadata": {
|
|
1405
2070
|
"extensions": {
|
|
@@ -1457,7 +2122,9 @@
|
|
|
1457
2122
|
"time",
|
|
1458
2123
|
"datetime",
|
|
1459
2124
|
"relativeTime",
|
|
1460
|
-
"duration"
|
|
2125
|
+
"duration",
|
|
2126
|
+
"color",
|
|
2127
|
+
"bytes"
|
|
1461
2128
|
]
|
|
1462
2129
|
},
|
|
1463
2130
|
"currency": {
|
|
@@ -1510,7 +2177,9 @@
|
|
|
1510
2177
|
"time",
|
|
1511
2178
|
"datetime",
|
|
1512
2179
|
"relativeTime",
|
|
1513
|
-
"duration"
|
|
2180
|
+
"duration",
|
|
2181
|
+
"color",
|
|
2182
|
+
"bytes"
|
|
1514
2183
|
]
|
|
1515
2184
|
},
|
|
1516
2185
|
"currency": {
|
|
@@ -1651,6 +2320,17 @@
|
|
|
1651
2320
|
},
|
|
1652
2321
|
"additionalProperties": false,
|
|
1653
2322
|
"description": "Key of the current item in host data"
|
|
2323
|
+
},
|
|
2324
|
+
"kind": {
|
|
2325
|
+
"enum": [
|
|
2326
|
+
"main",
|
|
2327
|
+
"breadcrumb",
|
|
2328
|
+
"nested",
|
|
2329
|
+
"toc",
|
|
2330
|
+
"local"
|
|
2331
|
+
],
|
|
2332
|
+
"default": "main",
|
|
2333
|
+
"description": "'main' is the product's sections; 'breadcrumb' the ordered trail to here; 'nested' groups that expand; 'toc' the sections of this page (items link to anchors named by their keys); 'local' the sections of one area, as tabs"
|
|
1654
2334
|
}
|
|
1655
2335
|
},
|
|
1656
2336
|
"required": [
|
|
@@ -1669,6 +2349,222 @@
|
|
|
1669
2349
|
}
|
|
1670
2350
|
}
|
|
1671
2351
|
},
|
|
2352
|
+
"Panel": {
|
|
2353
|
+
"type": "object",
|
|
2354
|
+
"description": "Content over the current view: a dialog, a drawer, a bottom sheet or a popover, opened from an action and dismissed to return.",
|
|
2355
|
+
"properties": {
|
|
2356
|
+
"component": {
|
|
2357
|
+
"const": "Panel"
|
|
2358
|
+
},
|
|
2359
|
+
"visible": {
|
|
2360
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2361
|
+
"description": "Hide the component when false"
|
|
2362
|
+
},
|
|
2363
|
+
"kind": {
|
|
2364
|
+
"enum": [
|
|
2365
|
+
"dialog",
|
|
2366
|
+
"drawer",
|
|
2367
|
+
"sheet",
|
|
2368
|
+
"popover"
|
|
2369
|
+
],
|
|
2370
|
+
"default": "dialog",
|
|
2371
|
+
"description": "'dialog' centres and blocks; 'drawer' slides from the side for a form or a record; 'sheet' rises from the bottom on phones; 'popover' floats by its opener for a small choice"
|
|
2372
|
+
},
|
|
2373
|
+
"title": {
|
|
2374
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
2375
|
+
},
|
|
2376
|
+
"children": {
|
|
2377
|
+
"$ref": "common_types.json#/$defs/ChildList",
|
|
2378
|
+
"type": "array",
|
|
2379
|
+
"minItems": 1,
|
|
2380
|
+
"description": "What the panel holds"
|
|
2381
|
+
},
|
|
2382
|
+
"actions": {
|
|
2383
|
+
"$ref": "common_types.json#/$defs/ComponentId",
|
|
2384
|
+
"description": "An ActionBar in the panel's footer: its primary action and a Cancel"
|
|
2385
|
+
},
|
|
2386
|
+
"open": {
|
|
2387
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2388
|
+
"description": "Bound to host data: true shows the panel; the renderer writes false on dismiss. Open when absent"
|
|
2389
|
+
},
|
|
2390
|
+
"dismissible": {
|
|
2391
|
+
"type": "boolean",
|
|
2392
|
+
"default": true,
|
|
2393
|
+
"description": "Escape, the close control and the backdrop dismiss it; false for a panel that must be completed"
|
|
2394
|
+
},
|
|
2395
|
+
"size": {
|
|
2396
|
+
"enum": [
|
|
2397
|
+
"small",
|
|
2398
|
+
"default",
|
|
2399
|
+
"large"
|
|
2400
|
+
],
|
|
2401
|
+
"default": "default"
|
|
2402
|
+
}
|
|
2403
|
+
},
|
|
2404
|
+
"required": [
|
|
2405
|
+
"component",
|
|
2406
|
+
"title",
|
|
2407
|
+
"children"
|
|
2408
|
+
],
|
|
2409
|
+
"allowedChildren": [
|
|
2410
|
+
"ActionBar",
|
|
2411
|
+
"Card",
|
|
2412
|
+
"Choice",
|
|
2413
|
+
"Code",
|
|
2414
|
+
"CodeInput",
|
|
2415
|
+
"Collection",
|
|
2416
|
+
"ColorInput",
|
|
2417
|
+
"DateInput",
|
|
2418
|
+
"DetailList",
|
|
2419
|
+
"Disclosure",
|
|
2420
|
+
"FileInput",
|
|
2421
|
+
"Form",
|
|
2422
|
+
"Group",
|
|
2423
|
+
"Identity",
|
|
2424
|
+
"Media",
|
|
2425
|
+
"Metric",
|
|
2426
|
+
"Progress",
|
|
2427
|
+
"RangeInput",
|
|
2428
|
+
"Rating",
|
|
2429
|
+
"Section",
|
|
2430
|
+
"Status",
|
|
2431
|
+
"Table",
|
|
2432
|
+
"Tag",
|
|
2433
|
+
"Text",
|
|
2434
|
+
"TextInput",
|
|
2435
|
+
"Toggle",
|
|
2436
|
+
"Tree",
|
|
2437
|
+
"Views"
|
|
2438
|
+
],
|
|
2439
|
+
"metadata": {
|
|
2440
|
+
"extensions": {
|
|
2441
|
+
"com_polyxd": {
|
|
2442
|
+
"category": "structure",
|
|
2443
|
+
"target": "custom",
|
|
2444
|
+
"basicAnalog": "Modal",
|
|
2445
|
+
"why": "Modal has no kind (drawer, sheet, popover), no bound open state, no footer action bar and no dismissible flag."
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
},
|
|
2450
|
+
"Progress": {
|
|
2451
|
+
"type": "object",
|
|
2452
|
+
"description": "How far along something is, or how much of a bounded amount is used: a bar, a ring or a meter.",
|
|
2453
|
+
"properties": {
|
|
2454
|
+
"component": {
|
|
2455
|
+
"const": "Progress"
|
|
2456
|
+
},
|
|
2457
|
+
"visible": {
|
|
2458
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2459
|
+
"description": "Hide the component when false"
|
|
2460
|
+
},
|
|
2461
|
+
"label": {
|
|
2462
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2463
|
+
"description": "What is being measured: 'Storage used', 'Upload', 'Goal'"
|
|
2464
|
+
},
|
|
2465
|
+
"value": {
|
|
2466
|
+
"$ref": "common_types.json#/$defs/DynamicNumber",
|
|
2467
|
+
"description": "Bound to host data. A fraction from 0 to 1, or an amount when max is given"
|
|
2468
|
+
},
|
|
2469
|
+
"max": {
|
|
2470
|
+
"$ref": "common_types.json#/$defs/DynamicNumber",
|
|
2471
|
+
"description": "The whole, when value is an amount rather than a fraction: 200 for '180 of 200 GB'"
|
|
2472
|
+
},
|
|
2473
|
+
"kind": {
|
|
2474
|
+
"enum": [
|
|
2475
|
+
"bar",
|
|
2476
|
+
"ring",
|
|
2477
|
+
"meter"
|
|
2478
|
+
],
|
|
2479
|
+
"default": "bar",
|
|
2480
|
+
"description": "'bar' and 'ring' show progress towards done; 'meter' shows a measured amount within bounds, with tone by threshold"
|
|
2481
|
+
},
|
|
2482
|
+
"caption": {
|
|
2483
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2484
|
+
"description": "Text beside the readout: '180 of 200 GB', '3 days left'. The readout itself is derived from value"
|
|
2485
|
+
},
|
|
2486
|
+
"format": {
|
|
2487
|
+
"type": "object",
|
|
2488
|
+
"required": [
|
|
2489
|
+
"type"
|
|
2490
|
+
],
|
|
2491
|
+
"properties": {
|
|
2492
|
+
"type": {
|
|
2493
|
+
"enum": [
|
|
2494
|
+
"text",
|
|
2495
|
+
"number",
|
|
2496
|
+
"currency",
|
|
2497
|
+
"percent",
|
|
2498
|
+
"date",
|
|
2499
|
+
"time",
|
|
2500
|
+
"datetime",
|
|
2501
|
+
"relativeTime",
|
|
2502
|
+
"duration",
|
|
2503
|
+
"color",
|
|
2504
|
+
"bytes"
|
|
2505
|
+
]
|
|
2506
|
+
},
|
|
2507
|
+
"currency": {
|
|
2508
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2509
|
+
"description": "ISO 4217 code, required for type 'currency'"
|
|
2510
|
+
},
|
|
2511
|
+
"precision": {
|
|
2512
|
+
"type": "integer",
|
|
2513
|
+
"minimum": 0,
|
|
2514
|
+
"maximum": 6
|
|
2515
|
+
}
|
|
2516
|
+
},
|
|
2517
|
+
"additionalProperties": false,
|
|
2518
|
+
"description": "How the readout is shown; percent without it"
|
|
2519
|
+
},
|
|
2520
|
+
"tone": {
|
|
2521
|
+
"enum": [
|
|
2522
|
+
"neutral",
|
|
2523
|
+
"info",
|
|
2524
|
+
"success",
|
|
2525
|
+
"warning",
|
|
2526
|
+
"danger"
|
|
2527
|
+
],
|
|
2528
|
+
"description": "Fixed tone; a meter without one takes warning past thresholds.warning and danger past thresholds.danger"
|
|
2529
|
+
},
|
|
2530
|
+
"thresholds": {
|
|
2531
|
+
"type": "object",
|
|
2532
|
+
"properties": {
|
|
2533
|
+
"warning": {
|
|
2534
|
+
"type": "number",
|
|
2535
|
+
"minimum": 0,
|
|
2536
|
+
"maximum": 1
|
|
2537
|
+
},
|
|
2538
|
+
"danger": {
|
|
2539
|
+
"type": "number",
|
|
2540
|
+
"minimum": 0,
|
|
2541
|
+
"maximum": 1
|
|
2542
|
+
}
|
|
2543
|
+
},
|
|
2544
|
+
"additionalProperties": false,
|
|
2545
|
+
"description": "Fractions at which a meter changes tone"
|
|
2546
|
+
},
|
|
2547
|
+
"indeterminate": {
|
|
2548
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2549
|
+
"description": "The task is running and how far along isn't known"
|
|
2550
|
+
}
|
|
2551
|
+
},
|
|
2552
|
+
"required": [
|
|
2553
|
+
"component",
|
|
2554
|
+
"label",
|
|
2555
|
+
"value"
|
|
2556
|
+
],
|
|
2557
|
+
"metadata": {
|
|
2558
|
+
"extensions": {
|
|
2559
|
+
"com_polyxd": {
|
|
2560
|
+
"category": "content",
|
|
2561
|
+
"target": "custom",
|
|
2562
|
+
"basicAnalog": "Text",
|
|
2563
|
+
"why": "Basic has no progress or meter; the fraction, bound and tone thresholds would be lost."
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
},
|
|
1672
2568
|
"RangeInput": {
|
|
1673
2569
|
"type": "object",
|
|
1674
2570
|
"description": "A number, or a range between two numbers, within known bounds.",
|
|
@@ -1724,7 +2620,9 @@
|
|
|
1724
2620
|
"time",
|
|
1725
2621
|
"datetime",
|
|
1726
2622
|
"relativeTime",
|
|
1727
|
-
"duration"
|
|
2623
|
+
"duration",
|
|
2624
|
+
"color",
|
|
2625
|
+
"bytes"
|
|
1728
2626
|
]
|
|
1729
2627
|
},
|
|
1730
2628
|
"currency": {
|
|
@@ -1767,6 +2665,79 @@
|
|
|
1767
2665
|
}
|
|
1768
2666
|
}
|
|
1769
2667
|
},
|
|
2668
|
+
"Rating": {
|
|
2669
|
+
"type": "object",
|
|
2670
|
+
"description": "A score out of N: given by the person, or shown as others gave it.",
|
|
2671
|
+
"properties": {
|
|
2672
|
+
"component": {
|
|
2673
|
+
"const": "Rating"
|
|
2674
|
+
},
|
|
2675
|
+
"visible": {
|
|
2676
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2677
|
+
"description": "Hide the component when false"
|
|
2678
|
+
},
|
|
2679
|
+
"label": {
|
|
2680
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2681
|
+
"description": "What is rated: 'Your rating', 'Average rating'"
|
|
2682
|
+
},
|
|
2683
|
+
"value": {
|
|
2684
|
+
"type": "object",
|
|
2685
|
+
"required": [
|
|
2686
|
+
"path"
|
|
2687
|
+
],
|
|
2688
|
+
"properties": {
|
|
2689
|
+
"path": {
|
|
2690
|
+
"type": "string",
|
|
2691
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
2692
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
2693
|
+
}
|
|
2694
|
+
},
|
|
2695
|
+
"additionalProperties": false,
|
|
2696
|
+
"description": "The score in host data; written when the person can rate"
|
|
2697
|
+
},
|
|
2698
|
+
"max": {
|
|
2699
|
+
"type": "integer",
|
|
2700
|
+
"minimum": 2,
|
|
2701
|
+
"maximum": 10,
|
|
2702
|
+
"default": 5
|
|
2703
|
+
},
|
|
2704
|
+
"readOnly": {
|
|
2705
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2706
|
+
"default": false,
|
|
2707
|
+
"description": "Show a score rather than take one"
|
|
2708
|
+
},
|
|
2709
|
+
"count": {
|
|
2710
|
+
"$ref": "common_types.json#/$defs/DynamicNumber",
|
|
2711
|
+
"description": "How many ratings the score is from, shown after it: '4.6 (212)'"
|
|
2712
|
+
},
|
|
2713
|
+
"help": {
|
|
2714
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
2715
|
+
},
|
|
2716
|
+
"required": {
|
|
2717
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
2718
|
+
"default": false
|
|
2719
|
+
},
|
|
2720
|
+
"action": {
|
|
2721
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
2722
|
+
"description": "Runs when a rating is given, with context bound to value"
|
|
2723
|
+
}
|
|
2724
|
+
},
|
|
2725
|
+
"required": [
|
|
2726
|
+
"component",
|
|
2727
|
+
"label",
|
|
2728
|
+
"value"
|
|
2729
|
+
],
|
|
2730
|
+
"metadata": {
|
|
2731
|
+
"extensions": {
|
|
2732
|
+
"com_polyxd": {
|
|
2733
|
+
"category": "input",
|
|
2734
|
+
"target": "custom",
|
|
2735
|
+
"basicAnalog": "Row of Icon",
|
|
2736
|
+
"why": "Icons can't be a radiogroup that writes a value, and lose the count and read-only distinction."
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
},
|
|
1770
2741
|
"Section": {
|
|
1771
2742
|
"type": "object",
|
|
1772
2743
|
"description": "A titled region of the surface that groups related content under a heading.",
|
|
@@ -1920,11 +2891,24 @@
|
|
|
1920
2891
|
},
|
|
1921
2892
|
"content": {
|
|
1922
2893
|
"$ref": "common_types.json#/$defs/ComponentId"
|
|
2894
|
+
},
|
|
2895
|
+
"status": {
|
|
2896
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
2897
|
+
"description": "For 'tasklist': 'todo', 'inProgress', 'done' or 'blocked', usually bound to host data"
|
|
1923
2898
|
}
|
|
1924
2899
|
},
|
|
1925
2900
|
"additionalProperties": false
|
|
1926
2901
|
}
|
|
1927
2902
|
},
|
|
2903
|
+
"kind": {
|
|
2904
|
+
"enum": [
|
|
2905
|
+
"wizard",
|
|
2906
|
+
"tasklist",
|
|
2907
|
+
"guide"
|
|
2908
|
+
],
|
|
2909
|
+
"default": "wizard",
|
|
2910
|
+
"description": "'wizard' shows one step at a time in order; 'tasklist' lists tasks people do in any order, each with its status; 'guide' is numbered instructions with no state"
|
|
2911
|
+
},
|
|
1928
2912
|
"current": {
|
|
1929
2913
|
"$ref": "common_types.json#/$defs/DynamicNumber",
|
|
1930
2914
|
"description": "Index of the current step (default 0)"
|
|
@@ -2033,7 +3017,9 @@
|
|
|
2033
3017
|
"time",
|
|
2034
3018
|
"datetime",
|
|
2035
3019
|
"relativeTime",
|
|
2036
|
-
"duration"
|
|
3020
|
+
"duration",
|
|
3021
|
+
"color",
|
|
3022
|
+
"bytes"
|
|
2037
3023
|
]
|
|
2038
3024
|
},
|
|
2039
3025
|
"currency": {
|
|
@@ -2188,6 +3174,15 @@
|
|
|
2188
3174
|
"$ref": "common_types.json#/$defs/ComponentId",
|
|
2189
3175
|
"description": "ActionBar offered per row, in a menu named after the row"
|
|
2190
3176
|
},
|
|
3177
|
+
"expandable": {
|
|
3178
|
+
"type": "boolean",
|
|
3179
|
+
"default": false,
|
|
3180
|
+
"description": "Rows open to show 'detail' beneath them"
|
|
3181
|
+
},
|
|
3182
|
+
"detail": {
|
|
3183
|
+
"$ref": "common_types.json#/$defs/ComponentId",
|
|
3184
|
+
"description": "Component rendered under an expanded row; relative paths inside it resolve against the row"
|
|
3185
|
+
},
|
|
2191
3186
|
"toolbar": {
|
|
2192
3187
|
"$ref": "common_types.json#/$defs/ComponentId",
|
|
2193
3188
|
"description": "ActionBar above the table (e.g. New, Import, Export)"
|
|
@@ -2312,22 +3307,88 @@
|
|
|
2312
3307
|
},
|
|
2313
3308
|
"required": [
|
|
2314
3309
|
"component",
|
|
2315
|
-
"rows",
|
|
2316
|
-
"caption",
|
|
2317
|
-
"columns"
|
|
2318
|
-
],
|
|
2319
|
-
"allowedChildren": [
|
|
2320
|
-
"ActionBar",
|
|
2321
|
-
"
|
|
2322
|
-
"
|
|
3310
|
+
"rows",
|
|
3311
|
+
"caption",
|
|
3312
|
+
"columns"
|
|
3313
|
+
],
|
|
3314
|
+
"allowedChildren": [
|
|
3315
|
+
"ActionBar",
|
|
3316
|
+
"Card",
|
|
3317
|
+
"Collection",
|
|
3318
|
+
"DetailList",
|
|
3319
|
+
"Group",
|
|
3320
|
+
"Media",
|
|
3321
|
+
"Metric",
|
|
3322
|
+
"Status",
|
|
3323
|
+
"Text",
|
|
3324
|
+
"TextInput"
|
|
3325
|
+
],
|
|
3326
|
+
"metadata": {
|
|
3327
|
+
"extensions": {
|
|
3328
|
+
"com_polyxd": {
|
|
3329
|
+
"category": "content",
|
|
3330
|
+
"target": "custom",
|
|
3331
|
+
"basicAnalog": "List of Row",
|
|
3332
|
+
"why": "Basic has no table. Caption, column headers, formats, row action and empty state would be lost."
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
},
|
|
3337
|
+
"Tag": {
|
|
3338
|
+
"type": "object",
|
|
3339
|
+
"description": "A short label, status or count attached to something else.",
|
|
3340
|
+
"properties": {
|
|
3341
|
+
"component": {
|
|
3342
|
+
"const": "Tag"
|
|
3343
|
+
},
|
|
3344
|
+
"visible": {
|
|
3345
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
3346
|
+
"description": "Hide the component when false"
|
|
3347
|
+
},
|
|
3348
|
+
"label": {
|
|
3349
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
3350
|
+
"description": "The word or two it shows: 'Past due', 'Beta', 'Design'"
|
|
3351
|
+
},
|
|
3352
|
+
"kind": {
|
|
3353
|
+
"enum": [
|
|
3354
|
+
"label",
|
|
3355
|
+
"status",
|
|
3356
|
+
"count"
|
|
3357
|
+
],
|
|
3358
|
+
"default": "label",
|
|
3359
|
+
"description": "'status' is the state of the thing it sits on and is coloured by tone; 'count' is a number, with the label as its accessible name"
|
|
3360
|
+
},
|
|
3361
|
+
"tone": {
|
|
3362
|
+
"enum": [
|
|
3363
|
+
"neutral",
|
|
3364
|
+
"info",
|
|
3365
|
+
"success",
|
|
3366
|
+
"warning",
|
|
3367
|
+
"danger"
|
|
3368
|
+
],
|
|
3369
|
+
"default": "neutral",
|
|
3370
|
+
"description": "Meaning, not decoration: a status tag's tone says whether the state is fine, a warning or a problem"
|
|
3371
|
+
},
|
|
3372
|
+
"count": {
|
|
3373
|
+
"$ref": "common_types.json#/$defs/DynamicNumber",
|
|
3374
|
+
"description": "For kind 'count': the number, bound to host data"
|
|
3375
|
+
},
|
|
3376
|
+
"remove": {
|
|
3377
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
3378
|
+
"description": "Present when the person can take the tag off (a filter chip, a chosen recipient): the capability that removes it"
|
|
3379
|
+
}
|
|
3380
|
+
},
|
|
3381
|
+
"required": [
|
|
3382
|
+
"component",
|
|
3383
|
+
"label"
|
|
2323
3384
|
],
|
|
2324
3385
|
"metadata": {
|
|
2325
3386
|
"extensions": {
|
|
2326
3387
|
"com_polyxd": {
|
|
2327
3388
|
"category": "content",
|
|
2328
3389
|
"target": "custom",
|
|
2329
|
-
"basicAnalog": "
|
|
2330
|
-
"why": "
|
|
3390
|
+
"basicAnalog": "Text",
|
|
3391
|
+
"why": "Text has no tone, no count and no remove control; a status tag's meaning is its tone."
|
|
2331
3392
|
}
|
|
2332
3393
|
}
|
|
2333
3394
|
}
|
|
@@ -2350,9 +3411,13 @@
|
|
|
2350
3411
|
"enum": [
|
|
2351
3412
|
"body",
|
|
2352
3413
|
"supporting",
|
|
2353
|
-
"caption"
|
|
3414
|
+
"caption",
|
|
3415
|
+
"rich",
|
|
3416
|
+
"list",
|
|
3417
|
+
"quote"
|
|
2354
3418
|
],
|
|
2355
|
-
"default": "body"
|
|
3419
|
+
"default": "body",
|
|
3420
|
+
"description": "'rich' allows **bold**, *italic*, `code` and [links](href) in the text; 'list' is a bulleted or numbered list of 'items'; 'quote' is a quotation with an optional 'cite'"
|
|
2356
3421
|
},
|
|
2357
3422
|
"format": {
|
|
2358
3423
|
"type": "object",
|
|
@@ -2370,7 +3435,9 @@
|
|
|
2370
3435
|
"time",
|
|
2371
3436
|
"datetime",
|
|
2372
3437
|
"relativeTime",
|
|
2373
|
-
"duration"
|
|
3438
|
+
"duration",
|
|
3439
|
+
"color",
|
|
3440
|
+
"bytes"
|
|
2374
3441
|
]
|
|
2375
3442
|
},
|
|
2376
3443
|
"currency": {
|
|
@@ -2385,6 +3452,35 @@
|
|
|
2385
3452
|
},
|
|
2386
3453
|
"additionalProperties": false,
|
|
2387
3454
|
"description": "Only when 'text' is bound to a non-string value"
|
|
3455
|
+
},
|
|
3456
|
+
"items": {
|
|
3457
|
+
"type": "object",
|
|
3458
|
+
"required": [
|
|
3459
|
+
"path"
|
|
3460
|
+
],
|
|
3461
|
+
"properties": {
|
|
3462
|
+
"path": {
|
|
3463
|
+
"type": "string",
|
|
3464
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3465
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3466
|
+
}
|
|
3467
|
+
},
|
|
3468
|
+
"additionalProperties": false,
|
|
3469
|
+
"description": "For 'list': array in host data, one entry per item; 'text' introduces the list"
|
|
3470
|
+
},
|
|
3471
|
+
"itemPath": {
|
|
3472
|
+
"type": "string",
|
|
3473
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3474
|
+
"description": "For 'list': relative path in each entry to the text shown, when the entries are objects"
|
|
3475
|
+
},
|
|
3476
|
+
"ordered": {
|
|
3477
|
+
"type": "boolean",
|
|
3478
|
+
"default": false,
|
|
3479
|
+
"description": "For 'list': numbered rather than bulleted"
|
|
3480
|
+
},
|
|
3481
|
+
"cite": {
|
|
3482
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
3483
|
+
"description": "For 'quote': who or what is quoted"
|
|
2388
3484
|
}
|
|
2389
3485
|
},
|
|
2390
3486
|
"required": [
|
|
@@ -2440,9 +3536,99 @@
|
|
|
2440
3536
|
"email",
|
|
2441
3537
|
"phone",
|
|
2442
3538
|
"url",
|
|
2443
|
-
"search"
|
|
3539
|
+
"search",
|
|
3540
|
+
"suggestions",
|
|
3541
|
+
"richtext",
|
|
3542
|
+
"tags",
|
|
3543
|
+
"mentions",
|
|
3544
|
+
"code",
|
|
3545
|
+
"masked",
|
|
3546
|
+
"inline"
|
|
3547
|
+
],
|
|
3548
|
+
"default": "text",
|
|
3549
|
+
"description": "'suggestions' offers completions from 'options' while leaving any text allowed; 'richtext' is short formatted text (bold, italic, lists) stored as markdown-ish text; 'tags' is a list of short values entered one at a time; 'mentions' offers 'options' after an @; 'code' is monospace with no autocorrection; 'masked' follows 'mask'; 'inline' reads as text until it is clicked"
|
|
3550
|
+
},
|
|
3551
|
+
"options": {
|
|
3552
|
+
"oneOf": [
|
|
3553
|
+
{
|
|
3554
|
+
"type": "array",
|
|
3555
|
+
"minItems": 2,
|
|
3556
|
+
"items": {
|
|
3557
|
+
"type": "object",
|
|
3558
|
+
"required": [
|
|
3559
|
+
"value",
|
|
3560
|
+
"label"
|
|
3561
|
+
],
|
|
3562
|
+
"properties": {
|
|
3563
|
+
"value": {
|
|
3564
|
+
"type": [
|
|
3565
|
+
"string",
|
|
3566
|
+
"number",
|
|
3567
|
+
"boolean"
|
|
3568
|
+
]
|
|
3569
|
+
},
|
|
3570
|
+
"label": {
|
|
3571
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
3572
|
+
},
|
|
3573
|
+
"description": {
|
|
3574
|
+
"$ref": "common_types.json#/$defs/DynamicString"
|
|
3575
|
+
}
|
|
3576
|
+
},
|
|
3577
|
+
"additionalProperties": false
|
|
3578
|
+
}
|
|
3579
|
+
},
|
|
3580
|
+
{
|
|
3581
|
+
"type": "object",
|
|
3582
|
+
"required": [
|
|
3583
|
+
"path",
|
|
3584
|
+
"valuePath",
|
|
3585
|
+
"labelPath"
|
|
3586
|
+
],
|
|
3587
|
+
"properties": {
|
|
3588
|
+
"path": {
|
|
3589
|
+
"type": "string",
|
|
3590
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3591
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3592
|
+
},
|
|
3593
|
+
"valuePath": {
|
|
3594
|
+
"type": "string",
|
|
3595
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3596
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3597
|
+
},
|
|
3598
|
+
"labelPath": {
|
|
3599
|
+
"type": "string",
|
|
3600
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3601
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3602
|
+
},
|
|
3603
|
+
"descriptionPath": {
|
|
3604
|
+
"type": "string",
|
|
3605
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3606
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3607
|
+
},
|
|
3608
|
+
"avatarPath": {
|
|
3609
|
+
"type": "string",
|
|
3610
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3611
|
+
"description": "Initials or a media reference per option: renders people and places with a face"
|
|
3612
|
+
},
|
|
3613
|
+
"imagePath": {
|
|
3614
|
+
"type": "string",
|
|
3615
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3616
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3617
|
+
},
|
|
3618
|
+
"recentPath": {
|
|
3619
|
+
"type": "string",
|
|
3620
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3621
|
+
"description": "Boolean per option: shown in a 'Recent' row above the full list"
|
|
3622
|
+
}
|
|
3623
|
+
},
|
|
3624
|
+
"additionalProperties": false
|
|
3625
|
+
}
|
|
2444
3626
|
],
|
|
2445
|
-
"
|
|
3627
|
+
"description": "For 'suggestions' and 'mentions': the completions offered"
|
|
3628
|
+
},
|
|
3629
|
+
"mask": {
|
|
3630
|
+
"type": "string",
|
|
3631
|
+
"description": "For 'masked': # for a digit, A for a letter, * for either, anything else typed for you, e.g. '#### #### #### ####'"
|
|
2446
3632
|
},
|
|
2447
3633
|
"currency": {
|
|
2448
3634
|
"$ref": "common_types.json#/$defs/DynamicString",
|
|
@@ -2566,6 +3752,117 @@
|
|
|
2566
3752
|
}
|
|
2567
3753
|
}
|
|
2568
3754
|
},
|
|
3755
|
+
"Tree": {
|
|
3756
|
+
"type": "object",
|
|
3757
|
+
"description": "A hierarchy people expand, browse and pick from: folders, an org chart, nested categories.",
|
|
3758
|
+
"properties": {
|
|
3759
|
+
"component": {
|
|
3760
|
+
"const": "Tree"
|
|
3761
|
+
},
|
|
3762
|
+
"visible": {
|
|
3763
|
+
"$ref": "common_types.json#/$defs/DynamicBoolean",
|
|
3764
|
+
"description": "Hide the component when false"
|
|
3765
|
+
},
|
|
3766
|
+
"label": {
|
|
3767
|
+
"$ref": "common_types.json#/$defs/DynamicString",
|
|
3768
|
+
"description": "What the tree holds, e.g. 'Folders'"
|
|
3769
|
+
},
|
|
3770
|
+
"items": {
|
|
3771
|
+
"type": "object",
|
|
3772
|
+
"required": [
|
|
3773
|
+
"path"
|
|
3774
|
+
],
|
|
3775
|
+
"properties": {
|
|
3776
|
+
"path": {
|
|
3777
|
+
"type": "string",
|
|
3778
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3779
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3780
|
+
}
|
|
3781
|
+
},
|
|
3782
|
+
"additionalProperties": false,
|
|
3783
|
+
"description": "The top-level nodes in host data: a list"
|
|
3784
|
+
},
|
|
3785
|
+
"labelPath": {
|
|
3786
|
+
"type": "string",
|
|
3787
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3788
|
+
"description": "Relative to each node: the text shown"
|
|
3789
|
+
},
|
|
3790
|
+
"childrenPath": {
|
|
3791
|
+
"type": "string",
|
|
3792
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3793
|
+
"description": "Relative to each node: its list of child nodes, absent or empty for a leaf"
|
|
3794
|
+
},
|
|
3795
|
+
"valuePath": {
|
|
3796
|
+
"type": "string",
|
|
3797
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3798
|
+
"description": "Relative to each node: what selection writes; the label when absent"
|
|
3799
|
+
},
|
|
3800
|
+
"detailPath": {
|
|
3801
|
+
"type": "string",
|
|
3802
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3803
|
+
"description": "Relative to each node: a count or note shown after the label"
|
|
3804
|
+
},
|
|
3805
|
+
"selection": {
|
|
3806
|
+
"enum": [
|
|
3807
|
+
"none",
|
|
3808
|
+
"single",
|
|
3809
|
+
"multiple"
|
|
3810
|
+
],
|
|
3811
|
+
"default": "none"
|
|
3812
|
+
},
|
|
3813
|
+
"selected": {
|
|
3814
|
+
"type": "object",
|
|
3815
|
+
"required": [
|
|
3816
|
+
"path"
|
|
3817
|
+
],
|
|
3818
|
+
"properties": {
|
|
3819
|
+
"path": {
|
|
3820
|
+
"type": "string",
|
|
3821
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3822
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3823
|
+
}
|
|
3824
|
+
},
|
|
3825
|
+
"additionalProperties": false,
|
|
3826
|
+
"description": "Selected node value(s) in host data when selection is not 'none'"
|
|
3827
|
+
},
|
|
3828
|
+
"expanded": {
|
|
3829
|
+
"type": "object",
|
|
3830
|
+
"required": [
|
|
3831
|
+
"path"
|
|
3832
|
+
],
|
|
3833
|
+
"properties": {
|
|
3834
|
+
"path": {
|
|
3835
|
+
"type": "string",
|
|
3836
|
+
"pattern": "^(/([^/~]|~[01])*)+$|^[A-Za-z0-9_]([^/~]|~[01])*(/([^/~]|~[01])*)*$",
|
|
3837
|
+
"description": "RFC 6901 JSON Pointer into host-provided data. Absolute ('/account/balance') or, inside a template, relative to the current item ('amount')."
|
|
3838
|
+
}
|
|
3839
|
+
},
|
|
3840
|
+
"additionalProperties": false,
|
|
3841
|
+
"description": "Values of the nodes shown open; the first level is open without it"
|
|
3842
|
+
},
|
|
3843
|
+
"action": {
|
|
3844
|
+
"$ref": "common_types.json#/$defs/Action",
|
|
3845
|
+
"description": "Activating a node, e.g. open that folder; context may bind to the node's fields"
|
|
3846
|
+
}
|
|
3847
|
+
},
|
|
3848
|
+
"required": [
|
|
3849
|
+
"component",
|
|
3850
|
+
"label",
|
|
3851
|
+
"items",
|
|
3852
|
+
"labelPath",
|
|
3853
|
+
"childrenPath"
|
|
3854
|
+
],
|
|
3855
|
+
"metadata": {
|
|
3856
|
+
"extensions": {
|
|
3857
|
+
"com_polyxd": {
|
|
3858
|
+
"category": "content",
|
|
3859
|
+
"target": "custom",
|
|
3860
|
+
"basicAnalog": "Nested Column of Text",
|
|
3861
|
+
"why": "Column can't express expand/collapse, levels, selection or the per-node action."
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
},
|
|
2569
3866
|
"Views": {
|
|
2570
3867
|
"type": "object",
|
|
2571
3868
|
"description": "Switch between alternative views of the same subject (tabs).",
|
|
@@ -2712,6 +4009,9 @@
|
|
|
2712
4009
|
{
|
|
2713
4010
|
"$ref": "#/components/ActionBar"
|
|
2714
4011
|
},
|
|
4012
|
+
{
|
|
4013
|
+
"$ref": "#/components/ActionMenu"
|
|
4014
|
+
},
|
|
2715
4015
|
{
|
|
2716
4016
|
"$ref": "#/components/Card"
|
|
2717
4017
|
},
|
|
@@ -2721,9 +4021,18 @@
|
|
|
2721
4021
|
{
|
|
2722
4022
|
"$ref": "#/components/Choice"
|
|
2723
4023
|
},
|
|
4024
|
+
{
|
|
4025
|
+
"$ref": "#/components/Code"
|
|
4026
|
+
},
|
|
4027
|
+
{
|
|
4028
|
+
"$ref": "#/components/CodeInput"
|
|
4029
|
+
},
|
|
2724
4030
|
{
|
|
2725
4031
|
"$ref": "#/components/Collection"
|
|
2726
4032
|
},
|
|
4033
|
+
{
|
|
4034
|
+
"$ref": "#/components/ColorInput"
|
|
4035
|
+
},
|
|
2727
4036
|
{
|
|
2728
4037
|
"$ref": "#/components/Comparison"
|
|
2729
4038
|
},
|
|
@@ -2739,6 +4048,9 @@
|
|
|
2739
4048
|
{
|
|
2740
4049
|
"$ref": "#/components/Disclosure"
|
|
2741
4050
|
},
|
|
4051
|
+
{
|
|
4052
|
+
"$ref": "#/components/FileInput"
|
|
4053
|
+
},
|
|
2742
4054
|
{
|
|
2743
4055
|
"$ref": "#/components/FilterPanel"
|
|
2744
4056
|
},
|
|
@@ -2748,6 +4060,9 @@
|
|
|
2748
4060
|
{
|
|
2749
4061
|
"$ref": "#/components/Group"
|
|
2750
4062
|
},
|
|
4063
|
+
{
|
|
4064
|
+
"$ref": "#/components/Identity"
|
|
4065
|
+
},
|
|
2751
4066
|
{
|
|
2752
4067
|
"$ref": "#/components/Media"
|
|
2753
4068
|
},
|
|
@@ -2757,9 +4072,18 @@
|
|
|
2757
4072
|
{
|
|
2758
4073
|
"$ref": "#/components/Navigation"
|
|
2759
4074
|
},
|
|
4075
|
+
{
|
|
4076
|
+
"$ref": "#/components/Panel"
|
|
4077
|
+
},
|
|
4078
|
+
{
|
|
4079
|
+
"$ref": "#/components/Progress"
|
|
4080
|
+
},
|
|
2760
4081
|
{
|
|
2761
4082
|
"$ref": "#/components/RangeInput"
|
|
2762
4083
|
},
|
|
4084
|
+
{
|
|
4085
|
+
"$ref": "#/components/Rating"
|
|
4086
|
+
},
|
|
2763
4087
|
{
|
|
2764
4088
|
"$ref": "#/components/Section"
|
|
2765
4089
|
},
|
|
@@ -2772,6 +4096,9 @@
|
|
|
2772
4096
|
{
|
|
2773
4097
|
"$ref": "#/components/Table"
|
|
2774
4098
|
},
|
|
4099
|
+
{
|
|
4100
|
+
"$ref": "#/components/Tag"
|
|
4101
|
+
},
|
|
2775
4102
|
{
|
|
2776
4103
|
"$ref": "#/components/Text"
|
|
2777
4104
|
},
|
|
@@ -2781,6 +4108,9 @@
|
|
|
2781
4108
|
{
|
|
2782
4109
|
"$ref": "#/components/Toggle"
|
|
2783
4110
|
},
|
|
4111
|
+
{
|
|
4112
|
+
"$ref": "#/components/Tree"
|
|
4113
|
+
},
|
|
2784
4114
|
{
|
|
2785
4115
|
"$ref": "#/components/Views"
|
|
2786
4116
|
}
|