Documentation blocks
Every component in Grails can have extended usage documentation authored as typed blocks. This documentation is intended for the entire product team — designers, engineers, and product managers — to understand how and when to use each component correctly.
Opening the Documentation Drawer
From any component in the library, click the Book icon (📖) in the top-right area of the Component Details Panel. This opens a secondary Documentation Drawer, stacked on top of the component drawer.
The Book icon is only visible when the component has documentation attached. If no documentation exists, the icon is hidden.
What Documentation Contains
Documentation is written as typed blocks, not as one free-form body of Markdown. The type of a block is not a label: it is a shape that determines which fields the content has. A rule with a level of obligation is stored with that level as a field, so an audit can read it — not as a word buried in a paragraph.
Pick the shape by what it does, and when two of them fit, by the question it answers.
The Add block menu lists the shapes in this order:
| Block | What it does | Answers | Don’t use it when |
|---|---|---|---|
Title (title) | Inserts a section title with hierarchy levels | What section is this? | You want to write under the heading too — a title carries no body, the prose goes in a Text block below it |
Text (sections) | Displays plain text or bulleted lists | — see the note | See the note below |
Table (table) | Custom tabulated data | How do these values compare? | Each row names something and defines what it is → Specs |
Props (api) | Table with the current Component’s properties | What properties does it have? | Only on a component — it reads the props from the spec |
Specs (specs) | Definitions with option to cross reference them (eg: use A instead of B) | What is this, exactly? | The row prescribes something and carries a level of obligation → Guidelines; if the rows get ticked → Checklist; if you are reading a value across columns → Table |
Guidelines (guidelines) | Complex rules with their usage and reason (eg: MUST NOT use A because..) | How do I use it well? | It helps decide whether to use it → Use cases |
Use cases (use-cases) | Documents Do’s and Dont’s | Should I use this or not? | The reader already decided and just wants to use it well → Guidelines |
Checklist (checklist) | A list of steps that can be checked to reflect status | What do I need to verify? | Nobody will tick them → Guidelines |
Image (image) | Attaches an image with an optional description | What does it look like? | A comparison needs several, each with its own alt text |
File (file) | Supports PDF, PPTX, DOCX with content extraction for auto-indexation | Where is the document? | You could say it in three paragraphs → Text. See the note below |
Specs, Table and Guidelines — the three that get confused
Take one subject — spacing — and notice that it wants a different shape depending on what you are actually writing down:
- Specs defines. Each row names something and says what it is, one row at a time: Gap — the space between two items inside a stack. Inset — the space between a container’s edge and its content.
- Table compares. Same subject, but now the rows only mean something read across columns: xs · 4px · 2px, sm · 8px · 4px, md · 16px · 8px. Nobody is being told what a thing is; they are looking up a number.
- Guidelines prescribes. It tells someone what to do, and it carries a level of obligation:
Use
mdbetween form fields (should). Never hardcode a pixel value (must not).
Two tests settle almost every case:
- Specs or Table? Read one row on its own, with the headings covered. “Gap: the space between two items in a stack” still says something — that is a spec. “sm · 8px · 4px” says nothing without its column headings — that is a table.
- Specs or Guidelines? Put must in front of it. “Must: the border is 2 px” is nonsense, so it is a spec. “Must: use a 2 px border” reads perfectly, so it is a guideline.
This is not a matter of taste. A guideline stores its level as a field, which is what lets an audit read it; Specs gives every row a stable identity, which is what lets rows point at each other; a Table keeps columns as columns, so a value stays a value. Content written in the wrong shape looks right on the page and is invisible to everything else.
Specs used to be called Table, and was renamed on 2026-09-08. The old name and its table icon made people pick it when they wanted to lay data out in rows and columns — and then find two fixed fields that do not do that. Existing blocks were converted automatically and nothing was lost; what used to be called Term is now called Spec. The Table block you see today is a different, new shape — the one that actually tabulates.
Pointing one spec at another
Inside a Specs block, a row can point at other rows of the same block, and the reference now says how the two relate: Instead of, Along with, Requires, Replaces, Replaced by or See also. You pick the target from the block’s own rows, so a reference cannot go stale when a row is renamed or translated.
Before this, a reference had no verb and every one of them silently meant instead of. Existing references were kept and are now labelled Instead of explicitly — the meaning did not change, it just stopped being implied.
Tables
Adding a table starts with its size: sweep the grid to say how many rows and columns you want, rather than accepting a default that is wrong most of the time — a breakpoint table is 4×2, a support matrix is 3×6.
From there you edit it in place, on the page, not in a side panel.
- Rows and columns are added and removed around the cell your cursor is in — insert above, insert below, insert to the left, insert to the right, delete this row, delete this column.
- The header row can be turned off and back on. A table does need one to be saved; if you leave it off, Grails tells you before saving rather than failing afterwards.
- Cells take bold and italic, and mentions of other entities, like anywhere else.
- Column widths are dragged, and they stay. Reopen the block a month later and the columns come back the way you left them.
- The title is optional. A table without one is a finished table.
- A cell holds one paragraph. If you put a line break inside a cell, you are asked to remove it before saving.
A table never gets a height of its own: it grows downwards and pushes whatever is below it, so no row is ever hidden behind a scrollbar. Columns share the width available and long text wraps rather than forcing the table wider.
Props — the only one you do not write in full
A Props block does not store the list of properties: it reads them from the component’s spec, live. What you write is the prose for each one — what it is for, what happens if you leave it at its default, which other prop it does not combine with.
That is why it is the only shape that exists on a component and nowhere else: on a token or a style there would be no spec to read from, and the menu does not even offer it.
And it is why it cannot go stale. If someone adds a variant in Figma tomorrow, the row shows up on its own with an empty description; if they remove a property, the row disappears and your text about it is kept in case it returns. The spec owns the structure, you own the judgement.
Example. On a
Button, thesizerow arrives from the spec with itssm · md · lgvalues, and you write: “mdis the default and covers almost everything.smis for dense bars — do not use it as a screen’s primary action — andlgonly on the first action of a landing page.”
Guidelines — rules with a level of obligation
A guideline is a rule with its reason and its weight. The weight is not a word inside the paragraph: it is a field, so an audit can read “this rule is MUST” without interpreting prose.
- MUST — not meeting it is a defect.
- SHOULD — the exception exists and has to be justified.
- MAY — allowed, and it needs no explanation.
Always write the reason. A rule without one is followed while someone remembers it, and dropped the day it gets in the way. With the reason written down, whoever finds it can decide whether the case in front of them is the exception.
Example. “MUST NOT use the commercial Banner inside a payment flow — it competes with the primary action, and there is measured conversion loss at checkout.”
Reach for Guidelines when the reader has already decided to use the thing and wants to use it well. If they are still deciding whether to use it, that is Use cases.
Use cases — what to do and what not to
Use cases is read before deciding; Guidelines, after. That is the whole difference between the two, and it is the most common confusion.
Each item carries a stance — recommended or discouraged — and can point at the alternative. That is what makes it a real do / don’t instead of two paragraphs that say opposite things with nothing relating them.
Example. “Avoid the Context Selector for navigating between different sections of the app — it always keeps one option selected, so it says ‘you are in one of these’, not ‘you are going elsewhere’. Use Tabs for that.”
Write the alternative as a mention of the entity, not as text: that way, the day someone renames
Tabs, your recommendation still points at the same thing.
Checklist — steps someone is going to tick
A Checklist is a list whose state is saved. Ticking an item is not a mental note: it is stored on the block, with its date, and whoever opens the page later sees what has already been done.
That decides when to use it: if nobody is going to tick them, it is not a checklist — it is guidelines with bullets. The question is not whether the content looks like a list, it is whether anyone is keeping count.
Example. An accessibility checklist on a component: “Contrast ≥ 4.5:1 in both themes · Keyboard navigable with no focus trap · The error state is announced, not just painted · The touch target reaches 44×44”.
Image — and why the alt text is not optional
An Image attaches a file and a description. The description is not a decorative caption: it is what screen-reader users and search read, so an image without text is an image that answers no query.
Describe what the image shows, not what it illustrates. “The component in its error state” is useless; “The field with a red border, the alert icon on the right and the message below it in dark red” works, because someone who cannot see it can reconstruct it.
A comparison — the before and the after, the right way and the wrong way — is two image blocks, each with its own description. A single image with both inside forces you to describe both in one text, and neither is separately searchable.
Section titles
A Title block is a heading and nothing else. You pick its level — H1 through H6 — and everything that follows it, until the next title, reads as its section.
- It carries no body. The prose that belongs under a heading goes in a Text block below it.
- It is one line, and it is not the entity’s name: the page already shows that at the top, which is why a new title starts at H2.
- You see the level, you do not just name it. What you type is rendered at the size the heading will have, so switching from H2 to H4 resizes the text in front of you.
- Nothing is nested. Order alone associates a title with what it titles, exactly as in a written document — move a paragraph above a heading and it belongs to the previous section.
Text is text again
The Text block used to offer headings and a table button. Both are now shapes of their own, so what Text offers is bold, italic, bullet lists and mentions — prose, in other words.
Older Text blocks that already contain a heading or a Markdown table still display and edit correctly; nothing was converted and nothing was lost. What changed is what the toolbar invites you to write from now on.
Attaching a file
Use a File block when the document is the documentation — the brand guidelines PDF, a spec somebody exported — and transcribing it would be busywork. The text inside is pulled out automatically, so the content answers searches just as if it had been typed.
Two things worth knowing before you reach for it:
- A scanned PDF has no text inside it. That is not something the file type tells us — it only shows up once we read the document — and when it happens the file is still attached and still downloadable, but it will not appear in any search. It is an attachment, not documentation.
- The first 30,000 characters are what gets indexed. A longer document uploads fine and is marked as truncated, but anything past that point is not searchable.
Accepted formats are PDF, Word, PowerPoint, Excel and OpenDocument. The older Office formats —
.doc, .ppt, .xls — are refused when you upload them, because there is no reliable way to read
their contents, and an attachment nobody can read is worse than being told up front.
⚠️ Deleting a page or a block deletes its file too, permanently. Unlike documentation attached to a synced component, which is restored on the next sync, there is nothing that brings a page’s file back.
Text is the default destination, not the preferred one. If you find yourself typing ### in a
Text block, that is a Title; if you find yourself drawing a Markdown table in one, that is a
Table. Move it to the shape that stores those fields. Simulated structure looks the same on
screen and is invisible to everything else — search, audits, and the DSDS export.
Editing a Block
Hover a block and its two controls appear in the top-right corner of that block: edit and delete. The block itself picks up a faint tint at the same moment, and that tint is the answer to a question the buttons alone left open — can this be edited at all? A viewer sees the same blocks with neither the tint nor the buttons, so nobody has to find out by trying.
The edit trigger is the button, not the block. Clicking anywhere inside a block used to open its editor, which made ordinary reading hazardous: selecting a line to copy it, or clicking a link in a rule, dropped you into edit mode. Text inside a block is now selectable and links are clickable, the way they are anywhere else on the page.
Editing does not put the block in a box. A block being edited shows a toolbar above it with the controls of its shape — bold and italic for text, the level for a title, the row and column controls for a table — plus Save and Discard. The block itself stays where it is and keeps looking like part of the page it belongs to, which is the point of writing on the page in the first place.
A block with changes you have not saved is marked: a tinted background, a coloured rail down its left edge, and an Unsaved changes label in its toolbar. It stays marked even after you click somewhere else, so a block you left half-written is visible before the warning dialog on the way out tells you about it.
Viewers see no controls at all — the buttons appear only for roles that may write.
Saving
Nothing is written until you press Save. Adding a block, rewriting one, reordering them and deleting one all happen in the browser: you can restructure a whole page and commit it in one go.
That is a change from how it used to work. Every edit used to be written the moment you made it, which meant a half-finished thought was already stored — and reordering blocks twice while thinking was three separate versions of the page.
The panel tells you when you have unsaved work, and asks before letting you close it:
- Closing the panel, or pressing
Esc, asks first. - Closing or reloading the browser tab asks too.
- Navigating elsewhere inside Grails does not ask, and the changes are lost. A link or the back button leaves the page without warning.
Deleting a block follows the same rule: it disappears from the panel immediately, and it is only removed for real when you save. Until then, closing without saving brings it back.
How Documentation is Authored
Write it directly in Grails, block by block. Each shape has its own editor: a rule picks its level from a dropdown, a use case marks whether it is recommended or discouraged and points at a real alternative component.
Most shapes open their editor in a side panel. Text, titles and tables are edited in place, on the page itself, because what you are judging is how they sit there: the size of a heading against its neighbours, the width of a column against the page. Neither can be judged in a 500px panel and then applied somewhere else.
Agents can also write documentation through the API. Every shape is discoverable there — including what it is for, when not to use it, and a valid example — so an agent picks the same shape a person would.
Permission Notes
| Action | Roles | Notes |
|---|---|---|
| Read Documentation | Admin, Editor, Viewer | All roles can open and read the documentation drawer. |
| Edit Documentation | Admin, Editor | Only Admins and Editors can update the documentation content. |