mapples 0.2.0-beta.1 → 0.2.0-beta.12

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.
Files changed (171) hide show
  1. package/README.md +133 -22
  2. package/dist/adopt/scan.d.ts +8 -2
  3. package/dist/adopt/scan.js +31 -13
  4. package/dist/adopt/scan.js.map +1 -1
  5. package/dist/api/agent.d.ts +85 -0
  6. package/dist/api/agent.js +92 -0
  7. package/dist/api/agent.js.map +1 -0
  8. package/dist/api/client.d.ts +12 -1
  9. package/dist/api/client.js +23 -2
  10. package/dist/api/client.js.map +1 -1
  11. package/dist/api/commit.d.ts +9 -0
  12. package/dist/api/commit.js +51 -2
  13. package/dist/api/commit.js.map +1 -1
  14. package/dist/api/errors.d.ts +1 -1
  15. package/dist/api/errors.js +15 -2
  16. package/dist/api/errors.js.map +1 -1
  17. package/dist/api/objects.d.ts +39 -6
  18. package/dist/api/objects.js +204 -11
  19. package/dist/api/objects.js.map +1 -1
  20. package/dist/api/poll.d.ts +5 -3
  21. package/dist/api/poll.js +17 -6
  22. package/dist/api/poll.js.map +1 -1
  23. package/dist/api/txPlan.d.ts +15 -0
  24. package/dist/api/txPlan.js +196 -0
  25. package/dist/api/txPlan.js.map +1 -0
  26. package/dist/assets/assets.d.ts +21 -0
  27. package/dist/assets/assets.js +62 -4
  28. package/dist/assets/assets.js.map +1 -1
  29. package/dist/codegen/emit.d.ts +4 -7
  30. package/dist/codegen/emit.js +10 -29
  31. package/dist/codegen/emit.js.map +1 -1
  32. package/dist/codegen/imports.d.ts +8 -15
  33. package/dist/codegen/imports.js +27 -72
  34. package/dist/codegen/imports.js.map +1 -1
  35. package/dist/codegen/instances.d.ts +5 -0
  36. package/dist/codegen/instances.js +30 -0
  37. package/dist/codegen/instances.js.map +1 -0
  38. package/dist/codegen/styles.d.ts +1 -0
  39. package/dist/codegen/styles.js +3 -0
  40. package/dist/codegen/styles.js.map +1 -0
  41. package/dist/commands/agent.d.ts +2 -0
  42. package/dist/commands/agent.js +87 -0
  43. package/dist/commands/agent.js.map +1 -0
  44. package/dist/commands/create.js +1 -0
  45. package/dist/commands/create.js.map +1 -1
  46. package/dist/commands/impl/adoptImpl.js +3 -0
  47. package/dist/commands/impl/adoptImpl.js.map +1 -1
  48. package/dist/commands/impl/agentImpl.d.ts +23 -0
  49. package/dist/commands/impl/agentImpl.js +426 -0
  50. package/dist/commands/impl/agentImpl.js.map +1 -0
  51. package/dist/commands/impl/createImpl.js +31 -4
  52. package/dist/commands/impl/createImpl.js.map +1 -1
  53. package/dist/commands/impl/initImpl.js +35 -5
  54. package/dist/commands/impl/initImpl.js.map +1 -1
  55. package/dist/commands/impl/syncImpl.js +30 -5
  56. package/dist/commands/impl/syncImpl.js.map +1 -1
  57. package/dist/commands/init.js +1 -0
  58. package/dist/commands/init.js.map +1 -1
  59. package/dist/index.js +12 -1
  60. package/dist/index.js.map +1 -1
  61. package/dist/merge/applyOps.d.ts +5 -2
  62. package/dist/merge/applyOps.js +75 -32
  63. package/dist/merge/applyOps.js.map +1 -1
  64. package/dist/merge/childrenOrder.d.ts +13 -0
  65. package/dist/merge/childrenOrder.js +51 -0
  66. package/dist/merge/childrenOrder.js.map +1 -0
  67. package/dist/merge/diff.d.ts +20 -1
  68. package/dist/merge/diff.js +77 -17
  69. package/dist/merge/diff.js.map +1 -1
  70. package/dist/merge/threeWay.d.ts +2 -2
  71. package/dist/merge/threeWay.js +74 -10
  72. package/dist/merge/threeWay.js.map +1 -1
  73. package/dist/merge/toEdits.d.ts +1 -3
  74. package/dist/merge/toEdits.js +3 -91
  75. package/dist/merge/toEdits.js.map +1 -1
  76. package/dist/nav/navigatorTree.d.ts +78 -0
  77. package/dist/nav/navigatorTree.js +419 -0
  78. package/dist/nav/navigatorTree.js.map +1 -0
  79. package/dist/nav/placement.d.ts +53 -0
  80. package/dist/nav/placement.js +260 -0
  81. package/dist/nav/placement.js.map +1 -0
  82. package/dist/nav/routeTree.d.ts +8 -2
  83. package/dist/nav/routeTree.js +85 -152
  84. package/dist/nav/routeTree.js.map +1 -1
  85. package/dist/nav/screenOptions.d.ts +15 -0
  86. package/dist/nav/screenOptions.js +213 -0
  87. package/dist/nav/screenOptions.js.map +1 -0
  88. package/dist/project/agentState.d.ts +30 -0
  89. package/dist/project/agentState.js +42 -0
  90. package/dist/project/agentState.js.map +1 -0
  91. package/dist/project/baseStore.d.ts +19 -1
  92. package/dist/project/baseStore.js +28 -0
  93. package/dist/project/baseStore.js.map +1 -1
  94. package/dist/project/componentsMap.d.ts +7 -0
  95. package/dist/project/componentsMap.js +21 -0
  96. package/dist/project/componentsMap.js.map +1 -0
  97. package/dist/project/config.d.ts +12 -3
  98. package/dist/project/config.js +11 -2
  99. package/dist/project/config.js.map +1 -1
  100. package/dist/project/env.d.ts +10 -3
  101. package/dist/project/env.js +23 -5
  102. package/dist/project/env.js.map +1 -1
  103. package/dist/project/pagesMap.d.ts +2 -0
  104. package/dist/project/pagesMap.js.map +1 -1
  105. package/dist/project/secret.d.ts +6 -2
  106. package/dist/project/secret.js +11 -5
  107. package/dist/project/secret.js.map +1 -1
  108. package/dist/services/adoptService.d.ts +3 -0
  109. package/dist/services/adoptService.js +357 -38
  110. package/dist/services/adoptService.js.map +1 -1
  111. package/dist/services/agentInstall.d.ts +80 -0
  112. package/dist/services/agentInstall.js +309 -0
  113. package/dist/services/agentInstall.js.map +1 -0
  114. package/dist/services/agentLease.d.ts +2 -0
  115. package/dist/services/agentLease.js +32 -0
  116. package/dist/services/agentLease.js.map +1 -0
  117. package/dist/services/clientFactory.d.ts +2 -0
  118. package/dist/services/clientFactory.js +20 -3
  119. package/dist/services/clientFactory.js.map +1 -1
  120. package/dist/services/doctorService.js +77 -66
  121. package/dist/services/doctorService.js.map +1 -1
  122. package/dist/services/scaffold.d.ts +3 -0
  123. package/dist/services/scaffold.js +16 -0
  124. package/dist/services/scaffold.js.map +1 -1
  125. package/dist/services/syncEngine.d.ts +7 -0
  126. package/dist/services/syncEngine.js +766 -306
  127. package/dist/services/syncEngine.js.map +1 -1
  128. package/dist/style/theme.js +17 -1
  129. package/dist/style/theme.js.map +1 -1
  130. package/dist/types.d.ts +55 -2
  131. package/dist/types.js +25 -0
  132. package/dist/types.js.map +1 -1
  133. package/dist/ui/report.d.ts +15 -0
  134. package/dist/ui/report.js +30 -0
  135. package/dist/ui/report.js.map +1 -1
  136. package/package.json +4 -2
  137. package/templates/agent/agents-md/AGENTS.md +8 -0
  138. package/templates/agent/claude/CLAUDE.md +7 -0
  139. package/templates/agent/claude/mcp.json +11 -0
  140. package/templates/agent/claude/settings.json +26 -0
  141. package/templates/agent/codex/config.toml +6 -0
  142. package/templates/agent/codex/hooks.json +26 -0
  143. package/templates/agent/cursor/hooks.json +9 -0
  144. package/templates/agent/cursor/mcp.json +10 -0
  145. package/templates/agent/mapples.md +124 -0
  146. package/templates/agent/skills/mapples-conventions/SKILL.md +137 -0
  147. package/templates/agent/skills/mapples-design/SKILL.md +235 -0
  148. package/templates/agent/skills/mapples-design/reference/component-library.md +128 -0
  149. package/templates/agent/skills/mapples-design/reference/design-tokens.md +132 -0
  150. package/templates/agent/skills/mapples-design/reference/layout-contract.md +227 -0
  151. package/templates/agent/skills/mapples-design/reference/lint-checklist.md +51 -0
  152. package/templates/agent/skills/mapples-design/reference/plan.md +95 -0
  153. package/templates/agent/skills/mapples-design/reference/playbooks/empty-states.md +14 -0
  154. package/templates/agent/skills/mapples-design/reference/playbooks/forms-and-auth.md +22 -0
  155. package/templates/agent/skills/mapples-design/reference/playbooks/home-dashboard.md +14 -0
  156. package/templates/agent/skills/mapples-design/reference/playbooks/list-and-detail.md +18 -0
  157. package/templates/agent/skills/mapples-design/reference/playbooks/microcopy.md +20 -0
  158. package/templates/agent/skills/mapples-design/reference/playbooks/navigation-chrome.md +21 -0
  159. package/templates/agent/skills/mapples-design/reference/playbooks/onboarding-flow.md +15 -0
  160. package/templates/agent/skills/mapples-design/reference/playbooks/screen-flow-wiring.md +37 -0
  161. package/templates/agent/skills/mapples-design/reference/playbooks/settings-profile.md +16 -0
  162. package/templates/agent/skills/mapples-design/reference/playbooks/stats-and-progress.md +17 -0
  163. package/templates/agent/skills/mapples-design/reference/playbooks/visual-hierarchy.md +18 -0
  164. package/templates/agent/skills/mapples-design/reference/style-guides.md +92 -0
  165. package/templates/agent/skills/mapples-sync/SKILL.md +93 -0
  166. package/templates/app/_layout.tsx +9 -1
  167. package/templates/app.json +0 -1
  168. package/templates/gitignore +2 -0
  169. package/templates/mapples/sid.d.ts +6 -0
  170. package/templates/metro.config.js +11 -0
  171. package/templates/package.json +13 -10
