Schema table
2 minutes read
A schema table turns a JSON Schema into the properties table a reference page needs: name, type, whether it is required, its default, its allowed values, and its description. Nested properties are indented under their parent, and $ref is followed within the same document.
Syntax
::schema-table{data="widget" label="Widget options"}
Options
| Name | Type | Default | What it does |
|---|---|---|---|
data |
string | required | The schema's path under _data, without its extension: widget reads _data/widget.json or _data/widget.yml; guides/steps reads _data/guides/steps.yml. |
label |
string | Properties |
The accessible name of the scroll region. |
Example
No schema in _data at "schema-table".
The file behind this table is _data/schema-table.json:
{
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "description": "The widget's name." },
"size": { "enum": ["s", "m", "l"], "default": "m" }
}
}
Structured field evidence
Besides the table, each schema table publishes an inert JSON block — a <script type="application/json" data-schema-fields> inside its region — with the same fields the rows show, so an agent can read the schema without scraping formatted cells. The block is part of the server-rendered page and needs no JavaScript. It is written with every < escaped, so no value, description, or schema name can close the block early.
{
"component": "schema-table",
"version": 1,
"data": "schema-table",
"fields": [
{
"path": "size",
"name": "size",
"anchor": "schema-schema-table-field-size",
"depth": 0,
"type": "enum",
"copyValue": "size: enum",
"required": false,
"default": { "present": true, "hasValue": true, "value": "m" },
"values": ["s", "m", "l"],
"description": "",
"truncated": null,
"children": []
}
]
}
fieldskeeps the table's order and nesting: nested properties and array-item fields appear under their parent inchildren, each with its dottedpath,depth, and the row'sanchorid.required,values(fromenumorconst),description, andcopyValue(the row's current copy text) carry the row's evidence as the table shows it.defaulttells absent from explicit null:presentis whether the schema has adefaultkeyword, andhasValueis whether that default is a readable value — so"default": nullpublishes{ "present": true, "hasValue": true, "value": null }while a field with no default publishes{ "present": false, "hasValue": false }.falseand""defaults survive as themselves.truncatedmarks where expansion stopped early —"cycle"for a$refalready on the way down,"depth"at the level the depth limit cut off — so an emptychildrennever implies a leaf when it is not one.
Notes
- The schema is read from
_data, so the page and the schema stay separate. A schema that is not there renders a message naming the missing file. - Column headers, the
requiredcell, the default table name, and every message come fromi18n/*.jsonin the page's language. $refmust point inside the same document, such as#/$defs/option. A reference to another file is ignored.- Deeply nested schemas stop expanding after eight levels and show the row without its children. The JSON block marks such a row
truncated: "depth", and a row cut off by a recursive$ref"cycle", instead of implying the tree is complete. - The table scrolls inside its own region and is reachable by keyboard.