@close-by/clay 0.2.24 → 0.2.25
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/docs/README.md +2 -0
- package/docs/api.md +4 -2
- package/docs/compatibility.md +79 -0
- package/docs/elements.md +7 -1
- package/docs/examples.md +13 -17
- package/docs/getting-started.md +2 -1
- package/docs/llms.txt +4 -0
- package/docs/mobile.md +111 -0
- package/docs/ops-patterns.md +1 -1
- package/package.json +5 -5
package/docs/README.md
CHANGED
|
@@ -11,6 +11,7 @@ For coding agents: the repo-root [llms.txt](../llms.txt) is a short map of these
|
|
|
11
11
|
| Doc | Description |
|
|
12
12
|
|-----|-------------|
|
|
13
13
|
| [Getting started](./getting-started.md) | Install, `clay` CLI, create a page |
|
|
14
|
+
| [Mobile and installable apps](./mobile.md) | Phone tab bar (`mobileNav`), installable app (`pwa`, `--pwa`) |
|
|
14
15
|
| [Boot: CLI vs library](./boot.md) | Production `ui.run` path, `clientDir`, `_run.ts`, reload stubs |
|
|
15
16
|
| [Tailwind](./tailwind.md) | Zero-config utilities from page modules; optional tokens |
|
|
16
17
|
| [Sample app](./tutorial.md) | Step-by-step tasks list, then two pages + shell |
|
|
@@ -24,6 +25,7 @@ For coding agents: the repo-root [llms.txt](../llms.txt) is a short map of these
|
|
|
24
25
|
| [Elements](./elements.md) | All element types and props |
|
|
25
26
|
| [Maps](./maps.md) | `ui.map`: MapLibre markers, routes, arcs, GeoJSON, clusters; palette theming and in-place updates |
|
|
26
27
|
| [WebSocket protocol](./protocol.md) | Client ↔ server message formats |
|
|
28
|
+
| [Compatibility](./compatibility.md) | Public API promise, aliases, and compatibility checks |
|
|
27
29
|
| [Architecture](./architecture.md) | Packages, data flow, and ownership |
|
|
28
30
|
| [Examples](./examples.md) | Demo apps and patterns |
|
|
29
31
|
| [Reactive `let`](./reactive-let.md) | NiceGUI-style `let` transform (opt-in `--reactive-let`) |
|
package/docs/api.md
CHANGED
|
@@ -93,6 +93,7 @@ ui.run({
|
|
|
93
93
|
| `css` | `string \| string[]` | | Extra CSS file path(s) served after the client bundle (absolute or cwd-relative). Override theme tokens without rebuilding the client. |
|
|
94
94
|
| `sound` | `boolean` | | Play short synthesized interface sounds by default (`false`). See [Sound](#sound). |
|
|
95
95
|
| `app` | `AppProps` | | Global dashboard shell; client keeps chrome sticky across navigate |
|
|
96
|
+
| `pwa` | `boolean \| ClayPwaConfig` | | Installable app: web manifest, icons, and a service worker that caches the app shell. See [Mobile and installable apps](./mobile.md#installable-app-pwa) |
|
|
96
97
|
| `authSecret` | `string` | | Enables signed auth cookies (`POST`/`DELETE /auth/session`), `ui.establishAuthSession` / `ui.clearAuthSession`, and default `resolveUserId` from the cookie |
|
|
97
98
|
| `authCookieMaxAgeSec` | `number` | `43200` (12h) | Auth cookie Max-Age |
|
|
98
99
|
| `sessionIdleMs` | `number` | | Optional: clear auth + redirect after this idle time |
|
|
@@ -1822,7 +1823,7 @@ onClick: async () => {
|
|
|
1822
1823
|
| `ui.redirect(url)` | `void` | Full-page navigation in the current tab (`location.assign`) — for sign-in routes / external pages; use `ui.navigate` for app pages |
|
|
1823
1824
|
| `ui.theme.set(mode)` | `void` | Push `light` \| `dark` \| `system` to this client |
|
|
1824
1825
|
| `ui.theme.get()` | `ThemeMode \| null` | Last value set on this session |
|
|
1825
|
-
| `ui.theme.palette(name)` | `void` | Switch colour palette for this client (`kiln`, `cobalt`, `ocean`, `forest`, `orchid`, `citrus`, `graphite`, `neon`, `sky`, `navy`, `indigo`, `denim`, `midnight`, or a custom one); remembered across reloads |
|
|
1826
|
+
| `ui.theme.palette(name)` | `void` | Switch colour palette for this client (`kiln`, `cobalt`, `ocean`, `forest`, `orchid`, `citrus`, `graphite`, `chalk`, `brutal`, `terminal`, `editorial`, `bubble`, `soothe`, `nebula`, `studio`, `iris`, `ledger`, `contrast`, `dim`, `neon`, `sky`, `navy`, `indigo`, `denim`, `midnight`, or a custom one); remembered across reloads |
|
|
1826
1827
|
| `ui.theme.getPalette()` | `ThemePalette \| null` | Last palette set, else the one the client reported on connect |
|
|
1827
1828
|
| `ui.theme.palettes` | `readonly string[]` | Built-in palette names |
|
|
1828
1829
|
| `ui.sound.set(on)` | `void` | Turn automatic interface sounds on/off for this client; remembered across reloads. See [Sound](#sound) |
|
|
@@ -1960,6 +1961,7 @@ Sidebar layout for multi-page apps. Prefer `ui.run({ app })` so every page inher
|
|
|
1960
1961
|
| `user` | `AppUser` | Optional user menu (`name`, `email`, `avatar?`) |
|
|
1961
1962
|
| `variant` | `'sidebar' \| 'inset'` | Shell layout variant |
|
|
1962
1963
|
| `collapsible` | `'offcanvas' \| 'icon' \| 'none'` | Sidebar collapse behavior |
|
|
1964
|
+
| `mobileNav` | `'tabs' \| 'menu'` | Phone navigation. Default `'tabs'` (bottom tab bar); `'menu'` keeps only the sidebar sheet. See [Mobile](./mobile.md#keep-only-the-menu) |
|
|
1963
1965
|
| `className` | `string` | Extra classes on the shell |
|
|
1964
1966
|
|
|
1965
1967
|
`AppNavItem`: `{ label, href, icon?, description?, items? }` — `icon` is a Lucide kebab-case name (full set; e.g. `home`, `gauge`, `sparkles`). Nested `items` render as collapsible sub-links in the sidebar.
|
|
@@ -2114,7 +2116,7 @@ form.name = 'Ada'; // persisted
|
|
|
2114
2116
|
ui.draft.clear('formDemo'); // drop storage key; reset the object yourself if needed
|
|
2115
2117
|
```
|
|
2116
2118
|
|
|
2117
|
-
See
|
|
2119
|
+
See Forms (`/examples/forms`).
|
|
2118
2120
|
|
|
2119
2121
|
### `ui.auto(fn)`
|
|
2120
2122
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Compatibility
|
|
2
|
+
|
|
3
|
+
An app written for a Clay release keeps working on later releases unchanged.
|
|
4
|
+
If an app breaks after a Clay update, that is a bug in Clay unless the release
|
|
5
|
+
notes list the change under **Breaking**.
|
|
6
|
+
|
|
7
|
+
## What this covers
|
|
8
|
+
|
|
9
|
+
The promise covers the public surface apps use:
|
|
10
|
+
|
|
11
|
+
- `ui.*` functions and namespaces, including `ui.ai`, `ui.storage`, and `ui.theme`.
|
|
12
|
+
- Element methods such as `setText`, `classes`, and `bindValue`.
|
|
13
|
+
- Package exports, including exports moved to another module.
|
|
14
|
+
- Factory option names and element prop names.
|
|
15
|
+
- Event names and their payloads.
|
|
16
|
+
- Element wire types and protocol operations.
|
|
17
|
+
- CLI flags, defaults, and behavior.
|
|
18
|
+
|
|
19
|
+
The client and server ship together, but the wire format still matters.
|
|
20
|
+
Apps use `ui.runJavaScript` and custom clients, and old browser tabs reconnect
|
|
21
|
+
to new servers. Updating the server must account for those callers too.
|
|
22
|
+
|
|
23
|
+
## Rules for changes
|
|
24
|
+
|
|
25
|
+
1. What a release shipped stays available in later releases, unless its removal
|
|
26
|
+
is explicitly listed under Breaking in the release notes.
|
|
27
|
+
2. A rename keeps the old name as an alias of the same implementation.
|
|
28
|
+
Mark the old name with JSDoc `@deprecated Use newName.` so editors can guide
|
|
29
|
+
callers to the replacement. Moving an export keeps it in the old module too.
|
|
30
|
+
3. Types only widen: options gain optional members, unions gain cases, and
|
|
31
|
+
functions gain optional trailing parameters or overloads. Apps should handle
|
|
32
|
+
values they do not know, for example with a default branch in a switch.
|
|
33
|
+
4. Behavior does not change silently. Defaults, units, payload shapes, and
|
|
34
|
+
callback order are part of the contract even when the names stay the same.
|
|
35
|
+
|
|
36
|
+
For example, a renamed helper keeps a direct alias:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
export function newName(text: string) {
|
|
40
|
+
return ui.label(text);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** @deprecated Use newName. */
|
|
44
|
+
export const oldName = newName;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## How we check it
|
|
48
|
+
|
|
49
|
+
[compat/surface.json](../compat/surface.json) records the public names.
|
|
50
|
+
[packages/ui/src/compat.test.ts](../packages/ui/src/compat.test.ts) compares that
|
|
51
|
+
record with the current source as part of `bun run test`.
|
|
52
|
+
Missing names fail the test; new names also fail until the record is updated.
|
|
53
|
+
|
|
54
|
+
The record contains:
|
|
55
|
+
|
|
56
|
+
- `ui.<path>`: functions and plain-object namespaces, up to three levels deep.
|
|
57
|
+
Session-created values and getters requiring a session are excluded.
|
|
58
|
+
- `export:<package-name>:<name>`: runtime exports from Clay, core, components,
|
|
59
|
+
server, auth, and file persistence. Type-only exports are absent at runtime.
|
|
60
|
+
- `element.<method>`: methods on the core Element prototype chain.
|
|
61
|
+
- `class.<ExportName>.<method>`: own methods of other Element classes exported
|
|
62
|
+
by `@close-by/clay`.
|
|
63
|
+
- `wire.<type>`: element types handled by the client renderer.
|
|
64
|
+
- `op.server.<op>`, `op.client.<op>`, and `op.patch.<op>`: protocol operations.
|
|
65
|
+
- `cli.<flag>`: CLI flags, including short aliases.
|
|
66
|
+
|
|
67
|
+
After adding public API, run `bun scripts/compat-surface.ts --write` and commit
|
|
68
|
+
`compat/surface.json` with the implementation. Review its diff before committing.
|
|
69
|
+
For a rename, restore the old alias before updating the record.
|
|
70
|
+
For an intentional removal, list it under Breaking in the release notes and
|
|
71
|
+
regenerate the record. Run `bun test packages/ui` to check it.
|
|
72
|
+
Run `bun scripts/compat-surface.ts` for counts without changing the record.
|
|
73
|
+
|
|
74
|
+
This check records names, not full signatures or behavior. Option and prop names,
|
|
75
|
+
event payload shapes, defaults, units, and callback order are not checked
|
|
76
|
+
automatically yet. Reviewers check these, along with type compatibility.
|
|
77
|
+
Native and network adapter packages are outside the mechanical record.
|
|
78
|
+
|
|
79
|
+
Practice adapted from [Native Shell's compatibility policy](https://nsh.dev/docs/compatibility).
|
package/docs/elements.md
CHANGED
|
@@ -201,6 +201,12 @@ Server patches still reconcile when `props.value` changes (e.g. `draft.text = ''
|
|
|
201
201
|
|
|
202
202
|
Field `error` is **server-owned** (via initial props, `.setError`, or `ui.validate`). It is not optimistic — the client shows `props.error` after `updateProps` patches.
|
|
203
203
|
|
|
204
|
+
## On phones
|
|
205
|
+
|
|
206
|
+
On phone-sized touch screens (max-width 767px and coarse pointer), `select` uses the native picker
|
|
207
|
+
and `date` uses the native date picker. `dropdownmenu` and `combobox` open bottom sheets.
|
|
208
|
+
Props and events stay the same. Desktop rendering is unchanged.
|
|
209
|
+
|
|
204
210
|
## Styling
|
|
205
211
|
|
|
206
212
|
Prefer Tailwind utility classes via `.classes(...)`:
|
|
@@ -213,4 +219,4 @@ Layout `gap` uses a small numeric scale mapped to `gap-0` … `gap-8` in the cli
|
|
|
213
219
|
|
|
214
220
|
The client ships the "kiln" theme — warm neutrals, a fired-clay primary, vivid chart colours, light + dark (ShadCN-style CSS variables in `packages/client/src/index.css`, Plus Jakarta Sans bundled). Override tokens at runtime with `ui.run({ css: './globals.css' })`; Clay extras include `--clay-brand-from` / `--clay-brand-to` and the `clay-brand-gradient`, `clay-brand-text`, `clay-ambient` classes.
|
|
215
221
|
|
|
216
|
-
|
|
222
|
+
Twenty-four more palettes ship alongside kiln — `cobalt`, `ocean`, `forest`, `orchid`, `citrus`, `graphite`, `chalk`, `brutal`, `terminal`, `editorial`, `bubble`, `soothe`, `nebula`, `studio`, `iris`, `ledger`, `contrast`, `dim`, `neon`, plus the blues `sky`, `navy`, `indigo`, `denim`, `midnight` (each light + dark, in `packages/client/src/palettes.css`). Pick the app default with `ui.run({ palette: 'ocean' })` or switch per session with `ui.theme.palette('neon')`. `chalk`, `brutal`, `terminal`, `editorial`, `bubble`, `soothe`, `nebula`, `studio`, `iris`, `ledger`, `contrast`, and `dim` also change font, radius and shadows. `contrast` is the accessibility option, with high-contrast colours and explicit focus indicators. Custom palettes: define `:root[data-palette="mine"] { … }` and `:root.dark[data-palette="mine"] { … }` in your `css` file, then `ui.theme.palette('mine')`.
|
package/docs/examples.md
CHANGED
|
@@ -7,7 +7,7 @@ After `bun run build:client && bun run demo` (or `bun run demo:cli`), open http:
|
|
|
7
7
|
|
|
8
8
|
## Sidebar groups
|
|
9
9
|
|
|
10
|
-
Each page sets `group` / `groupIcon` in its `pageMeta`, so the sidebar and the home page's catalog share one structure: **Start here** (themes, fill layout, counter, todo, kitchen sink) → **Reactivity** → **Data** → **Maps** (gallery, delivery tracker, store locator, globe, uptime monitor) → **Forms & controls** → **
|
|
10
|
+
Each page sets `group` / `groupIcon` in its `pageMeta`, so the sidebar and the home page's catalog share one structure: **Start here** (themes, fill layout, counter, todo, kitchen sink) → **Reactivity** → **Data** → **Maps** (map gallery, delivery tracker, store locator, globe, uptime monitor) → **Forms & controls** → **Components** → **Apps** (including List, Kanban, Gantt, Flow, and Ops console) → **Account**. Order within a group is `pageMeta.order`.
|
|
11
11
|
|
|
12
12
|
## Catalog
|
|
13
13
|
|
|
@@ -16,34 +16,30 @@ Each page sets `group` / `groupIcon` in its `pageMeta`, so the sidebar and the h
|
|
|
16
16
|
| `/` | `Home.ts` | Landing page: hero, live counter + source side by side (`ui.codeBlock`), feature grid, catalog grouped via `ui.navFromPages()` (same as sidebar) |
|
|
17
17
|
| `/examples/counter` | `Counter.ts` | `setText`, `refreshable`, button variants |
|
|
18
18
|
| `/examples/todo` | `Todo.ts` | `reactive`, `bindValue`, list `refreshable`, filters |
|
|
19
|
+
| `/examples/reactive-let-orders` | `ReactiveLetOrders.ts` | Order filters and master–detail views with `ui.state` / `ui.auto` |
|
|
20
|
+
| `/examples/reactive-let-orders-let` | `ReactiveLetOrdersLet.ts` | The same order workflow with reactive `let` variables and the Clay CLI transform |
|
|
19
21
|
| `/examples/chat` | `Chat.ts` | `ui.storage.app` (persisted messages + ephemeral presence), async `get`/`set` |
|
|
20
22
|
| `/examples/ai` | `AiDemo.ts` | `ui.ai.*` gallery — chat, prompt bar, loader/thinking, agent cards, diff/insights/fine-tune (static props; no model runtime) |
|
|
21
23
|
| `/examples/upload` | `FileUpload.ts` | `ui.upload` button + dropzone (progress/abort/size), `ui.storage.tab` / `user`, `ui.download`, `ui.clipboard` |
|
|
22
24
|
| `/examples/dashboard` | `Dashboard.ts` | `stat`, `areaChart`, full-chrome `dataTable` (views, editors, detail drawer) |
|
|
23
25
|
| `/examples/datatable` | `DataTableDemo.ts` | Multi-sort (Shift+click / badges), footer aggregates + a11y hints, column pin, remote filter/sort + pagination; density/zebra, editors (Enter/Esc + focus restore), resize, virtualization (≥40, coexists with reorder via windowed drop targets); facets, bulk, collapse/expand, loading/empty; `ui.table` sugar |
|
|
24
|
-
| `/examples/
|
|
25
|
-
| `/examples/
|
|
26
|
-
| `/examples/
|
|
27
|
-
| `/examples/reui-batch-7` | `ReuiBatch7Demo.ts` | ReUI batch 7: `inputGroup`, `toggle`, `descriptionList`, `staticTable`, `aspectRatio`, `itemList`, `checkboxGroup` |
|
|
28
|
-
| `/examples/charts` | `ChartDemo.ts` | `ui.chart.*`, `ui.sparkline`, composed/scatter charts |
|
|
26
|
+
| `/examples/ops-console` | `OpsConsoleDemo.ts` | Order triage: `filterBar` → `feedList` → `descriptionList` / `staticTable` |
|
|
27
|
+
| `/examples/charts` | `ChartDemo.ts` | `ui.chart.*`, `ui.sparkline`, composed/scatter charts, `stat` + sparkline |
|
|
28
|
+
| `/examples/live-table` | `LiveTableStress.ts` | High-frequency table updates, configurable row count, and live price changes |
|
|
29
29
|
| `/examples/live-charts` | `LiveCharts.ts` | Live charts: `appendData` sliding windows, `setData` tweens, `upsertData` buckets, live gauge and sparklines |
|
|
30
|
-
| `/examples/slider-demo` | `SliderDemo.ts` | Slider, checkbox, select + bindings |
|
|
31
30
|
| `/examples/themes` | `ThemesDemo.ts` | Palette gallery: `ui.theme.palette`, light/dark, component preview |
|
|
32
31
|
| `/examples/layout` | `LayoutDemo.ts` | Fill layout: `fillViewport`, `grow`, `scroll`, `ui.grid` |
|
|
33
|
-
| `/examples/feedback` | `FeedbackDemo.ts` |
|
|
34
|
-
| `/examples/
|
|
32
|
+
| `/examples/feedback` | `FeedbackDemo.ts` | Feedback & status: alert, spinner, progress, `runJavaScript` / scroll, live timer clock, notice, empty, timeline |
|
|
33
|
+
| `/examples/forms` | `FormDemo.ts` | Forms: validation, `ui.draft`, slider, checkbox, select, rating, color picker, tags, field, numberField, phoneInput, nativeSelect, inputGroup, toggle, checkboxGroup, dateRange, stepper |
|
|
35
34
|
| `/examples/auth` | `Auth.ts` (+ login/admin/change-password) | Signed cookie session, hashed passwords, login lockout, role-gated admin + audit log |
|
|
36
|
-
| `/examples/
|
|
37
|
-
| `/examples/
|
|
38
|
-
| `/examples/
|
|
39
|
-
| `/examples/controls` | `ControlsDemo.ts` | Menubar (submenu/checkbox/radio), command dialog + inline, carousel, resizable, scroll-area, `ui.state` / `ui.auto` |
|
|
40
|
-
| `/examples/controls-extra` | `ControlsExtra.ts` | `ui.codeBlock` (Shiki), `ui.tree` |
|
|
41
|
-
| `/examples/media-extra` | `MediaExtra.ts` | `ui.relativeTime`, `ui.qrCode`, `ui.imageZoom`, `ui.imageCrop` |
|
|
35
|
+
| `/examples/overlays` | `OverlaysDemo.ts` | Breadcrumb, dropdown/context menu, hover card, popover, dialog/sheet/drawer, `dialogStack` multi-step stacked modal |
|
|
36
|
+
| `/examples/navigation` | `NavigationDemo.ts` | Navigation & layout: menubar, command, carousel, resizable, scrollArea, keybind, viewportEnter, navigationMenu, buttonGroup, pagination, aspectRatio |
|
|
37
|
+
| `/examples/content` | `ContentDemo.ts` | Content & media: markdown, html, codeBlock, descriptionList, staticTable, itemList, tree, image, imageZoom, imageCrop, qrCode, iframe, relativeTime, eventCalendar |
|
|
42
38
|
| `/examples/editor` | `EditorDemo.ts` | `ui.editor` HTML + Markdown side-by-side, bindValue |
|
|
43
39
|
| `/examples/kanban` | `KanbanDemo.ts` | `ui.kanban` swimlanes, card detail drawer, element-owned `cardMove`/`cardSelect`, reset via APIs |
|
|
44
|
-
| `/examples/list` | `ListDemo.ts` | `ui.list`
|
|
40
|
+
| `/examples/list` | `ListDemo.ts` | Apps: `ui.list` groups, drag to reorder, reset via `setGroups` |
|
|
45
41
|
| `/examples/gantt` | `GanttDemo.ts` | `ui.gantt` owned rows/dates/markers/deps, cross-row drag, header double-click markers, `itemMove` / `markerAdd` settle |
|
|
46
|
-
| `/examples/flow` | `FlowDemo.ts` | Four `ui.flow` demos: ETL with in-node controls + labeled edges + dagre auto-layout, multi-handle approval branches, fan-in/out + `addNode` dynamic stages, group/`parentId` nesting
|
|
42
|
+
| `/examples/flow` | `FlowDemo.ts` | Four `ui.flow` demos: ETL with in-node controls + labeled edges + dagre auto-layout, multi-handle approval branches, fan-in/out + `addNode` dynamic stages, group/`parentId` nesting with interactive edges and positions |
|
|
47
43
|
| `/examples/data-clients` | `DataClientsDemo.ts` | DuckDB / Kibana / ClickHouse integration story (mock-friendly) |
|
|
48
44
|
| `/examples/maps` | `MapsGallery.ts` | `ui.map` gallery: markers and popups, routes, arcs, choropleth, clusters, compact analytics map |
|
|
49
45
|
| `/examples/delivery-tracker` | `DeliveryTracker.ts` | `ui.map` route progress and courier marker: `updateRoute` / `upsertMarker` on a timer, `fill` layout |
|
package/docs/getting-started.md
CHANGED
|
@@ -149,6 +149,7 @@ bun run clay ./pages --app --title "My App"
|
|
|
149
149
|
| `-p, --port` | Port (default `3000`) |
|
|
150
150
|
| `-t, --title` | HTML / shell title |
|
|
151
151
|
| `--app` | Dashboard shell + nav from discovered pages |
|
|
152
|
+
| `--pwa` | Installable app: manifest + service worker ([Mobile and installable apps](./mobile.md)) |
|
|
152
153
|
| `--no-open` | Do not open the browser |
|
|
153
154
|
| `--reload` | Restart on file changes (`bun --watch`); opens the browser once; prints `↻ clay: reloading…` and re-imports pages (clears `require.cache`) |
|
|
154
155
|
| `--reactive-let` | Enable compile-time reactive `let` Bun loader (**off** by default; still needs `// @clay-reactive` or `"use reactive";` in source) |
|
|
@@ -181,7 +182,7 @@ Open:
|
|
|
181
182
|
- http://localhost:4000 — home with links to examples
|
|
182
183
|
- http://localhost:4000/examples/counter
|
|
183
184
|
- http://localhost:4000/examples/todo
|
|
184
|
-
- http://localhost:4000/examples/
|
|
185
|
+
- http://localhost:4000/examples/forms
|
|
185
186
|
- http://localhost:4000/examples/auth
|
|
186
187
|
|
|
187
188
|
| Script | What it does |
|
package/docs/llms.txt
CHANGED
|
@@ -11,6 +11,8 @@ Notes for agents:
|
|
|
11
11
|
- Update existing nodes with `setText` / `setValue` / bindings. Prefer `ui.state` + `ui.auto` (+ `ui.timer`) for async/live UIs; `ui.refreshable` for simple one-shot rebuilds. Shared or persisted state: `ui.storage` (`tab` / `user` / `app`).
|
|
12
12
|
- Never use `window` / `navigator` in page code — use `ui.clipboard`, `ui.setUrlHash`, `ui.getUrlSearch` / `ui.updateUrlSearch`, `ui.openExternal`.
|
|
13
13
|
- Runtime is Bun. In this repo: `bun run build:client`, then `bun run demo` (http://localhost:4000) or `bun run clay hello.ts`.
|
|
14
|
+
- Installable app is opt-in: `ui.run({ pwa: true })` or `clay ./pages --app --pwa` adds a manifest and an app-shell service worker (see docs/mobile.md).
|
|
15
|
+
- On phones the `app` nav becomes a bottom tab bar; `app: { mobileNav: 'menu' }` keeps only the sidebar sheet.
|
|
14
16
|
- `ui.ai.*` is visual primitives only — no model or streaming runtime.
|
|
15
17
|
- Agent skill (Cursor / compatible tools): `@close-by/clay/SKILL.md` — copy to `.cursor/skills/clay/SKILL.md` or read from `node_modules` when installed.
|
|
16
18
|
|
|
@@ -20,6 +22,7 @@ Notes for agents:
|
|
|
20
22
|
- [Getting started](docs/getting-started.md): Install, `clay` CLI, first app, publishing
|
|
21
23
|
- [Boot](docs/boot.md): CLI vs library, `clientDir`, `_run.ts`, reload stubs
|
|
22
24
|
- [Tailwind](docs/tailwind.md): Scanned utilities + `ui.run({ css })`
|
|
25
|
+
- [Mobile and installable apps](docs/mobile.md): Phone tab bar (`mobileNav`), installable PWA (`ui.run({ pwa })`, `--pwa`)
|
|
23
26
|
- [Sample app](docs/tutorial.md): Step-by-step tasks list, then two pages + shell
|
|
24
27
|
- [Concepts](docs/concepts.md): Sessions, element tree, patches, refreshable, bindings, storage
|
|
25
28
|
- [Browser APIs](docs/browser-apis.md): `ui.clipboard` / hash / `openExternal` — no `window` in page code
|
|
@@ -37,6 +40,7 @@ Notes for agents:
|
|
|
37
40
|
|
|
38
41
|
- [Architecture](docs/architecture.md): Packages and data flow
|
|
39
42
|
- [WebSocket protocol](docs/protocol.md): Message formats
|
|
43
|
+
- [Compatibility](docs/compatibility.md): Public API promise, aliases, and compatibility checks
|
|
40
44
|
- [AI UI](docs/ai.md): `ui.ai.*` visual primitives
|
|
41
45
|
- [Reactive let](docs/reactive-let.md): `ui.state` / `ui.auto` and the compile-time `let` transform
|
|
42
46
|
- [DuckDB](docs/duckdb.md): `@close-by/clay-duckdb`
|
package/docs/mobile.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Mobile and installable apps
|
|
2
|
+
|
|
3
|
+
Apps built with the `app` shell work on phones without changes. You can also make an app installable to the home screen, which is opt-in.
|
|
4
|
+
|
|
5
|
+
## Phone layout
|
|
6
|
+
|
|
7
|
+
On phone-sized screens (narrow, with a touch pointer) the shell changes on its own:
|
|
8
|
+
|
|
9
|
+
- **Bottom tab bar.** Up to 4 top-level `nav` items become tabs. When there are more items, or `navSecondary`, `documents` or `user` is set, a **More** tab opens the sidebar sheet. A tab is highlighted when its page, or one of its child pages, is active.
|
|
10
|
+
- **Bottom sheets.** Dialogs open as bottom sheets.
|
|
11
|
+
- **Safe areas.** Content clears the iPhone notch and home indicator.
|
|
12
|
+
- **Toasts and the connection chip** sit above the tab bar.
|
|
13
|
+
- **16px form text.** iOS doesn't zoom when a field is focused.
|
|
14
|
+
|
|
15
|
+
`select`, `combobox`, `date` and `dropdownMenu` also use native pickers or bottom drawers on phones. See [Elements](./elements.md#on-phones).
|
|
16
|
+
|
|
17
|
+
### Keep only the menu
|
|
18
|
+
|
|
19
|
+
Set `mobileNav: 'menu'` to keep the hamburger sheet and skip the tab bar:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
ui.run({
|
|
23
|
+
app: {
|
|
24
|
+
title: 'My App',
|
|
25
|
+
nav: ui.navFromPages(),
|
|
26
|
+
mobileNav: 'menu', // default: 'tabs'
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`mobileNav` is also a [`ui.app()`](./api.md#uiappprops-fn) prop.
|
|
32
|
+
|
|
33
|
+
## Installable app (PWA)
|
|
34
|
+
|
|
35
|
+
Opt in with the CLI flag or the `pwa` option:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
clay ./pages --app --pwa
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
ui.run({ pwa: true }); // defaults
|
|
43
|
+
|
|
44
|
+
ui.run({
|
|
45
|
+
title: 'My App',
|
|
46
|
+
pwa: {
|
|
47
|
+
shortName: 'App',
|
|
48
|
+
description: 'Track my work',
|
|
49
|
+
themeColor: '#1d4ed8',
|
|
50
|
+
backgroundColor: '#ffffff',
|
|
51
|
+
display: 'standalone',
|
|
52
|
+
startUrl: '/',
|
|
53
|
+
icon: './assets/icon-512.png',
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`ClayPwaConfig` is exported from `@close-by/clay-server`.
|
|
59
|
+
|
|
60
|
+
| Option | Default | Description |
|
|
61
|
+
|--------|---------|-------------|
|
|
62
|
+
| `name` | `title` | App name in the install prompt and splash screen |
|
|
63
|
+
| `shortName` | `name` | Label under the home-screen icon |
|
|
64
|
+
| `description` | | Manifest description |
|
|
65
|
+
| `themeColor` | Clay light/dark background | Browser and OS chrome color |
|
|
66
|
+
| `backgroundColor` | Clay light background | Splash screen background |
|
|
67
|
+
| `display` | `'standalone'` | `'standalone' \| 'fullscreen' \| 'minimal-ui' \| 'browser'` |
|
|
68
|
+
| `startUrl` | `'/'` | URL opened from the home screen |
|
|
69
|
+
| `icon` | Clay's bundled icons | Square PNG (512px+ recommended) or SVG, relative to the working directory |
|
|
70
|
+
|
|
71
|
+
It adds:
|
|
72
|
+
|
|
73
|
+
- `/manifest.webmanifest`, with name, icons, colors and display mode.
|
|
74
|
+
- `theme-color` and Apple meta tags, plus `viewport-fit=cover` so content can use the full screen.
|
|
75
|
+
- `/sw.js`, a service worker that caches the app shell (HTML, JS, CSS and icons). It uses network-first, so online users always get the latest build.
|
|
76
|
+
|
|
77
|
+
### Icons
|
|
78
|
+
|
|
79
|
+
- Without `icon`, Clay's bundled icons are used.
|
|
80
|
+
- `icon` must be a `.png` or `.svg` file. A missing or unsupported file throws at startup.
|
|
81
|
+
- iOS home-screen icons need a PNG. SVG gets no apple-touch-icon, so use a PNG if the app will be installed on iOS.
|
|
82
|
+
|
|
83
|
+
### Offline
|
|
84
|
+
|
|
85
|
+
The installed app still opens without a connection and shows Clay's reconnecting state. There is no offline mode for pages, since every screen runs on the server.
|
|
86
|
+
|
|
87
|
+
### HTTPS
|
|
88
|
+
|
|
89
|
+
Service workers require HTTPS. `localhost` is exempt, so you can test locally. Serve the app over HTTPS before asking people to install it.
|
|
90
|
+
|
|
91
|
+
### Install
|
|
92
|
+
|
|
93
|
+
- **Android and desktop Chrome:** an install prompt or menu item appears when the app is installable.
|
|
94
|
+
- **iOS Safari:** Share → Add to Home Screen.
|
|
95
|
+
|
|
96
|
+
### Turn it off
|
|
97
|
+
|
|
98
|
+
Remove `pwa` (or the `--pwa` flag). Clay then serves a `/sw.js` that clears the app cache and unregisters itself. Browsers that installed the app earlier clean up the next time they load it.
|
|
99
|
+
|
|
100
|
+
### Override the worker or manifest
|
|
101
|
+
|
|
102
|
+
`/sw.js` and `/manifest.webmanifest` can be replaced with `routes`, which match by exact path before pages:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
ui.run({
|
|
106
|
+
pwa: true,
|
|
107
|
+
routes: {
|
|
108
|
+
'/sw.js': () => new Response(mySource, { headers: { 'Content-Type': 'text/javascript' } }),
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
```
|
package/docs/ops-patterns.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Dense internal tools (live feeds, master–detail, logs/traces) push Clay past card dashboards. Prefer Phase 1 reactivity ([Concepts](./concepts.md#canonical-recipe-state--auto--timer)) and the helpers below.
|
|
4
4
|
|
|
5
|
-
**Runnable
|
|
5
|
+
**Runnable example:** `/examples/ops-console` (`OpsConsoleDemo.ts`) — one Orders-shaped surface using `filterBar`, `inputGroup`, `feedList`/`feedRow`, `descriptionList`, `staticTable`, `pagination`, `empty`, `notice`, and `toggle`. Use that page to find API friction before adding more wire types.
|
|
6
6
|
|
|
7
7
|
## Status chips
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@close-by/clay",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"description": "NiceGUI-like ui.* facade for Clay apps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@close-by/clay-compiler": "0.2.
|
|
41
|
-
"@close-by/clay-core": "0.2.
|
|
42
|
-
"@close-by/clay-components": "0.2.
|
|
43
|
-
"@close-by/clay-server": "0.2.
|
|
40
|
+
"@close-by/clay-compiler": "0.2.25",
|
|
41
|
+
"@close-by/clay-core": "0.2.25",
|
|
42
|
+
"@close-by/clay-components": "0.2.25",
|
|
43
|
+
"@close-by/clay-server": "0.2.25",
|
|
44
44
|
"@tailwindcss/cli": "^4.3.3",
|
|
45
45
|
"tailwindcss": "^4.3.3"
|
|
46
46
|
}
|