@@ -0,0 +1,124 @@
1
+ <!-- GENERATED by Mapples __CLI_VERSION__ — re-run npx -y mapples@__CLI_VERSION__ agent install --force to refresh -->
2
+ # Mapples conventions
3
+
4
+ This app is linked to a **Mapples Creator** project (visual editor at creator.mapples.io).
5
+ The link is the `mapples` CLI: screens, components and design tokens are TSX and TS files in
6
+ this repo, and `npx -y mapples@__CLI_VERSION__ sync` pushes your edits to Creator and pulls Creator's edits back
7
+ (two-way, 3-way merged). Every write to the project goes through `npx -y mapples@__CLI_VERSION__ sync` — there is no
8
+ other write path from here. The `mapples` MCP server (`.mcp.json`) is **read-only**: use it to
9
+ look at the project (style tokens, assets); never expect it to change anything.
10
+
11
+ ## Skills
12
+
13
+ - `__DESIGN_COMMAND__` — build the whole app from a product brief (tokens → plan → screens → wiring → review).
14
+ - `mapples-conventions` — how Mapples files are written (auto-applies when you edit them).
15
+ - `mapples-sync` — running `npx -y mapples@__CLI_VERSION__ sync`, reading its JSON report, handling conflicts and exit codes.
16
+
17
+ ## Where things live
18
+
19
+ | What | Where | Owner |
20
+ | --- | --- | --- |
21
+ | A screen in the navigation | `__ROUTES_DIR__/<segment>.tsx` (expo-router route file) | you + Creator (merged) |
22
+ | A screen outside the navigation | `__PAGES_DIR__/<Name>.tsx` | you + Creator (merged) |
23
+ | A navigator (stack / tabs / drawer) | `__ROUTES_DIR__/**/_layout.tsx` | **CLI** — regenerated every sync |
24
+ | A reusable Creator component | `__COMPONENTS_DIR__/<Name>.tsx` | you + Creator (merged) |
25
+ | Design tokens (theme, typography, sizing) | `mapples/theme.ts` | you + Creator (merged per key) |
26
+ | Assets | `mapples/assets/` + `assetMap.ts` | **CLI** |
27
+ | Project state (ids, base, head) | `.mapples/` | **CLI** — never edit |
28
+ | Product brief, chosen style, plan | `mapples/design.md` | you |
29
+
30
+ Read `.mapples/config.json` for the real `routesDir` / `pagesDir` / `componentsDir` of this app.
31
+
32
+ ## The rules that cannot be broken
33
+
34
+ 1. **`$sid` is opaque.** Every element Creator knows carries `$sid="nd_…"`. Never invent,
35
+ renumber, duplicate, move between elements or delete a `$sid`. New elements get **no**
36
+ `$sid` — `npx -y mapples@__CLI_VERSION__ sync` tags them and rewrites the file. Deleting an element deletes it in
37
+ Creator on the next sync (that is a real delete — say so when you do it).
38
+ 2. **Never touch CLI-owned files**: `_layout.tsx` under the routes dir, `assetMap.ts`, anything
39
+ in `.mapples/`, and `_depr_*` files. The one exception is the handshake for a new route
40
+ group: a `_layout.tsx` you create in a new `(group)/` directory must start with
41
+ `// GENERATED by Mapples` so the CLI adopts its navigator kind and owns it from then on.
42
+ 3. **Never delete `.mapples/head`, `.mapples/base/` or `.mapples/pages.json`** — they are the
43
+ sync base; losing them turns the next sync into a cold bootstrap.
44
+ 4. **Sync after every meaningful step** — `npx -y mapples@__CLI_VERSION__ sync --yes --json` — and read the report.
45
+ Exit 2 means conflicts (your file was kept as `_depr_<ts>_<name>.tsx.old`, the file was
46
+ regenerated from Creator: re-apply your intent onto the new file, never restore the old one).
47
+ 5. **A `_depr_` file is a signal, not a resource.** Diff it against the regenerated file, carry
48
+ the intent over, leave the `.old` file alone (the user deletes it).
49
+
50
+ ## Writing a screen
51
+
52
+ ```tsx
53
+ // __ROUTES_DIR__/index.tsx — route files get a `// mapples-route:` marker from the CLI; keep it.
54
+ import { ScrollView, Typography, View } from '@mapples/ui';
55
+ import { Button, Card, SectionHeader } from '@mapples/components';
56
+ import { Styler } from '@mapples/style';
57
+
58
+ export default function Home() {
59
+ return (
60
+ <ScrollView styled={{ contentContainerStyle: styles.content }}>
61
+ <Typography text="Good morning, Alex" variant="Headline" styled={{ style: styles.title }} />
62
+ <SectionHeader title="Today" actionLabel="See all" />
63
+ <Card variant="elevated" styled={{ style: styles.card }}>
64
+ <Typography text="Two habits left" variant="Body" />
65
+ </Card>
66
+ <Button
67
+ label="Start a session"
68
+ variant="filled"
69
+ size="lg"
70
+ fullWidth
71
+ $actions={{ onPress: { type: 'mapples:navigate', staticData: { pageUuid: '<uuid>' } } }}
72
+ />
73
+ </ScrollView>
74
+ );
75
+ }
76
+
77
+ const styles = Styler.create({
78
+ content: { padding: 'sizing.screenPadding', gap: 'sizing.lg', paddingBottom: 32 },
79
+ title: { color: 'theme.text.primary' },
80
+ card: { gap: 'sizing.sm' },
81
+ });
82
+ ```
83
+
84
+ - Primitives (`View`, `ScrollView`, `Typography`, `Image`, `Icon`, `Pressable`, `TextInput`, …)
85
+ come from `@mapples/ui`; the themed library (`Button`, `Card`, `ListItem`, `InputField`, …)
86
+ from `@mapples/components` — the full table is in the `mapples-conventions` skill.
87
+ - Every style is a literal object hoisted into `const styles = Styler.create({...})` and
88
+ referenced as `styled={{ style: styles.x }}` (slots: `style`, `styleTypography`, `styleSvg`,
89
+ `styleImage`, `contentContainerStyle`, `placeholderTextColor`). Creator reads the dictionary.
90
+ - Token strings replace raw values: colors `'theme.primary.main'`, `'theme.text.secondary'`,
91
+ `'theme.background.card'`; spacing `'sizing.md'`, `'sizing.screenPadding'`, or `'*4'` (4 × base).
92
+ Raw hex only inside gradients (tokens do not resolve there).
93
+ - Text is always `Typography` with `text` + `variant` (`Headline`, `Subtitle`, `Body`, `Caption`,
94
+ `Overline`, `Button`, `Link`, `Label`, `Code`). Never `Text`, never JSX children text.
95
+ - Props are literals. An expression prop (`{count}`) is kept in code only and reported as
96
+ `NON_LITERAL_PROP`; Creator shows the last literal value.
97
+ - Navigation from code: `$actions={{ onPress: { type: 'mapples:navigate', staticData: { pageUuid } } }}`
98
+ on the element's primary event. The target's `pageUuid` is the `uuid` field of
99
+ `.mapples/base/pages/<pageId>.json`; `<pageId>` is the key in `.mapples/pages.json` whose
100
+ `file` is the target route file. Add a `router.push('/<segment>')` `onPress` handler too so
101
+ the built app navigates.
102
+ - Images: `<Image source="https://picsum.photos/seed/<topic>/<w>/<h>" contentFit="cover" />`
103
+ with an explicit width/height in `styled.style`. Creator asset references (`$refs`) are
104
+ Creator-side; do not invent them.
105
+
106
+ ## Design tokens
107
+
108
+ `mapples/theme.ts` exports three literal objects — `theme`, `typography`, `sizing` — with the
109
+ exact shape documented in `__SKILLS_DIR__/mapples-design/reference/design-tokens.md`. Creating
110
+ or editing the file and syncing pushes the tokens to Creator (missing file + empty project = no-op).
111
+
112
+ ## The agent lease
113
+
114
+ Creator shows "__AGENT_LABEL__ is working" and locks its own chat while you hold the project's
115
+ lease. You do not manage it for ordinary requests: this app's hooks take the lease as soon as
116
+ the user sends a prompt and release it when you finish responding, even when you change
117
+ nothing. Do not call `agent start` or `agent stop` yourself for a normal request.
118
+
119
+ The first thing `__DESIGN_COMMAND__` does — before syncing or asking the user anything — is
120
+ `npx -y mapples@__CLI_VERSION__ agent start`, which holds a lease on the project so Creator shows
121
+ "__AGENT_LABEL__ is working" and locks its own chat for the whole run, questions included. `npx -y mapples@__CLI_VERSION__ agent step` reports progress;
122
+ `npx -y mapples@__CLI_VERSION__ agent stop` releases. `.mapples/agent.json` exists while the lease is held and labels
123
+ every sync commit "__AGENT_LABEL__: <step>". Exit codes: `3` = the lease is gone (Creator
124
+ disconnected you or it expired — stop and tell the user), `4` = another agent holds the project.
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: mapples-conventions
3
+ description: How Mapples-managed files are written — file layout, $sid rules, $actions/$data/$refs, the @mapples/ui vs @mapples/components import table, token strings and Styler dictionaries. Use whenever editing a route file, mapples/pages, mapples/components or mapples/theme.ts in a Mapples-linked Expo app.
4
+ ---
5
+ <!-- GENERATED by Mapples __CLI_VERSION__ — re-run npx -y mapples@__CLI_VERSION__ agent install --force to refresh -->
6
+ # Mapples conventions
7
+
8
+ Read `__CONVENTIONS_PATH__` first (the summary). This skill is the reference.
9
+
10
+ ## File layout
11
+
12
+ | File | Role | Editable |
13
+ | --- | --- | --- |
14
+ | `__ROUTES_DIR__/<segment>.tsx`, `__ROUTES_DIR__/(group)/<segment>.tsx` | a screen that is in the navigation; `index.tsx` is the section's first screen | yes — merged with Creator |
15
+ | `__ROUTES_DIR__/**/_layout.tsx` | the navigator (Stack/Tabs/Drawer); regenerated from Creator's navigation on every sync | **no** (handshake only, below) |
16
+ | `__PAGES_DIR__/<Name>.tsx` | a screen not (yet) in the navigation; moves into the routes dir when placed | yes |
17
+ | `__COMPONENTS_DIR__/<Name>.tsx` | a reusable Creator component; instances are `import X from '…/<Name>'` + `<X styled />` | yes |
18
+ | `mapples/theme.ts` | design tokens (`theme`, `typography`, `sizing`) | yes — merged per key |
19
+ | `mapples/assets/`, `mapples/assetMap.ts` | Creator assets | **no** |
20
+ | `mapples/sid.d.ts` | types for the `$sid`/`$refs`/`$data`/`$actions`/`$fallback` attributes | no |
21
+ | `.mapples/` | config, secret, head, base, pages.json, components.json, outbox, agent.json | **no** |
22
+ | `_depr_<ts>_<name>.tsx.old` | your version of a file the CLI had to regenerate | read, never restore |
23
+
24
+ The route marker `// mapples-route: <id> — “<Name>”` on line 1 of a route file is the route's
25
+ identity: keep it verbatim. Renaming the file renames the route in Creator.
26
+
27
+ ## `$sid`
28
+
29
+ - `$sid="nd_…"` is the canvas node id. Opaque: never parse beyond the prefix, never invent,
30
+ never renumber, never copy to another element, never reuse a deleted one.
31
+ - New elements carry **no** `$sid`. `npx -y mapples@__CLI_VERSION__ sync` tags them (report: `tagged N new element(s)`)
32
+ and rewrites the file with the ids — re-read the file after a sync before editing again.
33
+ - Wrapping an existing element (moving it inside a new `View`) keeps its `$sid`; the sync sees a
34
+ move. Removing an element with a `$sid` deletes it in Creator.
35
+ - `$fallback={{ w, h }}` sits on `Custom` nodes (a non-Mapples component the canvas cannot
36
+ render); leave it as the CLI wrote it.
37
+
38
+ ## Transient attributes
39
+
40
+ | Attribute | Shape | Meaning |
41
+ | --- | --- | --- |
42
+ | `$actions` | `{ onPress: { type: 'mapples:navigate', staticData: { pageUuid: '<uuid>' } } }` | Creator prototype connection on that event. Other action types (`mapples:setState`, `mapples:goBack`, `mapples:switchTab`) exist; navigate is the one you write. |
43
+ | `$data` | `{ visible: { key: 'vars.sheetOpen', active: true } }` | a data binding of a prop to a project variable — only when the project already has the variable |
44
+ | `$refs` | `{ source: 'ref(image:<uuid>)' }` | a Creator asset reference — Creator-side; never invent one |
45
+
46
+ `pageUuid` lookup: `.mapples/pages.json` maps `pageId → { file, name, route, routeId }`; the
47
+ uuid the action needs is the `uuid` field of `.mapples/base/pages/<pageId>.json`. Both are
48
+ rewritten by every sync — read them fresh.
49
+
50
+ ## Imports
51
+
52
+ `@mapples/ui` — primitives (the canvas' base element types):
53
+
54
+ `View`, `Container`, `SafeAreaView`, `ScrollView`, `HorizontalScrollView`, `FlatList`,
55
+ `GridTwoColumns`, `GridThreeColumns`, `GridFourColumns`, `GradientBackground`,
56
+ `ImageBackgroundView`, `Typography`, `Text` (never on a screen — use Typography), `Image`,
57
+ `Icon`, `Svg`, `Vector`, `Video`, `QRCode`, `BarCode`, `Pressable`, `IconButton`, `TextInput`,
58
+ `Select`, `FormView`, `TextField`, `SubmitButton`, `Button` (themed like the library below, but
59
+ imported from `@mapples/ui`).
60
+
61
+ `@mapples/components` — the themed library (paints itself from the tokens; prefer it):
62
+
63
+ | Group | Types |
64
+ | --- | --- |
65
+ | actions | `ButtonGroup`, `Fab`, `TextLink`, `BottomActionBar` (`Button` is an `@mapples/ui` import) |
66
+ | input | `InputField`, `SelectField`, `Checkbox`, `RadioGroup`, `Switch`, `Slider`, `NumberStepper`, `PinInput`, `SearchBar`, `ChatComposer`, `SegmentedControl`, `Rating`, `ChipGroup`, `Chip` |
67
+ | content | `Card`, `MediaCard`, `List`, `ListItem`, `SectionHeader`, `Divider`, `Avatar`, `AvatarGroup`, `Badge`, `StatTile`, `Table`, `Timeline`, `ImageCarousel`, `MessageBubble`, `Accordion`, `Skeleton` |
68
+ | navigation | `TopAppBar`, `BottomNavigationBar`, `Tabs`, `Breadcrumbs`, `Steps`, `PageControl` |
69
+ | feedback | `ProgressBar`, `ProgressCircle`, `Spinner`, `Banner`, `Snackbar`, `EmptyState` |
70
+ | overlays | `Dialog`, `BottomSheet`, `ActionSheet` |
71
+
72
+ Anything else you import (a third-party or hand-written component) becomes an opaque `Custom`
73
+ node on the canvas with a `$fallback` size — allowed, but Creator cannot design inside it.
74
+
75
+ `Styler` comes from `@mapples/style`; `router` from `expo-router`.
76
+
77
+ ## Styling
78
+
79
+ ```tsx
80
+ <View styled={{ style: styles.row }}>
81
+ <Icon iconName="checkmark-circle" styled={{ styleSvg: styles.icon }} />
82
+ <Typography text="Done" variant="Label" styled={{ styleTypography: styles.done }} />
83
+ </View>
84
+
85
+ const styles = Styler.create({
86
+ row: { flexDirection: 'row', alignItems: 'center', gap: 'sizing.sm' },
87
+ icon: { width: 20, height: 20, color: 'theme.system.success' },
88
+ done: { color: 'theme.text.secondary' },
89
+ });
90
+ ```
91
+
92
+ - `styled={{ style }}` is the element's own box; `styleTypography` the text of a control
93
+ (Button label, ListItem title); `styleSvg` an Icon's glyph (`color`, `width`, `height`);
94
+ `styleImage` the picture inside an Image; `contentContainerStyle` the scrolling content of a
95
+ ScrollView/FlatList/HorizontalScrollView; `placeholderTextColor` a TextInput's placeholder.
96
+ - One `Styler.create` dictionary per file, below the component; keys say what the element shows
97
+ and is (`signInText`, `heroImage`, `listContent`). A `StyleSheet.create` dictionary is also
98
+ read, but write `Styler.create`.
99
+ - A style may be a single dictionary reference (`styles.card`) or a literal; never an array,
100
+ never a computed expression (Creator cannot read it → `NON_LITERAL_PROP`).
101
+ - Token strings: colors `'theme.<group>.<key>'` (`theme.primary.main`, `theme.primary.contrast`,
102
+ `theme.background.primary`, `theme.background.card`, `theme.text.primary|secondary|tertiary`,
103
+ `theme.neutral.n200`, `theme.system.error`); spacing `'sizing.<key>'` (`xs sm md lg xl
104
+ screenPadding gap radius radiusLarge control card icon`) or `'*N'` (N × base). Gradients take
105
+ literal hex/rgba only.
106
+ - `boxShadow` is an object `{ x, y, radius, color }`, never a CSS string.
107
+ - Library components set their own defaults; change their look through `variant`, `size`,
108
+ `tone` props and the slots — never rebuild one from Views.
109
+
110
+ ## Layouts (`_layout.tsx`)
111
+
112
+ The CLI generates every layout from Creator's navigation document. Do not edit or style them
113
+ (header/tab-bar options are set in Creator). To add a **new** section, create the directory
114
+ with a layout whose first line is `// GENERATED by Mapples`:
115
+
116
+ ```tsx
117
+ // GENERATED by Mapples — this layout is owned by the CLI and regenerated from the navigation document.
118
+ import { Tabs } from 'expo-router';
119
+
120
+ export default function MainLayout() {
121
+ return <Tabs />;
122
+ }
123
+ ```
124
+
125
+ `npx -y mapples@__CLI_VERSION__ sync --yes` then adopts the directory as a tabs navigator (`<Stack>` → stack,
126
+ `<Drawer>` from `expo-router/drawer` → drawer; no layout → stack) and regenerates the file. A
127
+ layout **without** the header is treated as yours and deprecated on the first sync.
128
+
129
+ ## What not to do
130
+
131
+ - Do not run `npx -y mapples@__CLI_VERSION__ init`, `npx -y mapples@__CLI_VERSION__ create`, or edit `.mapples/config.json`.
132
+ - Do not restore a `_depr_` file over the regenerated one.
133
+ - Do not hand-write `$sid`s, `$refs`, or navigator options.
134
+ - Do not put JSX children text inside `Typography` (`text` prop only), and do not use `Text`.
135
+ - Do not spread props or map arrays into JSX inside a managed element tree — Creator reads
136
+ literal trees; put dynamic lists behind a `FlatList`/`List` with literal `items` where
137
+ possible, or accept the `NON_LITERAL_PROP` note.
@@ -0,0 +1,235 @@
1
+ ---
2
+ name: mapples-design
3
+ description: Build a Mapples-linked Expo app from a product brief the way the Creator's in-app AI does — design tokens, an implementation plan, one screen per phase from the design playbooks, wiring and a review — writing route files and mapples/theme.ts and pushing each phase with `npx -y mapples@__CLI_VERSION__ sync` while holding the project's agent lease. Use when the user asks to design, generate or build the app, its screens or its design system.
4
+ argument-hint: "<product brief> [--scope single|minimal|basic|advanced]"
5
+ ---
6
+ <!-- GENERATED by Mapples __CLI_VERSION__ — re-run npx -y mapples@__CLI_VERSION__ agent install --force to refresh -->
7
+ # mapples-design — build the app from a brief
8
+
9
+ You are the product designer and builder for this app. Your bar is a finished screen a
10
+ designer would ship — not a wireframe. Everything you make is a file in this repo; every phase
11
+ ends with `npx -y mapples@__CLI_VERSION__ sync --yes --json`, which pushes it to Creator where the user watches it land.
12
+
13
+ ## First: take the project's lease
14
+
15
+ Do this **before anything else** — before reading references, syncing, or asking the user a
16
+ single question. While you hold the lease Creator locks its own AI chat and refuses Save, so
17
+ nobody changes the project from the browser while you are still asking about the brief.
18
+
19
+ 1. `.mapples/config.json` must exist (the app is linked). If not: stop and ask the user to run
20
+ `npx -y mapples@__CLI_VERSION__ init --secret <key> --agent __AGENT_FLAG__` — never run it yourself.
21
+ 2. Take the lease, pre-declaring the fixed step titles:
22
+
23
+ ```bash
24
+ npx -y mapples@__CLI_VERSION__ agent start --agent __AGENT_ID__ --label "__AGENT_LABEL__" --steps "Brief,Style guides,Design tokens,Plan,Scaffold navigation & screens" --json
25
+ ```
26
+
27
+ Exit 4 = busy: another agent session holds the project. That is the only question you may
28
+ ask before holding the lease — whether to take over (re-run with `--takeover`, which
29
+ disconnects the other session). Never take over silently; if the user says no, stop.
30
+ 3. Mark the brief running at once — the brief questions happen inside this step:
31
+
32
+ ```bash
33
+ npx -y mapples@__CLI_VERSION__ agent step --index 0 --title "Brief" --status running --json
34
+ ```
35
+
36
+ Only then:
37
+
38
+ 4. Read `__CONVENTIONS_PATH__` and the `mapples-conventions` and `mapples-sync` skills.
39
+ 5. `npx -y mapples@__CLI_VERSION__ sync --yes --json` — be current before designing. Exit 2 here means the repo
40
+ already had conflicts: resolve them (see `mapples-sync`) before going on.
41
+ 6. Read `mapples/design.md` if it exists: a previous run's brief, chosen style and plan. Resume
42
+ from the first phase whose output is missing rather than redoing everything.
43
+
44
+ If the user stops the run at any point — including while you are still asking questions —
45
+ release the lease before you reply (`agent stop --status failed --error "stopped by the user"`).
46
+
47
+ Reference material for this skill lives next to it:
48
+
49
+ - `reference/style-guides.md` — art directions and style guides (phase 1)
50
+ - `reference/design-tokens.md` — the `mapples/theme.ts` contract and template (phase 2)
51
+ - `reference/plan.md` — scopes and the implementation plan (phase 3)
52
+ - `reference/layout-contract.md` — the rules every screen obeys (phases 5…)
53
+ - `reference/component-library.md` — what to reach for, by need
54
+ - `reference/lint-checklist.md` — the review pass (phase N)
55
+ - `reference/playbooks/<name>.md` — screen-kind playbooks, loaded per screen
56
+
57
+ ## Steps and the lease
58
+
59
+ The lease taken above covers the whole run. Steps have a **fixed index convention** shared
60
+ with Creator's progress log:
61
+
62
+ ```
63
+ 0 Brief · 1 Style guides · 2 Design tokens · 3 Plan · 4 Scaffold navigation & screens ·
64
+ 5…N-2 one per plan step ("Build the Home screen", …) · N-1 Wiring · N Review
65
+ ```
66
+
67
+ After the plan exists (phase 3), the remaining titles are declared as they run:
68
+ `npx -y mapples@__CLI_VERSION__ agent step --index 5 --title "Build the Home screen" --status running` creates the step.
69
+ Wrap **every** phase:
70
+
71
+ ```bash
72
+ npx -y mapples@__CLI_VERSION__ agent step --index <i> --title "<title>" --status running --json
73
+ # … the work …
74
+ npx -y mapples@__CLI_VERSION__ agent step --index <i> --title "<title>" --status done --detail "<one line>" --json
75
+ ```
76
+
77
+ Exit 3 from any `agent` or `sync` command = the lease is gone (Creator disconnected you or the
78
+ lease expired). Stop immediately, do not sync again, and tell the user what was finished.
79
+
80
+ Always end the run — success or not:
81
+
82
+ ```bash
83
+ npx -y mapples@__CLI_VERSION__ agent stop --status done --json
84
+ npx -y mapples@__CLI_VERSION__ agent stop --status failed --error "<what blocked the run>" --json
85
+ ```
86
+
87
+ A phase's syncs are labelled with the running step in Creator's history automatically.
88
+
89
+ ## Phase 0 — Brief and scope
90
+
91
+ Step 0 is already running (you marked it right after taking the lease).
92
+
93
+ Input: `$ARGUMENTS` (the brief, optionally `--scope single|minimal|basic|advanced`). If the
94
+ brief is missing or too thin to name the audience, the core value and the mood, ask **one**
95
+ round of questions (with your multiple-choice question tool, when you have one) — audience, the one thing the app must do well, the
96
+ feeling it should have, and the scope if absent (default `basic`). Then write
97
+ `mapples/design.md`:
98
+
99
+ ```md
100
+ # <App name>
101
+ ## Brief
102
+ <the brief, cleaned up, 3–8 lines: audience, core value, mood, must-haves, non-goals>
103
+ ## Scope
104
+ <single|minimal|basic|advanced> — <one line why>
105
+ ```
106
+
107
+ Report the step done with the scope in `--detail`.
108
+
109
+ ## Phase 1 — Style guides
110
+
111
+ Follow `reference/style-guides.md`: propose 3 art directions **for this product**, then 3
112
+ compact style guides. Show them to the user as a table (name, direction, palette swatches as
113
+ hex, headline/body fonts, radius, elevation language, one don't) and ask which one — or accept
114
+ the user's pick from the brief. Append the chosen guide to `design.md` under `## Style guide`.
115
+
116
+ ## Phase 2 — Design tokens
117
+
118
+ Follow `reference/design-tokens.md` exactly: write `mapples/theme.ts` (create it — a missing
119
+ file and an empty project is a no-op, so the file is what pushes the tokens). Then
120
+
121
+ ```bash
122
+ npx -y mapples@__CLI_VERSION__ sync --yes --json
123
+ ```
124
+
125
+ Assert: `exitCode` 0, `pushedOps` ≥ 3 (Theme, Typography, Sizing updates) and no
126
+ `conflicts`. If `pushedOps` is 0, the file did not parse as three literal exports — fix the
127
+ file, do not move on. Record the token summary (primary, background, fonts, radius) in
128
+ `design.md` under `## Tokens`.
129
+
130
+ ## Phase 3 — Plan
131
+
132
+ Follow `reference/plan.md`: decisions, navigation (sections → screens), entry screen, ordered
133
+ build steps. Append it to `design.md` under `## Plan` **and** declare the remaining steps:
134
+
135
+ ```bash
136
+ npx -y mapples@__CLI_VERSION__ agent step --index 5 --title "<plan step 1 title>" --status pending --json
137
+ …
138
+ npx -y mapples@__CLI_VERSION__ agent step --index <N-1> --title "Wiring" --status pending --json
139
+ npx -y mapples@__CLI_VERSION__ agent step --index <N> --title "Review" --status pending --json
140
+ ```
141
+
142
+ Show the plan to the user in 6–10 lines; continue unless they object.
143
+
144
+ ## Phase 4 — Scaffold navigation and screens
145
+
146
+ Read `.mapples/config.json` for `routesDir` (`__ROUTES_DIR__` here). Then, for the plan's
147
+ navigation:
148
+
149
+ - The root layout already exists and is CLI-owned — leave it.
150
+ - One directory per section: `<routesDir>/(<section-slug>)/` with a `_layout.tsx` whose first
151
+ line is `// GENERATED by Mapples` and whose body renders `<Stack />`, `<Tabs />` (from
152
+ `expo-router`) or `<Drawer />` (from `expo-router/drawer`) per the section's type. This header
153
+ is the handshake: the CLI adopts the navigator kind from it and owns the file from then on.
154
+ - One **minimal** route file per screen: `index.tsx` for the section's first screen, `<slug>.tsx`
155
+ for the rest — a `View` with one `Typography` (`variant="Headline"`, the screen name). Real
156
+ content comes per screen later; the scaffold only mints ids. When the plan has a single
157
+ section, put its files at the root of the routes dir instead of a group.
158
+ - Do not write to `.mapples/`, do not touch the root `_layout.tsx`, do not create pages under
159
+ `pagesDir`.
160
+
161
+ ```bash
162
+ npx -y mapples@__CLI_VERSION__ sync --yes --json
163
+ ```
164
+
165
+ Assert no conflicts, then read `.mapples/pages.json`: every scaffolded file must be a value's
166
+ `file` with a `routeId`. Note the `pageId` per screen; the `uuid` for `$actions` is in
167
+ `.mapples/base/pages/<pageId>.json`. Screens now exist as empty pages in Creator. Re-read each
168
+ route file — the CLI added the `// mapples-route:` marker and `$sid`s.
169
+
170
+ Navigator and route options (headers, tab icons, initial route, modal presentation) are set in
171
+ Creator, not from code, in this version: describe the intended chrome in `design.md` under
172
+ `## Navigation chrome` so the user can apply it.
173
+
174
+ ## Phases 5…N-2 — one screen step at a time
175
+
176
+ For each plan step, in order:
177
+
178
+ 1. `agent step … --status running`.
179
+ 2. Load the matching playbook(s) from `reference/playbooks/` (read the file; once per run):
180
+ `onboarding-flow`, `home-dashboard`, `list-and-detail`, `forms-and-auth`, `empty-states`,
181
+ `stats-and-progress`, `settings-profile`, `navigation-chrome`; `visual-hierarchy` and
182
+ `microcopy` with the first screen step.
183
+ 3. Re-read the route file. Write the **whole screen** in one edit: keep the marker line, keep
184
+ every existing `$sid` on the element it is on, add none. Obey `reference/layout-contract.md`
185
+ and the chosen style guide's instructions (they outrank the contract where they differ).
186
+ Real copy from the brief; picsum photos in every hero/featured/thumb slot.
187
+ 4. `npx -y mapples@__CLI_VERSION__ sync --yes --json`. Assert `exitCode` 0; read `warnings` and fix what is yours
188
+ (NON_LITERAL_PROP on a value you can make literal, UNKNOWN_ELEMENT). Exit 2 → resolve per
189
+ `mapples-sync`, sync again.
190
+ 5. Re-read the file (it now carries `$sid`s), run it through `reference/lint-checklist.md`
191
+ mentally, fix, sync again if you changed anything.
192
+ 6. `agent step … --status done --detail "<screen>: <what it shows>"`.
193
+
194
+ Two screens in one plan step: do them one after the other inside the step, syncing after each.
195
+
196
+ ## Phase N-1 — Wiring
197
+
198
+ Load `playbooks/screen-flow-wiring.md`. For every navigation the plan names, add to the source
199
+ element's primary event both the Creator connection and the runtime handler:
200
+
201
+ ```tsx
202
+ <Button
203
+ label="Get started"
204
+ variant="filled"
205
+ size="lg"
206
+ fullWidth
207
+ onPress={() => router.push('/(main)')}
208
+ $actions={{ onPress: { type: 'mapples:navigate', staticData: { pageUuid: '<uuid from base>' } } }}
209
+ />
210
+ ```
211
+
212
+ (`import { router } from 'expo-router'`.) Rows and cards use their own `onPress`. Walk the golden
213
+ path from the entry screen; every screen reachable, every flow with an exit. Sync; the report's
214
+ `pushedOps` must cover every action you added.
215
+
216
+ ## Phase N — Review
217
+
218
+ Load `reference/lint-checklist.md`. For every screen: re-read the file, check each item, fix.
219
+ Then `npx -y mapples@__CLI_VERSION__ doctor --json` (no `duplicate`/`missing` issues; `drift` is fine before the final
220
+ sync) and a final `npx -y mapples@__CLI_VERSION__ sync --yes --json` with exit 0. Update `design.md` with a `## Status`
221
+ line (screens built, what was cut, the one decision the user may want to change). Then
222
+ `npx -y mapples@__CLI_VERSION__ agent stop --status done`.
223
+
224
+ Reply to the user in 3–5 lines: what was built, where to look in Creator, the one decision to
225
+ revisit. No headings.
226
+
227
+ ## Working style
228
+
229
+ - One screen, one edit — never element by element across many edits (each sync tags ids; many
230
+ partial syncs mean many rewrites).
231
+ - After every sync, re-read before editing. Never keep a stale copy of a file in your head.
232
+ - Prefer fewer screens fully designed over more screens sketched.
233
+ - Ask only when a product decision is genuinely ambiguous; otherwise decide, state it in
234
+ `design.md`, move on.
235
+ - Never emoji. Never lorem ipsum. Never `Text`. Never a hand-written `$sid`.
@@ -0,0 +1,128 @@
1
+ <!-- GENERATED by Mapples __CLI_VERSION__ — re-run npx -y mapples@__CLI_VERSION__ agent install --force to refresh -->
2
+ # Component library — what to reach for
3
+
4
+ Two packages, one canvas. Everything below is a registered canvas type: Creator renders it,
5
+ its style panel edits it, and `npx -y mapples@__CLI_VERSION__ sync` round-trips it. Import primitives from
6
+ `@mapples/ui`, the themed library from `@mapples/components`. Anything else you import is an
7
+ opaque `Custom` node (allowed, but Creator cannot design inside it).
8
+
9
+ ## `@mapples/ui` — primitives
10
+
11
+ | Type | Use | Notes |
12
+ | --- | --- | --- |
13
+ | `Container` | the screen root or a flex: 1 region | full-size column by default |
14
+ | `View` | any column/row | width 100% in a column; content-sized in a row |
15
+ | `SafeAreaView` | root that respects the notch | or paddingTop ≥ 48 on the root |
16
+ | `ScrollView` | vertical scrolling content | spacing in `styled.contentContainerStyle` |
17
+ | `HorizontalScrollView` | a rail of cards | full-bleed; `contentContainerStyle: { gap: 12, paddingHorizontal: 20 }` |
18
+ | `FlatList` | long uniform lists | prefer `List` + `ListItem` for designed rows |
19
+ | `GridTwoColumns` / `GridThreeColumns` / `GridFourColumns` | tile grids | children tile automatically |
20
+ | `GradientBackground` | the one gradient accent per screen | `gradient` prop with literal hex stops |
21
+ | `ImageBackgroundView` | photo with content over it | `source` + `overflow: 'hidden'` + a scrim child |
22
+ | `Typography` | every piece of text | `text` + `variant` (Headline, Subtitle, Body, Caption, Overline, Button, Link, Label, Code) |
23
+ | `Text` | never on a screen | bypasses the type scale |
24
+ | `Image` | a picture | `source` (picsum URL), `contentFit="cover"`, explicit width/height |
25
+ | `Icon` | a glyph from the project icon family | `iconName`; color/size in `styled.styleSvg` |
26
+ | `IconButton` | icon-only tap target | `iconName`, `accessibilityLabel` (required), `badgeCount` |
27
+ | `Pressable` | a custom tappable region | only when no library control fits |
28
+ | `TextInput` | raw input | in forms use `InputField` instead |
29
+ | `Select` | raw select | in forms use `SelectField` instead |
30
+ | `Svg` / `Vector` / `Video` / `QRCode` / `BarCode` | media specials | as needed |
31
+ | `FormView` / `TextField` / `SubmitButton` | form primitives | the library's `InputField`/`Button` are the designed versions |
32
+
33
+ ## `@mapples/components` — the themed library
34
+
35
+ Library types paint themselves from the tokens; change their look through `variant`, `size`
36
+ and `tone` props and the style slots — never rebuild one from Views. Array props (`options`,
37
+ `items`, `columns`) are literal arrays.
38
+
39
+ ### actions
40
+
41
+ | Type | Props to know | Use |
42
+ | --- | --- | --- |
43
+ | `Button` | `label`, `variant` filled\|outlined\|text\|tonal, `size` sm\|md\|lg, `fullWidth`, `leadingIconName`, `tone` | the primary action (filled lg fullWidth), secondary actions (outlined/text) — **imported from `@mapples/ui`**, not `@mapples/components` |
44
+ | `ButtonGroup` | `options` [{label, value}], `value` | a segmented pair of actions |
45
+ | `Fab` | `iconName`, `accessibilityLabel`, `label`, `extended` | one floating primary action |
46
+ | `TextLink` | `label`, `tone`, `underline` | Skip, Forgot password?, Sign in |
47
+ | `BottomActionBar` | `sticky`; children | the sticky bar holding price + CTA on detail/checkout screens |
48
+
49
+ ### input
50
+
51
+ | Type | Props to know | Use |
52
+ | --- | --- | --- |
53
+ | `InputField` | `label`, `placeholder`, `helperText`, `errorText`, `leadingIconName`, `keyboardType`, `autoCapitalize`, `secureTextEntry`, `showPasswordToggle`, `variant` outlined\|filled | every text field in a form |
54
+ | `SelectField` | `label`, `options`, `placeholder`, `value` | dropdowns |
55
+ | `Checkbox` | `label`, `value` | yes/no that lists |
56
+ | `RadioGroup` | `options`, `value` | one exclusive choice |
57
+ | `Switch` | `label`, `value` | a toggle |
58
+ | `Slider` | `min`, `max`, `value`, `showValue` | a range |
59
+ | `NumberStepper` | `min`, `max`, `value` | quantity |
60
+ | `PinInput` | `length` | one-time codes |
61
+ | `SearchBar` | `placeholder`, `value` | search (a filled pill by default) |
62
+ | `ChatComposer` | `placeholder`, `leadingIconName` | the chat input pinned to the bottom |
63
+ | `SegmentedControl` | `options`, `value` | switching a view mode |
64
+ | `Rating` | `value`, `max`, `readOnly` | stars |
65
+ | `ChipGroup` | `options` [{label, value, iconName?}], `value`, `variant` filter\|choice, `scrollable` | filters and tags |
66
+ | `Chip` | `label`, `variant` assist\|filter\|suggestion, `selected` | a single tag (content-sized; inside a row) |
67
+
68
+ ### content
69
+
70
+ | Type | Props to know | Use |
71
+ | --- | --- | --- |
72
+ | `Card` | `variant` elevated\|filled\|outlined; children | any surface that groups content |
73
+ | `MediaCard` | `source`, `title`, `subtitle`, `meta`, `aspectRatio` | a photo-topped tile (rails, grids) |
74
+ | `List` | `variant` plain\|inset\|card, `header`; `ListItem` children | rows — the List draws dividers and the surface |
75
+ | `ListItem` | `title`, `subtitle`, `leading` icon\|avatar\|image\|none, `leadingIconName`, `leadingName` (the name whose initials fill a `leading="avatar"` with no `source`), `source`, `trailing` chevron\|text\|switch\|checkbox\|none, `trailingText`, `tone` | one row |
76
+ | `SectionHeader` | `title`, `actionLabel` | "Popular · See all" |
77
+ | `Divider` | `inset` | a hairline between groups |
78
+ | `Avatar` | `name` or `source`, `size` sm\|md\|lg\|xl, `badgeCount` | a person |
79
+ | `AvatarGroup` | `items` [{name, source}], `max` | several people |
80
+ | `Badge` | `label` or `count`, `variant` text\|dot\|count, `tone` | a status pill or a count |
81
+ | `StatTile` | `label`, `value`, `unit`, `caption`, `trend`, `trendValue`, `iconName`, `variant` | a KPI |
82
+ | `Table` | `columns` [{key, title}], `rows` | tabular data |
83
+ | `Timeline` | `items` [{title, subtitle, time, status}] | a sequence of events |
84
+ | `ImageCarousel` | `items` [{source, caption}] | swipeable photos |
85
+ | `MessageBubble` | `text`, `direction` in\|out, `time`, `status` | a chat message |
86
+ | `Accordion` | `items` [{title, content}] | FAQ / expandable rows |
87
+ | `Skeleton` | `variant` text\|rect\|circle, `width`, `height` | a loading placeholder |
88
+
89
+ ### navigation (in-content)
90
+
91
+ | Type | Props to know | Use |
92
+ | --- | --- | --- |
93
+ | `TopAppBar` | `title`, `showBack`, `actions` [{iconName, value}], `variant` small\|large | an in-content header ONLY when the stack header is hidden |
94
+ | `BottomNavigationBar` | `items` [{label, iconName, value}], `value` | a single-screen demo of a tab shell — real tabs are a navigator |
95
+ | `Tabs` | `items` [{label, value}], `value` | switching panels inside ONE screen |
96
+ | `Breadcrumbs` | `items` [{label, value}], `separator`, `maxItems` | a path |
97
+ | `Steps` | `items` [{label}], `current` | a multi-step progress |
98
+ | `PageControl` | `count`, `value`, `variant` dots\|bars | onboarding page dots |
99
+
100
+ ### feedback
101
+
102
+ | Type | Props to know | Use |
103
+ | --- | --- | --- |
104
+ | `ProgressBar` | `value`, `max`, `showLabel` | a goal or an upload |
105
+ | `ProgressCircle` | `value`, `size`, `showLabel` | a ring |
106
+ | `Spinner` | `size` | loading |
107
+ | `Banner` | `title`, `message`, `tone`, `actionLabel` | an inline notice |
108
+ | `Snackbar` | `message`, `actionLabel`, `visible` | a toast (last in the root, `visible={false}` unless bound) |
109
+ | `EmptyState` | `iconName` or `imageSource`, `title`, `message`, `actionLabel`, `secondaryActionLabel`, `tone` | nothing to show |
110
+
111
+ ### overlays (last in the page root; `visible={false}` unless bound to a variable)
112
+
113
+ | Type | Props to know | Use |
114
+ | --- | --- | --- |
115
+ | `Dialog` | `title`, `message`, `primaryActionLabel`, `secondaryActionLabel`, `tone`, `visible` | a confirmation |
116
+ | `BottomSheet` | `title`, `visible`; children | a picker or a quick detail |
117
+ | `ActionSheet` | `options` [{label, value, iconName?, destructive?}], `visible` | a list of actions |
118
+
119
+ ## Style slots
120
+
121
+ `styled={{ style, styleTypography, styleSvg, styleImage, contentContainerStyle, placeholderTextColor }}` —
122
+ `style` is the element's box; `styleTypography` its text (Button label, ListItem title, StatTile
123
+ value); `styleSvg` its glyph; `contentContainerStyle` the scrolling content. Library components
124
+ expose the same slots; use them for one-off tweaks (a card's `gap`, a rail's padding) and
125
+ props for everything the component already knows how to do.
126
+
127
+ > Prop names above follow the Creator's component digest; when unsure, keep to the ones listed
128
+ > here — an unknown prop is ignored (and reported by the Creator lint as `unknown-prop`).