tsquare 0.3.2 → 0.4.1

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/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  printWireframeText,
7
7
  renderWireframe,
8
8
  wireframePrompt
9
- } from "./chunks/chunk-X46EDSCQ.js";
9
+ } from "./chunks/chunk-QLIHML44.js";
10
10
 
11
11
  // src/cli.ts
12
12
  import { readFile, writeFile } from "node:fs/promises";
@@ -28,28 +28,45 @@ declare function Note({ element, dir, aligned }: Props): React.JSX.Element;
28
28
  declare function Stack({ element, children, dir: parentDir, stretch }: Props): React.JSX.Element;
29
29
  declare function Grid({ element, children }: Props): React.JSX.Element;
30
30
  declare function Card({ element, children, dir, stretch }: Props): React.JSX.Element;
31
+ declare function Accordion({ element, children }: Props): React.JSX.Element;
31
32
  declare function Divider({ element, dir }: Props): React.JSX.Element;
32
33
  declare function Spacer({ element }: Props): React.JSX.Element;
33
34
  declare function Heading({ element }: Props): React.JSX.Element;
34
35
  declare function Text({ element }: Props): React.JSX.Element;
36
+ declare function Bullets({ element }: Props): React.JSX.Element;
35
37
  declare function Image({ element, dir }: Props): React.JSX.Element;
36
38
  declare function Icon({ element, dir, aligned }: Props): React.JSX.Element;
39
+ declare function Chart({ element, dir }: Props): React.JSX.Element;
37
40
  declare function Avatar({ element, dir, aligned }: Props): React.JSX.Element;
38
41
  declare function Badge({ element, dir, aligned, colors }: Props): React.JSX.Element;
39
42
  declare function Button({ element, dir, aligned, colors: c }: Props): React.JSX.Element;
40
- declare function Input({ element, dir }: Props): React.JSX.Element;
43
+ declare function Input({ element, dir, colors }: Props): React.JSX.Element;
41
44
  declare function Select({ element, dir }: Props): React.JSX.Element;
42
45
  declare function Checkbox({ element, dir, aligned, colors }: Props): React.JSX.Element;
43
46
  declare function Radio({ element, dir, aligned, colors }: Props): React.JSX.Element;
44
47
  declare function Toggle({ element, colors }: Props): React.JSX.Element;
48
+ declare function Slider({ element, colors: c }: Props): React.JSX.Element;
49
+ declare function Progress({ element, dir, aligned, colors: c }: Props): React.JSX.Element;
50
+ /** The weekday (0 = Sunday) the month starts on and its length, from text like "October 2026". Generic if it can't tell. */
51
+ export declare function monthGrid(month?: string | null): {
52
+ start: number;
53
+ days: number;
54
+ };
55
+ declare function Calendar({ element, dir, aligned, colors: c }: Props): React.JSX.Element;
45
56
  declare function NavBar({ element }: Props): React.JSX.Element;
46
57
  declare function TabBar({ element, colors: c }: Props): React.JSX.Element;
47
58
  declare function Tabs({ element, colors: c }: Props): React.JSX.Element;
59
+ /** The page numbers to show: all of them up to 7, otherwise the ends and the current page's neighbours. */
60
+ export declare function pageList(pages: number, current: number): (number | "…")[];
61
+ declare function Pagination({ element, dir, aligned, colors: c }: Props): React.JSX.Element;
48
62
  declare function List({ element, children, dir, stretch }: Props): React.JSX.Element;
49
63
  declare function ListItem({ element, colors }: Props): React.JSX.Element;
50
64
  declare function Table({ element }: Props): React.JSX.Element;
51
65
  declare function Modal({ element, children }: Props): React.JSX.Element;
52
66
  declare function Drawer({ element, children }: Props): React.JSX.Element;
