Diamond Stone: components
Date: 2026-11-11. Revision 1. Drawn in docs/component-map.html.
Every component of the shared interface package (packages/ui): its parts, its kinds,
the optional features it can switch on, its states and its movement. It expands
docs/DESIGN.md section 8 (a list of 27 elements with one line each) and the
"Components" layer of docs/FRONTEND.md section 1. Movement tokens are in
docs/MOTION.md; sizes in docs/DESIGN.md section 4.
Nothing is built. Names are proposals. The numbers at the start of each row are only for reference.
1. Why this is needed
The mockup draws 176 screens with 81 separate drawing functions, written one at a time as each screen needed something. Nine of them draw a row in a list. Five draw a card. Built that way, the real app would have the same component nine times, each slightly different, and each needing its own states, Arabic layout, screen reader names and tests.
This plan does the opposite: few components, each with named parts and switchable features. The 81 functions become 96 planned components, most of which the mockup never drew because they are behaviour (a field, a dialog, a list that only draws what is visible). The nine rows become one Row.
2. How a component is put together
Five things describe every component.
| What it is | Example: Row | |
|---|---|---|
| Parts | Named places inside it. Each is optional and takes a fixed kind of content | Lead (photo, icon or avatar) · Title · Detail · Meta · Trail (chip, amount, toggle or chevron) · Actions (revealed by swipe) |
| Kinds | A small fixed set of looks. Chosen by purpose, never by taste | Plain · Record (photo with the customer's circle) · Setting · Message |
| Features | Abilities switched on when needed, each written once and shared (section 3) | Pressable · Selectable · Swipe actions · Reveal · Sensitive amount · Suggested |
| States | What it looks like in each condition. All are built before the component is used anywhere | Rest · Pressed · Focused · Selected · Disabled · Busy · Loading · Error · Read-only · Queued offline |
| Motion | Its row from docs/MOTION.md section 7 |
Enters with shift.m if new; height closes on removal; values cross-fade |
Rules that keep it small.
- A part, not a new component. If two things differ only in what sits in one place, it is one component with a part.
- A feature, not a kind. If the difference is something it can do (be selected, be swiped, hide its amount), it is a feature, shared with every other component that can do the same.
- A kind only for a different purpose. At most five kinds per component. A sixth means it is two components.
- No look from outside. A screen cannot pass a colour, a size or a timing to a component. It passes meaning: tone, emphasis, size set.
- Three sizes at most: the two size sets (Compact, Comfortable) come from the person's setting, not the screen. A component may also have a "small" form for use inside another.
- Tones are five and shared: neutral, accent, good, warning, bad. Each is always colour plus icon or word.
- Every component is complete alone: all states, both directions, both themes, every surface level, enlarged text, a screen reader name, and its placeholder shape.
3. Features shared by all components
Each is written once, as a primitive or a small helper, and switched on per use.
| Feature | What it gives | Written in | Used by |
|---|---|---|---|
| Pressable | Same-frame press feedback, the touch area (larger than the drawing), keyboard and screen reader activation, one tap only while busy | Pressable | Anything that can be tapped |
| Surface | The right drawing for the phone's surface level; refuses glass inside glass and more glass than the phone's budget | Surface | Bars, sheets, cards |
| Presence | Enter and leave movement from the tokens; nothing on first paint or Back | Motion | Anything that appears |
| Draggable | Following the finger, rest points, release spring, direction lock | Draggable | Halo, sheet, row actions, photo |
| Selectable | Single or multiple choice, with the selected state announced | Helper | Row, chip, card, photo |
| Reveal | Opens more in place, height animated, state remembered | Helper | Row, card, section |
| Swipe actions | Up to two actions behind a row, each also in a menu | Draggable | Row |
| Hold to confirm | Press and hold for actions that cannot be undone | Pressable | Button |
| Step-up | Asks for the passkey before the action runs | Helper | Button, sheet |
| Permission | Hidden, read-only or disabled by role; the server decides, the component only shows it | Helper | Everything |
| Sensitive | Amounts covered when "hide amounts" is on; press and hold to see | Helper | Money, figure, row, card |
| Customer view | Draws what the customer would see (masked origin, no driver) | Helper | Row, card, map, record |
| Suggested | Marks content as an AI suggestion with its source, and Accept, Edit, Dismiss | Suggestion | Field, chip, row, composer |
| Queued | Shows "waiting to send", "sent", "failed" for work done offline | Helper | Row, button, message, photo |
| Loading shape | The component's own still placeholder | Skeleton | Every display component |
| Count | A number on a corner, cross-fading | Badge | Button, ring, chip, avatar |
| Tone | One of the five tones | Tokens | Chip, row, figure, banner, button |
| Long-press preview | A small sheet showing the record behind it | Sheet | Row, card, avatar, chip |
| Explain | A small "why" that opens a short explanation in place | Popover | Figure, chip, field |
| Direction | Mirrors for Arabic; isolates names, amounts and codes | Tokens, Text | Everything |
4. The components
Kinds are separated by "·". Features lists only those beyond Permission, Direction, Tone and Loading shape, which apply to all.
Primitives (behaviour only, no look): 12
| # | Component | Does | Notes |
|---|---|---|---|
| 1 | Surface | Draws a background at the phone's surface level | Kinds: bar · sheet · card · solid |
| 2 | Pressable | Press feedback and activation | |
| 3 | Motion | Presence, shared-element names, the spring solver | Reads the motion level |
| 4 | Draggable | Finger following and rest points | |
| 5 | Layout | Stack, line, grid, with spacing from tokens only | No free margins |
| 6 | Text | Type styles; direction isolation; numbers with tabular figures | Kinds: title · body · label · figure |
| 7 | Icon | The icon set at fixed sizes | Mirrors those that point |
| 8 | Layer | Places sheets, dialogs and toasts in the one fixed order | |
| 9 | Focus | Keeps focus inside an overlay and returns it after | |
| 10 | Announce | Tells a screen reader about a change | Polite · urgent |
| 11 | Scroll | Scrolling area that remembers its place; padding for the band and bar | Feature: pull to refresh |
| 12 | Long list | Draws only the rows in view | For lists over about 50 rows |
Actions: 10
| # | Component | Parts | Kinds | Features | Motion |
|---|---|---|---|---|---|
| 13 | Button | Icon, label, count | Main · quiet · tonal · danger | Busy, hold to confirm, step-up, queued | Press scale; label cross-fades to busy |
| 14 | Icon button | Icon, count | Plain · tonal | Press scale | |
| 15 | Action bar | Main button, one or two side buttons | Above the Omnibar · inside a sheet | Arrives with its screen | |
| 16 | Chip | Icon, label, count, remove | Status · filter · choice · entered value | Selectable, suggested, explain | Colour quick; selection slides |
| 17 | Chip line | Chips, more | Scrolls · wraps | ||
| 18 | Toggle | Track, thumb, label | Thumb spring.snappy |
||
| 19 | Segments | Two to four options | Selection slides spring.snappy |
||
| 20 | Stepper | Minus, value, plus | Count · quantity with unit | Hold to repeat | Value cross-fades |
| 21 | Menu | Items with icon, label, tone | From a button · from a long press | Grows from its source, move |
|
| 22 | Link | Label, icon | In text · alone | Colour only |
Inputs: 21
| # | Component | Parts | Kinds | Features | Motion |
|---|---|---|---|---|---|
| 23 | Field | Label above, input, unit or icon, hint, error | Text · long text · number · search | Suggested, clear, paste, scan into | Focus ring quick; error rises shift.s |
| 24 | Money field | As Field, with currency | Rials (3 decimals) · other currency with its decimals, the rate and the live rial value (docs/CURRENCY.md) |
Calculator, sensitive | Live total cross-fades |
| 25 | Phone field | Country, number | Always left to right | ||
| 26 | Code field | Boxes for a one-time code | 6 digits | Fills from the message by itself | Each box fills with quick |
| 27 | Quantity field | Value, unit switch | Area · length · count · weight | Converts between units | |
| 28 | Size field | Length × width × thickness | Slab · tile · cut piece | Works out area and weight | |
| 29 | Date field | Day, month, year or a calendar sheet | Date · range · month | Quick choices: today, tomorrow, Sunday | |
| 30 | Time field | Time · window | |||
| 31 | Picker | A field that opens a sheet of choices | One · several | Search, recent first, add new | Sheet |
| 32 | Record picker | Picker for a customer, stone, supplier, order | Scan, recent, duplicate check on add | Sheet | |
| 33 | Yes or no | Two large answers | Selection quick |
||
| 34 | Choice list | Rows with a mark | One · several | Mark draws quick |
|
| 35 | Rating | Five steps | Stars · faces | ||
| 36 | Slider | Track, thumb, value | One value · range | Follows the finger | |
| 37 | Keypad | Digits, decimal, done | Money · quantity · code | Press only | |
| 38 | Photo capture | Viewfinder, shutter, strip of shots | One · a set · a document with edges | Guidance (too dark, blurred), queued | Shot shrinks into its thumbnail |
| 39 | Scanner | Viewfinder, target, torch, type by hand | Code · label · business card | Target locks with a light tick | |
| 40 | Signature | Pad, clear, name | Follows the finger | ||
| 41 | Place picker | Map, pin, address | Site · yard | Current position | Pin settles |
| 42 | File add | Camera, gallery, file | Queued | ||
| 43 | Form | Sections, fields, review, action | One screen · steps | Saves as typed; warns before leaving | Steps slide in reading direction |
Showing: 26
| # | Component | Parts | Kinds | Features | Motion |
|---|---|---|---|---|---|
| 44 | Row | Lead, title, detail, meta, trail, actions | Plain · record · setting · message | Pressable, selectable, swipe actions, reveal, sensitive, suggested, queued, long-press preview, customer view | Enters if new; height closes; values cross-fade |
| 45 | List | Heading, rows on one surface with hairlines, footer | Plain · grouped · long | Sort, filter line, empty state | Stagger if new |
| 46 | Card | Heading, answer, visual, next step | Record · approval · match · figure | Pressable, reveal, sensitive, customer view, long-press preview | Enters if new; decided card slides toward the Omnibar |
| 47 | Section | Heading, count, action, content | Open · folds | Reveal | |
| 48 | Money | Amount, currency code, sign, currency mark when not rials, rial value beneath | Plain · large · change | Sensitive; customer view (own currency only) | Cross-fade |
| 49 | Figure | Number, label, comparison, small visual | Tile · inline · hero | Sensitive, explain, pressable | Cross-fade |
| 50 | Strip | Three or four figures in one line | |||
| 51 | Pairs | Label and value pairs | Two columns · one | Copy on hold | |
| 52 | Status chip | Icon, word | The five tones | Explain | Colour quick |
| 53 | Badge | Number or dot | Forms once; cross-fades | ||
| 54 | Avatar | Photo or initials, ring, mark | Person · company · stone | Count, long-press preview | |
| 55 | Faces | Up to four avatars and "+3" | |||
| 56 | Photo | Image, customer's circle, mark | Thumb · tile · wide | Opens to zoom; "may be shown" mark | Fades over its colour; opens by growing |
| 57 | Photo set | Grid or strip, count, add | View · choose · approve | Selectable | Sideways drag |
| 58 | Stage tracker | Three to six stages, current in words, next date | Line · dots · steps | Customer view | Segment fills; settle on the last |
| 59 | Route line | Places, the current leg, arrival | Sea · road | Customer view (masked origin) | Marker glides |
| 60 | Timeline | Events with time, person, channel | Record history · conversation | New item rises shift.s |
|
| 61 | Bar | Value, target, usual range | Progress · bullet · age · stacked | Explain | Fills once |
| 62 | Ring | Share of a whole, centre label | Progress · Halo ring | Count | Segment fills |
| 63 | Trend | A small line, last point marked | Draws once if new | ||
| 64 | Chart | Axis, marks, labels, key | Bars · line · stacked bars | Tap a mark for its figure; table view | Draws once; values cross-fade |
| 65 | Scale | A marker on a labelled range | Stone property | Explain | |
| 66 | Container | Outline, floor and weight bars | 20 ft · 40 ft | Bars fill | |
| 67 | Map | Tiles, markers, route, area | Track · pick · masked | Customer view | Marker glides between reports |
| 68 | Document | A page preview, watermark, code | Share | ||
| 69 | Code | A square code with its short address | Show · print label |
Telling: 9
| # | Component | Parts | Kinds | Features | Motion |
|---|---|---|---|---|---|
| 70 | Toast | Icon, words, one action | Done · undo · failed | From the bottom; leaves after 5 s | |
| 71 | Banner | Icon, words, action | Offline · problem · notice | From the top of the content | |
| 72 | Inline note | Icon, words | The five tones | Rises shift.s |
|
| 73 | Dialog | Title, words, two answers | Confirm · choose | Hold to confirm, step-up | Fades and scales from 0.94 |
| 74 | Empty state | Icon, one line, one action | Nothing yet · nothing found · no access | None | |
| 75 | Skeleton | Shapes of the content | Still; one slow pulse after 1 s | ||
| 76 | Progress | Line or ring, words | Measured · working | Linear | |
| 77 | Sync mark | Icon, age | Saved copy · sending · failed | Colour only | |
| 78 | Coach note | A pointer to one control, once | Fades in once |
Overlays: 6
| # | Component | Parts | Kinds | Features | Motion |
|---|---|---|---|---|---|
| 79 | Sheet | Handle, title, content, action | Half (glass top) · full (solid) · form · share | Draggable, step-up | Rises from its button, sheet |
| 80 | Preview sheet | A record at a glance, Open | move |
||
| 81 | Popover | Short text | Explain | quick |
|
| 82 | Photo viewer | Photo, count, marks | Zoom, pan, sideways | Grows from the thumbnail | |
| 83 | Camera screen | Photo capture, full screen | |||
| 84 | Step-up | Passkey prompt, what is being confirmed | Sheet |
Shell and patterns: 12
| # | Component | Parts | Kinds | Features | Motion |
|---|---|---|---|---|---|
| 85 | Halo band | Rings, handle; drawer; pulled-down groups | By role (11 sets) | Draggable (three rest points), count | Follows the finger; spring.standard |
| 86 | Halo ring | Ring, icon or face, count | You · needs you · watching · shortcut (docs/SHELL.md section 2) |
Count | Forms once |
| 87 | Omnibar | Place, Add, Scan, Search; or one action; or result with Undo | Nine modes: rest · action · decision · several · result · typing · search · camera · working (docs/SHELL.md section 6) |
Count on Place | Capsules exchange, move |
| 88 | Top bar | Back, title, detail, chip | Screen · record | Title is a shared element | |
| 89 | Stream | Cards in order of need | By role | Long list | |
| 90 | Record page | Answers in order, then reveal rows | By record kind | Customer view, "see what they see" | Photo, title, amount are shared elements |
| 91 | Review step | Totals, what will happen, one action | Step-up; one tap only | ||
| 92 | Composer | Text, channel switch, attach, send | WhatsApp · email · both · note | Suggested, templates, queued | Bubble rises; mark changes sent to read |
| 93 | Suggestion | Source line, the suggestion, Accept, Edit, Dismiss | Inline · panel | Rises shift.s; never by itself over typing |
|
| 94 | Search | Field, recent, results by kind | Scan | Cross-fade | |
| 95 | Filter line | Chips, sort, count of results | |||
| 96 | Calculator | Inputs, live result, "use this" | Area · weight · container · price | Runs in the rules engine | Result cross-fades |
Total: 96. Twelve primitives, 84 components and patterns. The Halo band, Halo ring
and Omnibar are broken into 24 named parts in docs/SHELL.md section 8.
5. States every component has
| State | Looks like | Applies to |
|---|---|---|
| Rest | All | |
| Pressed | Scale and a light under the finger | Pressable |
| Focused | A ring, by keyboard or screen reader | Pressable, inputs |
| Selected | Accent, with a mark | Selectable |
| Disabled | 0.38 opacity; says why when touched | Actions, inputs |
| Read-only | Looks like text, not a faded input | Inputs |
| Busy | The label becomes a working mark; no second tap | Actions |
| Loading | Its own placeholder shape | Display |
| Empty | One line and one action | Lists, sets |
| Error | Bad tone, icon, and words saying what to do | Inputs, rows, banners |
| Queued, sent, failed | Sync mark | Anything done offline |
| Stale | "Saved copy" with its age | Display |
| Hidden amount | Covered | Sensitive |
| Suggested | A marked edge and source | Suggested |
6. From the mockup's functions to components
| Component | Replaces these mockup functions |
|---|---|
| Row | row, lrow, shr, cls, irow, setr, ord, chl, yn (as a kind of Choice list) |
| Card | oc, kp, ask, hero, sgg |
| Figure, Strip | big, fig, strip, kp |
| Stage tracker | stages, trk, step |
| Bar | agebar, ms |
| Chip, Status chip | chip, chips |
| Avatar, Faces | av, faces |
| Halo band, Halo ring | halo, ring, HR |
| Omnibar, Action bar | omni, act, sdock, pdock |
| Document | pdf |
| Timeline, Composer | tl, th, chs, W, E |
The rest of the 81 are icons, layout and the phone frame.
7. How they are coded
| Matter | Rule |
|---|---|
| Parts | Svelte snippets with fixed names. A part that is not given takes no space |
| Kinds and features | Typed properties. An unknown kind fails the build |
| No free styling | No class or style property on any component |
| Properties | At most about twelve per component. More means it should be split |
| Behaviour before look | Each component is built on the primitives; it never handles touch, glass or movement itself |
| Meaning in, look out | A screen passes "tone: warning", never a colour |
| Names for a screen reader | Required properties. A Button with only an icon will not build without a name |
| Size | Each component has a size budget; the Chart, Map, Camera, Scanner and Signature load only when first needed |
| Lists | Over about 50 rows use the Long list; rows off-screen cost nothing |
| Images | The Photo component alone loads images: right size for the screen, reserved space, placeholder colour, lazy below the fold |
| Money and quantity | Formatting comes from the rules engine, so a component cannot show a figure the server would round differently |
8. Order of building
- Tokens, and the checks that enforce them.
- Primitives 1 to 12, each with a test page. The owner tries Surface, Pressable and Draggable on both phones.
- The shell: Halo band and ring, Omnibar, Top bar, Sheet.
- The eight most used: Button, Chip, Row, List, Card, Field, Money, Status chip. With these, about half the screens can be put together.
- Inputs, then the rest of Showing and Telling.
- Heavy ones last: Chart, Map, Camera, Scanner, Signature, Document.
A component is finished when its page in the workshop shows every kind, feature and state, in both directions, both themes, every surface level and both size sets, and all of those pass the picture comparison, the accessibility check and its size budget.
9. Decisions
- The names in section 4, before anything is coded against them.
- Whether the Slider and Rating are needed at all in the first build. Proposed: Rating yes (delivery feedback), Slider no.
- Charts: three kinds only (bars, line, stacked bars). Proposed: yes; no pies.
- Whether a component may ever be restyled by a screen. Proposed: never.
The website and portal have their own parts (added 11 November 2026)
The 96 components here are the staff app's. The public website and the client portal
use a separate, much smaller set (header, link row, menu, opening, stone figure, word
list, figures, specification, reading text, timeline, field, progress line, action
bar, footer), listed in docs/SITE-DESIGN.md sections 4 and 16. The two sets share
tokens for brand colour and typeface only.
Components 97 to 112: the Money desk (added 12 November 2026)
Sixteen more, in docs/MONEY-DESK.md section 7: table, tree, calendar and period
grid, board, split panes, document viewer, rail, command field, bulk bar, file drop,
column mapper, entry grid, date range, side panel, print view, shortcut sheet. Table,
tree, calendar and board were already used by phone screens and were missing from
this list.
After the critique (12 November 2026)
From docs/CRITIQUE.md section 2. Added or changed:
| # | Component | |
|---|---|---|
| 113 | Checklist | Icon, one line, a state word. Replaces the three-figure strip where it was used as a checklist |
| 114 | Blocked action | The Omnibar's main action when it cannot be done: grey, the reason, a tap to the blocker |
| 115 | Outdoor template | For driver, warehouse and factory tasks: the role's Halo, one action at a fixed place 92 px tall, icon first, nothing that wraps |
| 116 | Piece picker | For a layout: look closer, choose, step, or pick from a numbered list |
| Status slot | The title bar's one chip: a state word and its icon. No counts, periods or filters | |
| Targets | 44 px or more, by padding where the drawn part is smaller; 8 px between neighbours | |
| Marks on photographs | Never. A solid badge with dark text | |
| Chip text | Contrast of 7 to 1 |