67
+ declare function Toast({ element, aboveTabBar }: Props & {
68
+ aboveTabBar?: boolean;
69
+ }): React.JSX.Element;
53
70
  export declare const registry: {
54
71
  Board: typeof Board;
55
72
  Screen: typeof Screen;
@@ -57,11 +74,14 @@ export declare const registry: {
57
74
  Stack: typeof Stack;
58
75
  Grid: typeof Grid;
59
76
  Card: typeof Card;
77
+ Accordion: typeof Accordion;
60
78
  Divider: typeof Divider;
61
79
  Spacer: typeof Spacer;
62
80
  Heading: typeof Heading;
63
81
  Text: typeof Text;
82
+ Bullets: typeof Bullets;
64
83
  Image: typeof Image;
84
+ Chart: typeof Chart;
65
85
  Icon: typeof Icon;
66
86
  Avatar: typeof Avatar;
67
87
  Badge: typeof Badge;
@@ -71,13 +91,18 @@ export declare const registry: {
71
91
  Radio: typeof Radio;
72
92
  Toggle: typeof Toggle;
73
93
  Select: typeof Select;
94
+ Slider: typeof Slider;
95
+ Progress: typeof Progress;
96
+ Calendar: typeof Calendar;
74
97
  NavBar: typeof NavBar;
75
98
  TabBar: typeof TabBar;
76
99
  Tabs: typeof Tabs;
100
+ Pagination: typeof Pagination;
77
101
  List: typeof List;
78
102
  ListItem: typeof ListItem;
79
103
  Table: typeof Table;
80
104
  Modal: typeof Modal;
81
105
  Drawer: typeof Drawer;
106
+ Toast: typeof Toast;
82
107
  };
83
108
  export {};
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  upgradeSpec,
21
21
  upgradeWireframe,
22
22
  wireframePrompt
23
- } from "./chunks/chunk-X46EDSCQ.js";
23
+ } from "./chunks/chunk-QLIHML44.js";
24
24
 
25
25
  // src/share.ts
26
26
  import { deflateRawSync, inflateRawSync } from "node:zlib";
@@ -11,7 +11,7 @@ import {
11
11
  renderWireframePng,
12
12
  renderWireframeSvg,
13
13
  wireframePrompt
14
- } from "../chunks/chunk-X46EDSCQ.js";
14
+ } from "../chunks/chunk-QLIHML44.js";
15
15
 
16
16
  // src/playground/index.ts
17
17
  import { createServer } from "node:http";
@@ -38,7 +38,8 @@ function describe(name, schema) {
38
38
  return { name, kind: "number", description };
39
39
  case "array": {
40
40
  const el = unwrap(s.def.element);
41
- const hasIcon = el?.def?.type === "object" && "icon" in el.shape;
41
+ const objects = el?.def?.type === "union" ? el.def.options.map(unwrap) : [el];
42
+ const hasIcon = objects.some((x) => x?.def?.type === "object" && "icon" in x.shape);
42
43
  return { name, kind: "list", icon: iconish || hasIcon, description };
43
44
  }
44
45
  case "object":
@@ -72,11 +73,11 @@ function languageData() {
72
73
  // src/playground/reference.ts
73
74
  var GROUPS = [
74
75
  { name: "Canvas", components: ["Board", "Screen", "Note"] },
75
- { name: "Layout", components: ["Stack", "Grid", "Card", "Divider", "Spacer"] },
76
- { name: "Content", components: ["Heading", "Text", "Image", "Icon", "Avatar", "Badge"] },
77
- { name: "Controls", components: ["Button", "Input", "Checkbox", "Radio", "Toggle", "Select"] },
78
- { name: "Navigation & data", components: ["NavBar", "TabBar", "Tabs", "List", "ListItem", "Table"] },
79
- { name: "Overlays", components: ["Modal", "Drawer"] }
76
+ { name: "Layout", components: ["Stack", "Grid", "Card", "Accordion", "Divider", "Spacer"] },
77
+ { name: "Content", components: ["Heading", "Text", "Bullets", "Image", "Chart", "Icon", "Avatar", "Badge"] },
78
+ { name: "Controls", components: ["Button", "Input", "Checkbox", "Radio", "Toggle", "Select", "Slider", "Progress", "Calendar"] },
79
+ { name: "Navigation & data", components: ["NavBar", "TabBar", "Tabs", "Pagination", "List", "ListItem", "Table"] },
80
+ { name: "Overlays", components: ["Modal", "Drawer", "Toast"] }
80
81
  ];
81
82
  var EXAMPLES = {
82
83
  Board: `board row "Checkout flow" gap=48 accent=blue
@@ -148,6 +149,14 @@ var EXAMPLES = {
148
149
  text lines=3
149
150
  card "filled" variant=filled grow
150
151
  text lines=3`,
152
+ Accordion: `board
153
+ screen custom width=380 height=330 gap=0
154
+ heading "FAQ" level=3
155
+ accordion "How long does shipping take?" open
156
+ text "Orders arrive in 3\u20135 business days." muted
157
+ accordion "Can I return an item?"
158
+ accordion "Do you ship internationally?"
159
+ accordion "How do I track my order?"`,
151
160
  Divider: `board
152
161
  screen custom width=360 height=150
153
162
  text "Above"
@@ -171,20 +180,43 @@ var EXAMPLES = {
171
180
  heading "Level 3" level=3
172
181
  heading "Centered" level=3 align=center`,
173
182
  Text: `board
174
- screen custom width=360 height=300
183
+ screen custom width=360 height=370
175
184
  text "Body text, default size"
176
185
  text lg "Large"
177
186
  text sm "Small and muted" muted
178
187
  text "Bold" bold
179
188
  text "Placeholder lines when lines is set and there's no text:" sm muted
180
- text lines=3`,
189
+ text lines=3
190
+ text "Breadcrumbs are small muted text:" sm muted
191
+ text "Home / Settings / Profile" sm muted`,
192
+ Bullets: `board
193
+ screen custom width=420 height=600
194
+ text "Bullets" bold
195
+ bullets items=[Fast setup, No credit card, Cancel anytime]
196
+ text "numbered" bold
197
+ bullets numbered items=[Create an account, Verify your email, Invite your team]
198
+ text "icon= any Lucide icon" bold
199
+ bullets icon=check items=[Unlimited boards, Share links, Version history]
200
+ text "One item can change its icon, or be muted" bold
201
+ bullets icon=check items=[Unlimited boards, Share links, {label="SSO" icon=x muted}]`,
181
202
  Image: `board
182
- screen custom width=480 height=210
203
+ screen custom width=480 height=400
183
204
  stack row gap=12
184
205
  image "label" height=120 width=160
185
206
  image height=120 width=120 rounded
186
207
  image height=120
187
- text "In a row, an image without a width is square." sm muted`,
208
+ text "In a row, an image without a width is square." sm muted
209
+ image map height=150 "Map"`,
210
+ Chart: `board
211
+ screen custom width=640 height=430
212
+ stack row gap=16
213
+ chart line "line (default)"
214
+ chart bar "bar"
215
+ stack row gap=16
216
+ chart area "area" height=150
217
+ chart pie "pie" height=150
218
+ chart donut "donut" height=150
219
+ text "Charts are placeholders: they show the kind of chart, not data." sm muted`,
188
220
  Icon: `board
189
221
  screen custom width=360 height=120
190
222
  stack row gap=16 align=center
@@ -228,7 +260,7 @@ var EXAMPLES = {
228
260
  button primary "Full width" fullWidth
229
261
  text "With a board accent, primary buttons fill with it and ghost buttons use it for text." sm muted`,
230
262
  Input: `board
231
- screen custom width=420 height=540
263
+ screen custom width=420 height=760
232
264
  input "Email" placeholder="you@example.com" helper="We never share it"
233
265
  input "Username" value="dana moore" error helper="No spaces allowed"
234
266
  input password "Password" value=secret
@@ -236,7 +268,9 @@ var EXAMPLES = {
236
268
  input "Message" multiline=3
237
269
  stack row gap=8
238
270
  input placeholder="grow fills the row" grow
239
- button primary "Send"`,
271
+ button primary "Send"
272
+ input "Check-in" type=date value="Oct 14, 2026"
273
+ input "Verification code" type=code value="4821" helper="Sent to (555) 010-2400"`,
240
274
  Checkbox: `board
241
275
  screen custom width=300 height=100
242
276
  checkbox "Checked" checked
@@ -262,6 +296,24 @@ var EXAMPLES = {
262
296
  stack row gap=12
263
297
  input "City" placeholder="Monterrey" grow
264
298
  select "State" value="Nuevo Le\xF3n" grow`,
299
+ Slider: `board
300
+ screen custom width=380 height=200
301
+ slider "Volume" value=30
302
+ slider "Price range" range=[20, 80]`,
303
+ Progress: `board
304
+ screen custom width=420 height=330
305
+ progress "Uploading" value=40
306
+ progress value=75
307
+ stack row gap=24
308
+ progress circle "Storage" value=72
309
+ progress circle value=15
310
+ progress "Setup" steps=4 step=2`,
311
+ Calendar: `board
312
+ screen custom width=660 height=400
313
+ stack row gap=24 align=start
314
+ calendar "October 2026" selected=14
315
+ calendar "October 2026" range=[12, 18] marked=[3, 9, 22]
316
+ text "range selects several days; marked adds a dot, e.g. for events." sm muted`,
265
317
  NavBar: `board
266
318
  screen custom width=380 height=240 padding=0 gap=0
267
319
  navbar "leading=menu" leading=menu actions=[search, bell]
@@ -277,6 +329,10 @@ var EXAMPLES = {
277
329
  screen custom width=400 height=150
278
330
  tabs items=[Overview, Activity, Settings] active=0
279
331
  text lines=2`,
332
+ Pagination: `board
333
+ screen custom width=420 height=160
334
+ pagination pages=5 current=2
335
+ pagination pages=12 current=6`,
280
336
  List: `board
281
337
  screen custom width=380 height=420
282
338
  list
@@ -326,7 +382,19 @@ var EXAMPLES = {
326
382
  drawer bottom "Share" size=280
327
383
  list dividers=false
328
384
  listitem "Copy link" leadingIcon=link
329
- listitem "Message" leadingIcon=message-circle`
385
+ listitem "Message" leadingIcon=message-circle`,
386
+ Toast: `board
387
+ screen phone "Bottom, above a tab bar"
388
+ heading "Inbox" level=2
389
+ list
390
+ listitem "Ana Torres" subtitle="Lunch on Friday?" leading=avatar
391
+ listitem "Ben Cho" subtitle="Draft attached" leading=avatar
392
+ tabbar items=[{label=Inbox icon=inbox}, {label=Settings icon=settings}]
393
+ toast "Message sent" action="Undo" icon=check
394
+ screen phone "Top"
395
+ heading "Profile" level=2
396
+ image height=160
397
+ toast "Changes saved" position=top`
330
398
  };
331
399
 
332
400
  // src/playground/index.ts
package/dist/prompt.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare function componentDocs(): {
13
13
  props: PropDoc[];
14
14
  }[];
15
15
  export declare function componentReference(): string;
16
- export declare const RULES = "## Rules\n1. The top element is a Board. The Board's children are Screens, plus optional Notes beside them.\n2. Each Screen is one view of the product. Use several Screens to show several views or states.\n3. A Screen lays out its children top to bottom. Use Stack (direction row or column) and Grid to arrange content.\n4. NavBar is pinned to the top of its Screen and TabBar to the bottom.\n5. Modal and Drawer are overlays. They must be direct children of a Screen.\n6. This is a low-fidelity wireframe. Prefer placeholders (Image boxes, Text with lines) over invented copy unless the copy matters.\n7. Only use the components and props listed below. All props are optional unless marked required.\n8. Wireframes are grayscale. The only UI colors: Board accent (one color for primary buttons, checked controls, toggles, active tabs and ghost buttons), Badge tone (success, warning, danger) and Input error. Only add an accent if the request asks for color or a brand.";
16
+ export declare const RULES = "## Rules\n1. The top element is a Board. The Board's children are Screens, plus optional Notes beside them.\n2. Each Screen is one view of the product. Use several Screens to show several views or states.\n3. A Screen lays out its children top to bottom. Use Stack (direction row or column) and Grid to arrange content.\n4. NavBar is pinned to the top of its Screen and TabBar to the bottom.\n5. Modal, Drawer and Toast are overlays. They must be direct children of a Screen.\n6. This is a low-fidelity wireframe. Prefer placeholders (Image boxes, Text with lines) over invented copy unless the copy matters.\n7. Only use the components and props listed below. All props are optional unless marked required.\n8. Wireframes are grayscale. The only UI colors: Board accent (one color for primary buttons, checked controls, toggles, active tabs and ghost buttons), Badge tone (success, warning, danger) and Input error. Only add an accent if the request asks for color or a brand.";
17
17
  export declare const TEXT_FORMAT = "## Output format: wireframe text\nOne element per line. Indent children two spaces under their parent. The first line is the board.\n\nA line is the component name in lowercase, followed by arguments separated by spaces:\n- \"a quoted string\" sets the component's main text prop (marked \"main text\" below)\n- a bare word that is one of the component's option values sets that option: phone, desktop, primary, ghost, row, sm, left, bottom, password, \u2026\n- a bare prop name sets that component's yes/no prop to true, only on components that have it (see each component's props below): checked (checkbox, radio), fullWidth (button), muted (text), grow (stack, card, input, list). `off` and `unchecked` set on/checked to false\n- key=value sets any prop. Values: \"string\", number, true/false, bare word, [list, of, values], {key=value key=value}\n\nComments: a line that starts with # is a comment. A comment must be on its own line, never after an element on the same line. Anywhere else, # is ordinary text: [#1001, #1002], \"Order #12345\", accent=#1a73e8.\n\nLists: items are separated by commas, and an item can contain spaces without quotes: [All notes, Pinned, Shared]. To put a comma inside an item, quote the item: [\"$1,200\", \"Smith, J\"]. Inside quotes, write \\\" for a quote character. Numbers in a list of text are fine: [2023, 2024].\n\nIf a bare word could mean more than one prop, write it as key=value.";
18
18
  export declare const EXAMPLE_REQUEST = "Two phone screens for a recipe app: a browse screen with search, category tabs, a grid of recipe cards and a tab bar; and a recipe detail screen with its options sheet open.";
19
19
  /** The system prompt for writing wireframe text. */
@@ -1,5 +1,5 @@
1
1
  board "Analytics" accent=blue
2
- screen desktop "Dashboard" padding=0 height=640
2
+ screen desktop "Dashboard" padding=0 height=760
3
3
  stack row grow
4
4
  stack width=220 border=right fill padding=16 gap=6
5
5
  text "Acme" bold
@@ -24,4 +24,9 @@ board "Analytics" accent=blue
24
24
  heading "932" level=2
25
25
  card "Refunds"
26
26
  heading "12" level=2
27
+ stack row gap=12
28
+ card "Revenue" grow
29
+ chart area height=170
30
+ card "Traffic sources" width=300
31
+ chart donut height=170
27
32
  table columns=[Order, Customer, Status, Total] data=[["#1042", Ana Torres, Paid, "$120"], ["#1041", Ben Cho, Pending, "$80"], ["#1040", Priya Nair, Paid, "$45"]]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsquare",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "description": "Wireframes in plain text: easy for LLMs to write, fast to render as SVG or PNG.",
5
5
  "keywords": [
6
6
  "wireframe",
@@ -47,7 +47,7 @@ If a bare word could mean more than one prop, write it as key=value.
47
47
  2. Each Screen is one view of the product. Use several Screens to show several views or states.
48
48
  3. A Screen lays out its children top to bottom. Use Stack (direction row or column) and Grid to arrange content.
49
49
  4. NavBar is pinned to the top of its Screen and TabBar to the bottom.
50
- 5. Modal and Drawer are overlays. They must be direct children of a Screen.
50
+ 5. Modal, Drawer and Toast are overlays. They must be direct children of a Screen.
51
51
  6. This is a low-fidelity wireframe. Prefer placeholders (Image boxes, Text with lines) over invented copy unless the copy matters.
52
52
  7. Only use the components and props listed below. All props are optional unless marked required.
53
53
  8. Wireframes are grayscale. The only UI colors: Board accent (one color for primary buttons, checked controls, toggles, active tabs and ghost buttons), Badge tone (success, warning, danger) and Input error. Only add an accent if the request asks for color or a brand.
@@ -9,7 +9,7 @@ Root canvas (artboard). Holds Screens side by side, plus optional Notes. Must be
9
9
  - columns: number
10
10
  - gap: number
11
11
  - padding: number
12
- - accent: string — The one UI color: primary buttons, solid badges, checked controls, toggles, active tabs, ghost buttons. blue, indigo, violet, pink, red, orange, green, teal, or a hex color like #1a73e8. Omit for grayscale.
12
+ - accent: string — The one UI color: primary buttons, solid badges, checked controls, toggles, sliders, progress, selected days and pages, active tabs, ghost buttons. blue, indigo, violet, pink, red, orange, green, teal, or a hex color like #1a73e8. Omit for grayscale.
13
13
 
14
14
  ### Screen
15
15
  One view of the product in a device frame. Children stack vertically.
@@ -55,6 +55,11 @@ Bordered container with optional title. Children stack vertically.
55
55
  - grow: boolean
56
56
  - width: number | string — Fixed width, e.g. 320. Default fills the space.
57
57
 
58
+ ### Accordion
59
+ Collapsible section: a title row with a chevron, children below when open. Stack several for an FAQ.
60
+ - title: string (main text)
61
+ - open: boolean — Show the children. Default closed: only the title row
62
+
58
63
  ### Divider
59
64
  Thin separator line.
60
65
  - vertical: boolean
@@ -78,12 +83,26 @@ Body text, or placeholder lines when `lines` is set and `text` is not.
78
83
  - bold: boolean
79
84
  - align: "left" | "center" | "right"
80
85
 
86
+ ### Bullets
87
+ Bulleted, numbered or icon list of short lines.
88
+ - items (required): array of string | { label: string, icon: string, muted: boolean } — Text, or {label icon muted} to change one line, e.g. {label=SSO icon=x muted}
89
+ - numbered: boolean — 1. 2. 3. instead of dots
90
+ - icon: string — A Lucide icon instead of dots, e.g. check for a feature list
91
+
81
92
  ### Image
82
- Image placeholder: a box with an X through it.
93
+ Image placeholder: a box with an X through it, or a map.
83
94
  - height: number
84
95
  - width: number | string — Default fills the container width
85
96
  - label: string (main text)
86
97
  - rounded: boolean
98
+ - kind: "photo" | "map" — map draws roads and a pin instead of the X
99
+
100
+ ### Chart
101
+ Chart placeholder: a generic line, bar, area, pie or donut shape, no data.
102
+ - kind: "line" | "bar" | "area" | "pie" | "donut" — Default line
103
+ - title: string (main text)
104
+ - height: number — Default 180
105
+ - width: number | string — Default fills the container width
87
106
 
88
107
  ### Icon
89
108
  Line icon from Lucide.
@@ -115,7 +134,8 @@ Text field with optional label. Set multiline for a textarea.
115
134
  - label: string (main text)
116
135
  - placeholder: string
117
136
  - value: string
118
- - type: "text" | "password" | "search" | "email"
137
+ - type: "text" | "password" | "search" | "email" | "date" | "code" — date shows a calendar icon; code draws one box per digit
138
+ - digits: number — Boxes for type=code, default 6
119
139
  - multiline: number — Number of rows; 2 or more makes a textarea
120
140
  - helper: string
121
141
  - error: boolean — Validation error: red border and red helper text
@@ -145,6 +165,27 @@ Dropdown field (closed state).
145
165
  - grow: boolean — Fill the remaining space in a row
146
166
  - width: number | string — Fixed width, e.g. 320. Default fills the space.
147
167
 
168
+ ### Slider
169
+ Slider with one handle, or two with `range`.
170
+ - label: string (main text)
171
+ - value: number — Handle position: 0 to 100, or any amount (the track scales to fit)
172
+ - range: [number, number] — Two handles instead, e.g. [20, 80] or [50, 400]
173
+
174
+ ### Progress
175
+ Progress bar, ring (circle), or stepper (steps).
176
+ - label: string (main text)
177
+ - value: number — Percent done
178
+ - shape: "bar" | "circle" — Default bar; circle is a ring with the percent inside
179
+ - steps: number — Draw a stepper with this many steps instead
180
+ - step: number — The current step, with steps
181
+
182
+ ### Calendar
183
+ Month calendar.
184
+ - month: string (main text) — Month and year, e.g. "October 2026"; the days match that month
185
+ - selected: number
186
+ - range: [number, number] — Selected days, e.g. [12, 18]
187
+ - marked: array of number — Days with a dot, e.g. events
188
+
148
189
  ### NavBar
149
190
  Top app bar. Place first in a Screen.
150
191
  - title: string (main text)
@@ -162,6 +203,11 @@ In-page tabs with an underline on the active one.
162
203
  - items (required): array of string
163
204
  - active: number
164
205
 
206
+ ### Pagination
207
+ Page numbers with previous and next.
208
+ - pages (required): number
209
+ - current: number — Default 1
210
+
165
211
  ### List
166
212
  Vertical list of ListItems.
167
213
  - dividers: boolean
@@ -196,3 +242,10 @@ Panel sliding in from an edge: side nav (left), filters/details (right), or bott
196
242
  - size: number — Width for left/right, height for bottom
197
243
  - scrim: boolean — Dim the screen behind. Default true.
198
244
  - handle: boolean — Grab handle on bottom sheets. Default true for bottom.
245
+
246
+ ### Toast
247
+ Short message over the screen, e.g. after saving. Must be a direct child of a Screen, listed last.
248
+ - text: string (main text)
249
+ - action: string — A text button, e.g. "Undo"
250
+ - icon: string — Lucide icon name in kebab-case, e.g. menu, search, arrow-left, settings, bell, user
251
+ - position: "bottom" | "top" — Default bottom, above a TabBar