@jskit-ai/agent-docs 0.1.277 → 0.1.279
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/guide/agent/app-setup/authentication.md +13 -2
- package/guide/agent/app-setup/material-3-migration.md +17 -3
- package/guide/agent/framework/material-3.md +77 -22
- package/package.json +1 -1
- package/patterns/minimal-foundation/example/package.json +2 -2
- package/patterns/shell-foundation/example/package.json +3 -3
- package/reference/autogen/PATTERN_INDEX.md +16 -16
- package/reference/autogen/packages/auth-provider-local-core.md +1 -1
- package/reference/autogen/packages/http-web.md +0 -2
- package/reference/autogen/packages/shell-web.md +11 -4
- package/reference/autogen/packages/users-web.md +4 -0
- package/reference/autogen/tooling/jskit-catalog.md +3 -1
- package/skills/jskit/references/material-3.md +77 -22
- package/skills/jskit/references/pattern-index.md +16 -16
- package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +2 -2
- package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +3 -3
- package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +1 -1
- package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
- package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
- package/skills/jskit/references/patterns/users/account-settings/PATTERN.md +6 -1
- package/skills/jskit/references/patterns/users/account-settings/example/src/pages/account.vue +22 -0
|
@@ -154,8 +154,9 @@ like the recovery sender below; with it, `APP_PUBLIC_URL` is required and the
|
|
|
154
154
|
link is never returned or logged. In development without one, the link is in
|
|
155
155
|
the registration's answer (`confirmationUrl`) and the log, and the sign-in page
|
|
156
156
|
shows it with a button that confirms it. In production (`NODE_ENV=production`)
|
|
157
|
-
without one, the server refuses to start, naming
|
|
158
|
-
sender,
|
|
157
|
+
without one, while anyone may register, the server refuses to start, naming
|
|
158
|
+
the ways out: install a sender, set `AUTH_LOCAL_EMAIL_CONFIRMATION=false`, or
|
|
159
|
+
set `AUTH_LOCAL_SELF_REGISTRATION=false`. For direct library
|
|
159
160
|
composition, pass the sender as `confirmationSender` to
|
|
160
161
|
`createLocalAuthService()`, with `emailConfirmationSender: true` in
|
|
161
162
|
`resolveLocalAuthConfig()`; without one, pass
|
|
@@ -164,6 +165,16 @@ composition, pass the sender as `confirmationSender` to
|
|
|
164
165
|
| Env | Default | Meaning |
|
|
165
166
|
| --- | --- | --- |
|
|
166
167
|
| `AUTH_LOCAL_EMAIL_CONFIRMATION` | on | `false` registers and signs in at once, without confirming the email. |
|
|
168
|
+
| `AUTH_LOCAL_SELF_REGISTRATION` | on | `false`: only invited accounts and the first account register; anyone else is refused with 403 `auth.local.register.closed`. |
|
|
169
|
+
|
|
170
|
+
Confirmation guards self-registration. An app whose accounts are only invited,
|
|
171
|
+
or created through the first account, sets `AUTH_LOCAL_SELF_REGISTRATION=false`
|
|
172
|
+
and needs no confirmation sender: an invitation counts when a feature's
|
|
173
|
+
invitation context resolver (such as workspace invites) resolves it for that
|
|
174
|
+
email, and the first account is admitted by its setup code. In production
|
|
175
|
+
without a sender, those registrations sign in at once; with one, they confirm
|
|
176
|
+
as usual. An app that refused the register routes itself, with a 404 hook,
|
|
177
|
+
can drop the hook for this setting.
|
|
167
178
|
|
|
168
179
|
Accounts that exist already are confirmed: only registrations made after the
|
|
169
180
|
upgrade wait. Waiting registrations are kept in the file store
|
|
@@ -71,7 +71,11 @@ Delete, rather than port:
|
|
|
71
71
|
page needs no frame at all;
|
|
72
72
|
- `!important`, Sass variable overrides and component size or radius tweaks.
|
|
73
73
|
`material.css` sets 40dp buttons with a 48dp touch target, 12dp cards, 28dp
|
|
74
|
-
dialogs and sheets, 8dp chips and 16dp FABs, and an app's own props still win
|
|
74
|
+
dialogs and sheets, 8dp chips and 16dp FABs, and an app's own props still win;
|
|
75
|
+
- every `height` and `min-height` on a button, as a prop, a style or CSS. A
|
|
76
|
+
button that should look smaller becomes `size="small"` or `size="x-small"`:
|
|
77
|
+
it keeps the 48dp touch target. A long label ends in an ellipsis instead of
|
|
78
|
+
spilling out; give a label that can run long its `title`.
|
|
75
79
|
|
|
76
80
|
Use colour roles (`color="secondary-container"`, `bg-color="surface-container-high"`,
|
|
77
81
|
the `on-surface-variant` class) instead of colours.
|
|
@@ -110,8 +114,13 @@ definePage({ meta: { jskit: { title: "Edit book", parent: "/books/:bookId" } } }
|
|
|
110
114
|
```
|
|
111
115
|
|
|
112
116
|
`parent` is a path on the page's own surface, or `{ surface, path }` for
|
|
113
|
-
another one
|
|
114
|
-
|
|
117
|
+
another one; its `:param` segments take the current route's values. A main
|
|
118
|
+
navigation destination declares no parent and shows no arrow. A page with a
|
|
119
|
+
parent renders in its surface's shell layout (`ShellLayout` around
|
|
120
|
+
`<RouterView />`), which draws the bar with its title, Up and actions:
|
|
121
|
+
`jskit check` reports `nav/missing-shell-layout` until it does. The account
|
|
122
|
+
settings page needs `src/pages/account.vue` from the users/account-settings
|
|
123
|
+
pattern. The shell's Up arrow returns to the page the person came from, or else
|
|
115
124
|
to the parent, so:
|
|
116
125
|
|
|
117
126
|
- delete "Back to X" buttons, `router.back()` and `history.back()` calls;
|
|
@@ -203,6 +212,11 @@ opens the drawer over the page. A modal drawer opens over the app bar, as
|
|
|
203
212
|
Material 3 draws it, so a browser test that clicked the menu control again to
|
|
204
213
|
close it taps the scrim or presses Escape instead.
|
|
205
214
|
|
|
215
|
+
Each main-navigation placement is literal data, one `addPlacement({ ... })`
|
|
216
|
+
per destination with plain string `surface` and suffixes; one a helper builds is
|
|
217
|
+
a `nav/placement-data` finding, and no page is judged for a missing parent until
|
|
218
|
+
it is declared literally.
|
|
219
|
+
|
|
206
220
|
## 9. Check it
|
|
207
221
|
|
|
208
222
|
Look at every screen at 390, 768 and 1280 pixels wide, in light and dark. A
|
|
@@ -87,7 +87,10 @@ Exactly this, and nothing more:
|
|
|
87
87
|
2. **Each top-level destination is a main-navigation item** (a `kind: "link"`
|
|
88
88
|
placement with `target: "shell.primary-nav"` or `"shell.secondary-nav"`) and
|
|
89
89
|
declares no parent; nor do its tabs. A shell page with no parent is
|
|
90
|
-
top-level: no arrow, a fresh trail.
|
|
90
|
+
top-level: no arrow, a fresh trail. Placements are literal declarative data,
|
|
91
|
+
one `addPlacement({ ... })` per destination with plain string `surface`,
|
|
92
|
+
`scopedSuffix` and `unscopedSuffix`, never built by a helper, a spread or a
|
|
93
|
+
template, so a reader and `jskit check` can map every destination.
|
|
91
94
|
3. **Every in-app link and navigation goes through JSKIT navigation:**
|
|
92
95
|
`:to="paths.page('/suppliers')"` and `router.push(paths.page(...))` with
|
|
93
96
|
`usePaths()`, the CRUD runtime's `resolveViewUrl()`, `resolveEditUrl()` and
|
|
@@ -103,7 +106,10 @@ Exactly this, and nothing more:
|
|
|
103
106
|
5. **A full page load goes through the shell too:** `reloadAppPage(path)`
|
|
104
107
|
(after sign-in or a user switch, to rebuild client state) and
|
|
105
108
|
`leaveApp(url)` (an external site in the same tab, such as a payment page),
|
|
106
|
-
from `@jskit-ai/shell-web/client/navigation/documentNavigation`.
|
|
109
|
+
from `@jskit-ai/shell-web/client/navigation/documentNavigation`. `leaveApp`
|
|
110
|
+
opens the site with a push, so Back returns to the page; a hand-off page
|
|
111
|
+
that only forwards (to an OAuth consent screen) uses
|
|
112
|
+
`leaveApp(url, { replace: true })`, so Back from the site doesn't rerun it.
|
|
107
113
|
|
|
108
114
|
### Forbidden in app code
|
|
109
115
|
|
|
@@ -112,9 +118,11 @@ Exactly this, and nothing more:
|
|
|
112
118
|
| `nav/history` | `history.back()`, `history.go()`, `history.pushState()`/`replaceState()`, `router.back()`, `router.go()` |
|
|
113
119
|
| `nav/window-location` | `window.location` assignments, `.href =`, `location.assign()`, `location.replace()` |
|
|
114
120
|
| `nav/raw-link` | a hand-built in-app path in `to`, `href`, `router.push()`, `router.replace()` or a `to:`/`href:` object key outside a placement |
|
|
115
|
-
| `nav/back-control` | any back control but the shell's Up
|
|
121
|
+
| `nav/back-control` | any back control but the shell's Up that navigates the app: "Back to X", "← Suppliers", back arrows and navigating chevrons, breadcrumbs, a custom app-bar back button, a back component, a `goBack()`-style handler |
|
|
116
122
|
| `nav/missing-parent` | an inner page of a shell surface without a declared parent |
|
|
117
123
|
| `nav/top-level-parent` | a main-navigation destination that declares a parent |
|
|
124
|
+
| `nav/placement-data` | a main-navigation placement that isn't literal data (no page is judged for a missing parent until it is) |
|
|
125
|
+
| `nav/missing-shell-layout` | a page that declares a parent with no shell layout rendering it, so its title, Up and actions never show |
|
|
118
126
|
| `nav/allow` | any `m3-check: allow nav/...` comment: nothing excuses a navigation rule |
|
|
119
127
|
|
|
120
128
|
### Each rule, right and wrong
|
|
@@ -145,9 +153,15 @@ Exactly this, and nothing more:
|
|
|
145
153
|
`finish(recordUrl)`; the record shows, and Up goes where the record's Up went
|
|
146
154
|
before. Wrong: `router.push(recordUrl)` after Save, so Up or Back reopens the
|
|
147
155
|
form.
|
|
148
|
-
- **Steps inside a page are named actions
|
|
149
|
-
|
|
150
|
-
(
|
|
156
|
+
- **Steps and drill-downs inside a page are named actions.** A wizard step or
|
|
157
|
+
a panel the page opens in place is not a page, so it has no Up. Right:
|
|
158
|
+
"Previous step", or the destination's name ("Dashboard"), with no back
|
|
159
|
+
arrow. Wrong: "Back" or a back arrow. `nav/back-control` flags only controls
|
|
160
|
+
that navigate the app: a link into it, or a handler that reaches the router,
|
|
161
|
+
JSKIT paths, `up()`, `finish()` or the browser's history or location. Prose
|
|
162
|
+
("back from version 2"), a variable named `back` and an embedded frame's own
|
|
163
|
+
Back and Forward (`frame.contentWindow.history.back()`, as in a preview
|
|
164
|
+
browser) are not back controls.
|
|
151
165
|
|
|
152
166
|
## Foundation
|
|
153
167
|
|
|
@@ -181,10 +195,16 @@ JSKIT ships these exact sizes; an app never re-implements or overrides them,
|
|
|
181
195
|
and needs no Sass and no `!important` (Vuetify 4 keeps its CSS in cascade
|
|
182
196
|
layers):
|
|
183
197
|
|
|
184
|
-
- 40dp buttons with a 48dp touch target, icon buttons included;
|
|
185
|
-
-
|
|
198
|
+
- 40dp buttons with a 48dp touch target, icon buttons included; a smaller
|
|
199
|
+
button is `size="small"` or `size="x-small"`, which keeps its smaller look
|
|
200
|
+
and the 48dp target;
|
|
201
|
+
- one-line button labels: a label longer than its button ends in an ellipsis.
|
|
202
|
+
Keep labels short, and give a button whose label can run long, such as a
|
|
203
|
+
name, the full label as its `title`;
|
|
204
|
+
- 12dp cards: elevated (the default) at level 1, flat and tonal at level 0;
|
|
186
205
|
- 28dp dialogs and bottom-sheet top corners, square full-screen dialogs;
|
|
187
|
-
- 8dp chips and
|
|
206
|
+
- 8dp chips, and FABs of 56dp (small 40dp, large 96dp; extended 56dp tall)
|
|
207
|
+
with 16dp corners;
|
|
188
208
|
- emphasized easing, with reduced motion honoured.
|
|
189
209
|
|
|
190
210
|
So never set `height` or `min-height` on a button, or a radius on a card,
|
|
@@ -196,12 +216,22 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
196
216
|
`useShellPageTitle(title)` (`@jskit-ai/shell-web/client/composables/useShellPageTitle`)
|
|
197
217
|
for a runtime title such as the record's name. The shell renders it as the
|
|
198
218
|
app bar's only `h1`; pages add no `h1`, page header, title block or
|
|
199
|
-
standalone heading. A section inside a page uses a title role.
|
|
219
|
+
standalone heading. A section inside a page uses a title role. A page with
|
|
220
|
+
no top app bar (a hero front page, an intro, an invite or hand-off page)
|
|
221
|
+
has its own one `h1`.
|
|
200
222
|
- **Up** sits in the bar on every inner page (see Navigation and Up). On phones
|
|
201
223
|
it replaces the menu icon.
|
|
202
|
-
- **A layout
|
|
203
|
-
|
|
204
|
-
|
|
224
|
+
- **A layout that draws its own top app bar** (a workspace bar with the
|
|
225
|
+
app's own controls, instead of `ShellLayout`) builds it from `ShellLayout`'s
|
|
226
|
+
own pieces, from `@jskit-ai/shell-web/client`. It calls `useShellAppBar()`
|
|
227
|
+
once, so its pages enter the trail and their `ShellPageActions` show in its
|
|
228
|
+
bar, and renders `ShellUpButton` first, then `ShellPageTitle` (the page's one
|
|
229
|
+
`h1`: `useShellPageTitle()`, else the route's `jskit.title`, else its `title`
|
|
230
|
+
prop) and `ShellPageActionsTarget`. A title that is also a switcher, such as a
|
|
231
|
+
project menu, goes in `ShellPageTitle`'s default slot (given `{ title }`) as
|
|
232
|
+
the menu's activator, so it stays the one `h1`. `jskit check` counts it as a shell
|
|
233
|
+
layout, so its inner pages need parents; an Up the app draws itself is a
|
|
234
|
+
`nav/back-control` finding.
|
|
205
235
|
- **Actions:** a screen's actions go in the bar inside `ShellPageActions`
|
|
206
236
|
(`@jskit-ai/shell-web/client/components/ShellPageActions`), each a
|
|
207
237
|
`ShellPageAction` with `icon`, `label` (also its accessible name and compact
|
|
@@ -209,7 +239,9 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
209
239
|
On compact widths every action shows only its icon except the single
|
|
210
240
|
`primary` one.
|
|
211
241
|
- **Window size classes:** compact under 600 (navigation bar), medium 600–839
|
|
212
|
-
(navigation rail), expanded 840–1199 and large from 1200 (drawer).
|
|
242
|
+
(navigation rail), expanded 840–1199 and large from 1200 (drawer). A surface
|
|
243
|
+
with no navigation destinations, such as an account surface, draws no
|
|
244
|
+
navigation bar, rail or drawer; its pages keep the app bar. Read them
|
|
213
245
|
from `useShellWindowSizeClass()`
|
|
214
246
|
(`@jskit-ai/shell-web/client/composables/useShellWindowSizeClass`), never from
|
|
215
247
|
copied breakpoint numbers.
|
|
@@ -309,8 +341,8 @@ and so every app's verify, fail on them too:
|
|
|
309
341
|
|
|
310
342
|
| Rule | Finds |
|
|
311
343
|
|---|---|
|
|
312
|
-
| `m3/duplicate-h1` | a second `h1`, or an in-page `h1`
|
|
313
|
-
| `m3/raw-hex` | a hex colour outside `src/theme/` |
|
|
344
|
+
| `m3/duplicate-h1` | a second `h1`, or an in-page `h1` under the shell's page title |
|
|
345
|
+
| `m3/raw-hex` | a hex colour outside `src/theme/` (`palettes.js` holds content colours) |
|
|
314
346
|
| `m3/dark-scheme` | no dark scheme, or the theme pinned to light |
|
|
315
347
|
| `m3/outlined-card` | `variant="outlined"` or `border` on a card or sheet |
|
|
316
348
|
| `m3/mdi-icon` | `mdi-*` icon strings and `@mdi/js` imports |
|
|
@@ -328,16 +360,39 @@ Take the approved route first; none needs an exception:
|
|
|
328
360
|
|
|
329
361
|
- **Brand or partner colours** are theme custom colours, used by name:
|
|
330
362
|
`colors: { partner: "#0A7D3E" }` in `src/theme/index.js`, then
|
|
331
|
-
`<v-chip color="partner">`.
|
|
332
|
-
its hue
|
|
333
|
-
|
|
334
|
-
|
|
363
|
+
`<v-chip color="partner">`. A hex string is harmonized toward the seed; a
|
|
364
|
+
colour that must keep its hue is `{ value: "#F5C518", blend: false }`
|
|
365
|
+
(Material Theme Builder's Blend switched off), with the same four roles.
|
|
366
|
+
- **Content colours**, colours that are content rather than UI, keep one
|
|
367
|
+
value in both schemes: an identity palette a person picks and the server
|
|
368
|
+
stores, avatar and illustration artwork, brand marks (a language's
|
|
369
|
+
file-type tint), fixed chart series, QR codes, colours written into
|
|
370
|
+
exported files. They are named exports of plain hex values in
|
|
371
|
+
`src/theme/palettes.js`, used as they are, never for UI chrome (a theme
|
|
372
|
+
colour is toned per scheme, so it can't keep an identity the same).
|
|
373
|
+
Components read them through bindings:
|
|
374
|
+
|
|
375
|
+
```vue
|
|
376
|
+
<script setup>
|
|
377
|
+
// src/theme/palettes.js: export const botColours = ["#6750A4", "#B3261E"];
|
|
378
|
+
import { botColours } from "@/theme/palettes.js";
|
|
379
|
+
const props = defineProps({ bot: Object });
|
|
380
|
+
const ring = botColours[props.bot.colour];
|
|
381
|
+
</script>
|
|
382
|
+
<template>
|
|
383
|
+
<v-avatar :style="{ backgroundColor: ring }"><svg><path :fill="ring" /></svg></v-avatar>
|
|
384
|
+
</template>
|
|
385
|
+
<style scoped>.v-avatar { outline: 2px solid v-bind(ring); }</style>
|
|
386
|
+
```
|
|
387
|
+
- **Chart and data colours** that follow the scheme come from the theme:
|
|
388
|
+
`const theme = useTheme()`, then
|
|
389
|
+
`["primary", "tertiary"].map((role) => theme.current.value.colors[role])`.
|
|
335
390
|
- **A third-party widget** lives in one wrapper component, such as
|
|
336
391
|
`src/components/RouteMap.vue`, that hands it theme colours; pages use only
|
|
337
392
|
the wrapper.
|
|
338
393
|
|
|
339
|
-
What is left
|
|
340
|
-
before: `<!-- m3-check: allow m3/raw-hex - the partner's contractual logo colour -->`
|
|
394
|
+
What is left, such as a colour inside static SVG markup that can't import,
|
|
395
|
+
may be excused one line at a time, on its line or the line before: `<!-- m3-check: allow m3/raw-hex - the partner's contractual logo colour -->`
|
|
341
396
|
(`// m3-check: ...` in scripts, `/* ... */` in CSS). **Never add one on your
|
|
342
397
|
own:** ask the person first, naming the rule and the reason. A comment with no
|
|
343
398
|
reason (`m3/allow-reason`) or an unknown rule (`m3/allow-rule`), and any
|
package/package.json
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@local/main": "0.1.0",
|
|
36
36
|
"@fastify/static": "^10.1.3",
|
|
37
37
|
"@jskit-ai/kernel": "0.2.10",
|
|
38
|
-
"@jskit-ai/material-web": "0.1.
|
|
38
|
+
"@jskit-ai/material-web": "0.1.2",
|
|
39
39
|
"@tanstack/vue-query": "^5.101.0",
|
|
40
40
|
"fastify": "^5.12.7",
|
|
41
41
|
"pino": "^10.3.1",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@jskit-ai/config-eslint": "0.1.245",
|
|
53
|
-
"@jskit-ai/jskit-catalog": "0.2.
|
|
53
|
+
"@jskit-ai/jskit-catalog": "0.2.31",
|
|
54
54
|
"@playwright/test": "1.61.1",
|
|
55
55
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
56
56
|
"eslint": "^10.8.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@local/main": "0.1.0",
|
|
36
36
|
"@fastify/static": "^10.1.3",
|
|
37
37
|
"@jskit-ai/kernel": "0.2.10",
|
|
38
|
-
"@jskit-ai/material-web": "0.1.
|
|
38
|
+
"@jskit-ai/material-web": "0.1.2",
|
|
39
39
|
"@tanstack/vue-query": "^5.101.0",
|
|
40
40
|
"fastify": "^5.12.7",
|
|
41
41
|
"pino": "^10.3.1",
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
"vue-router": "^5.3.1",
|
|
46
46
|
"vuetify": "^4.3.0",
|
|
47
47
|
"@jskit-ai/http-runtime": "0.2.10",
|
|
48
|
-
"@jskit-ai/shell-web": "0.2.
|
|
48
|
+
"@jskit-ai/shell-web": "0.2.13",
|
|
49
49
|
"@fastify/fast-json-stringify-compiler": "^5.1.0",
|
|
50
50
|
"@vue/devtools-api": "^8.2.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@jskit-ai/config-eslint": "0.1.245",
|
|
54
|
-
"@jskit-ai/jskit-catalog": "0.2.
|
|
54
|
+
"@jskit-ai/jskit-catalog": "0.2.31",
|
|
55
55
|
"@playwright/test": "1.61.1",
|
|
56
56
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
57
57
|
"eslint": "^10.8.0",
|
|
@@ -15,7 +15,7 @@ A concrete Fastify, Vue, and JSKIT application foundation for products that do n
|
|
|
15
15
|
|
|
16
16
|
- Id: `app/minimal-foundation`
|
|
17
17
|
- Keywords: `app`, `fastify`, `foundation`, `minimal`, `server`, `vite`, `vue`
|
|
18
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
18
|
+
- Owner: `@jskit-ai/agent-docs@0.1.279`
|
|
19
19
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md)
|
|
20
20
|
- Examples: [example/](../../skills/jskit/references/patterns/app/minimal-foundation/example/)
|
|
21
21
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`
|
|
@@ -26,7 +26,7 @@ A concrete JSKIT web application foundation with responsive shell navigation, se
|
|
|
26
26
|
|
|
27
27
|
- Id: `app/shell-foundation`
|
|
28
28
|
- Keywords: `app`, `foundation`, `material`, `navigation`, `placements`, `shell`, `vite`, `vue`
|
|
29
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
29
|
+
- Owner: `@jskit-ai/agent-docs@0.1.279`
|
|
30
30
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/app/shell-foundation/PATTERN.md)
|
|
31
31
|
- Examples: [example/](../../skills/jskit/references/patterns/app/shell-foundation/example/)
|
|
32
32
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -37,7 +37,7 @@ Configure an assistant runtime for one application surface and expose its chat a
|
|
|
37
37
|
|
|
38
38
|
- Id: `assistant/assistant-surface`
|
|
39
39
|
- Keywords: `ai`, `assistant`, `chat`, `config`, `environment`, `page`, `placement`, `settings`, `surface`
|
|
40
|
-
- Owner: `@jskit-ai/assistant-runtime@0.2.
|
|
40
|
+
- Owner: `@jskit-ai/assistant-runtime@0.2.26`
|
|
41
41
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/assistant/assistant-surface/PATTERN.md)
|
|
42
42
|
- Examples: [example/](../../skills/jskit/references/patterns/assistant/assistant-surface/example/)
|
|
43
43
|
- Requires: `@jskit-ai/assistant-runtime`, `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`, `@jskit-ai/shell-web`
|
|
@@ -48,7 +48,7 @@ Run one OpenID Connect sign-in for all of an owner's apps as its own JSKIT proje
|
|
|
48
48
|
|
|
49
49
|
- Id: `auth/accounts-hub`
|
|
50
50
|
- Keywords: `accounts hub`, `auth`, `authentication`, `issuer`, `master login`, `oidc`, `openid connect`, `single sign-on`, `sso`
|
|
51
|
-
- Owner: `@jskit-ai/oidc-issuer-core@0.1.
|
|
51
|
+
- Owner: `@jskit-ai/oidc-issuer-core@0.1.18`
|
|
52
52
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/accounts-hub/PATTERN.md)
|
|
53
53
|
- Examples: [example/](../../skills/jskit/references/patterns/auth/accounts-hub/example/)
|
|
54
54
|
- Requires: `@jskit-ai/oidc-issuer-core`
|
|
@@ -59,7 +59,7 @@ Compose JSKIT authentication routes, views, profile controls, and public surface
|
|
|
59
59
|
|
|
60
60
|
- Id: `auth/auth-surface`
|
|
61
61
|
- Keywords: `account`, `auth`, `login`, `logout`, `password`, `placement`, `profile`, `reset`, `surface`
|
|
62
|
-
- Owner: `@jskit-ai/auth-web@0.2.
|
|
62
|
+
- Owner: `@jskit-ai/auth-web@0.2.15`
|
|
63
63
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/auth-surface/PATTERN.md)
|
|
64
64
|
- Examples: [example/](../../skills/jskit/references/patterns/auth/auth-surface/example/)
|
|
65
65
|
- Requires: `@jskit-ai/auth-core`, `@jskit-ai/auth-web`, `@jskit-ai/shell-web`
|
|
@@ -70,7 +70,7 @@ Let people sign in with the accounts they already have in an accounts hub or ano
|
|
|
70
70
|
|
|
71
71
|
- Id: `auth/oidc-sign-in`
|
|
72
72
|
- Keywords: `accounts hub`, `auth`, `authentication`, `back-channel logout`, `dynamic client registration`, `issuer`, `master login`, `oidc`, `openid connect`, `single sign-on`, `sso`
|
|
73
|
-
- Owner: `@jskit-ai/auth-provider-oidc-core@0.2.
|
|
73
|
+
- Owner: `@jskit-ai/auth-provider-oidc-core@0.2.17`
|
|
74
74
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/oidc-sign-in/PATTERN.md)
|
|
75
75
|
- Examples: [example/](../../skills/jskit/references/patterns/auth/oidc-sign-in/example/)
|
|
76
76
|
- Requires: `@jskit-ai/auth-provider-oidc-core`, `@jskit-ai/auth-web`
|
|
@@ -246,7 +246,7 @@ Add a protected administration surface, settings shell, and semantic navigation
|
|
|
246
246
|
|
|
247
247
|
- Id: `console/console-surface`
|
|
248
248
|
- Keywords: `admin`, `console`, `navigation`, `owner`, `placement`, `settings`, `surface`
|
|
249
|
-
- Owner: `@jskit-ai/console-web@0.1.
|
|
249
|
+
- Owner: `@jskit-ai/console-web@0.1.237`
|
|
250
250
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/console/console-surface/PATTERN.md)
|
|
251
251
|
- Examples: [example/](../../skills/jskit/references/patterns/console/console-surface/example/)
|
|
252
252
|
- Requires: `@jskit-ai/console-core`, `@jskit-ai/console-web`, `@jskit-ai/shell-web`
|
|
@@ -257,7 +257,7 @@ Build a routed CRUD user interface as thin application pages over JSKIT's shared
|
|
|
257
257
|
|
|
258
258
|
- Id: `crud/crud-screen-set`
|
|
259
259
|
- Keywords: `actions`, `add`, `crud`, `delete`, `edit`, `filters`, `list`, `material`, `routes`, `view`, `vue`
|
|
260
|
-
- Owner: `@jskit-ai/http-web@0.2.
|
|
260
|
+
- Owner: `@jskit-ai/http-web@0.2.18`
|
|
261
261
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md)
|
|
262
262
|
- Examples: [example/](../../skills/jskit/references/patterns/crud/crud-screen-set/example/)
|
|
263
263
|
- Requires: `@jskit-ai/http-web`, `@jskit-ai/resource-crud-core`
|
|
@@ -312,7 +312,7 @@ Wrap a JSKIT web application in a Capacitor Android shell using native Capacitor
|
|
|
312
312
|
|
|
313
313
|
- Id: `mobile/android-application`
|
|
314
314
|
- Keywords: `android`, `capacitor`, `device`, `mobile`, `native`, `shell`, `webview`
|
|
315
|
-
- Owner: `@jskit-ai/mobile-capacitor@0.2.
|
|
315
|
+
- Owner: `@jskit-ai/mobile-capacitor@0.2.13`
|
|
316
316
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/mobile/android-application/PATTERN.md)
|
|
317
317
|
- Examples: [example/](../../skills/jskit/references/patterns/mobile/android-application/example/)
|
|
318
318
|
- Requires: `@capacitor/android`, `@capacitor/app`, `@capacitor/cli`, `@jskit-ai/mobile-capacitor`
|
|
@@ -323,7 +323,7 @@ Add JSKIT realtime events with an optional Redis backplane and an explicit shell
|
|
|
323
323
|
|
|
324
324
|
- Id: `realtime/realtime-application`
|
|
325
325
|
- Keywords: `realtime`, `redis`, `socket.io`, `sockets`, `status`, `websocket`
|
|
326
|
-
- Owner: `@jskit-ai/realtime@0.2.
|
|
326
|
+
- Owner: `@jskit-ai/realtime@0.2.16`
|
|
327
327
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/realtime/realtime-application/PATTERN.md)
|
|
328
328
|
- Examples: [example/](../../skills/jskit/references/patterns/realtime/realtime-application/example/)
|
|
329
329
|
- Requires: `@jskit-ai/realtime`, `@jskit-ai/shell-web`
|
|
@@ -334,7 +334,7 @@ Compose application-owned Google Publisher Tag delivery with the generic rewarde
|
|
|
334
334
|
|
|
335
335
|
- Id: `rewards/google-rewarded`
|
|
336
336
|
- Keywords: `ads`, `google`, `publisher tag`, `rewarded`, `unlock`
|
|
337
|
-
- Owner: `@jskit-ai/rewarded-web@0.2.
|
|
337
|
+
- Owner: `@jskit-ai/rewarded-web@0.2.15`
|
|
338
338
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/rewards/google-rewarded/PATTERN.md)
|
|
339
339
|
- Examples: [example/](../../skills/jskit/references/patterns/rewards/google-rewarded/example/)
|
|
340
340
|
- Requires: `@jskit-ai/rewarded-web`
|
|
@@ -345,7 +345,7 @@ Define a server feature through explicit capabilities and first-class actions, a
|
|
|
345
345
|
|
|
346
346
|
- Id: `server/feature-package`
|
|
347
347
|
- Keywords: `actions`, `feature`, `json-rest`, `knex`, `orchestration`, `package`, `provider`, `repository`, `routes`, `server`
|
|
348
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
348
|
+
- Owner: `@jskit-ai/agent-docs@0.1.279`
|
|
349
349
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/server/feature-package/PATTERN.md)
|
|
350
350
|
- Examples: [example/](../../skills/jskit/references/patterns/server/feature-package/example/)
|
|
351
351
|
- Requires: `@jskit-ai/kernel`
|
|
@@ -356,7 +356,7 @@ Compose the JSKIT responsive shell, semantic placements, settings navigation, an
|
|
|
356
356
|
|
|
357
357
|
- Id: `shell/application-shell`
|
|
358
358
|
- Keywords: `adaptive`, `app`, `layout`, `navigation`, `placement`, `responsive`, `settings`, `shell`
|
|
359
|
-
- Owner: `@jskit-ai/shell-web@0.2.
|
|
359
|
+
- Owner: `@jskit-ai/shell-web@0.2.13`
|
|
360
360
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/shell/application-shell/PATTERN.md)
|
|
361
361
|
- Examples: [example/](../../skills/jskit/references/patterns/shell/application-shell/example/)
|
|
362
362
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -367,7 +367,7 @@ Add product routes and shell extensions through file routing, semantic placement
|
|
|
367
367
|
|
|
368
368
|
- Id: `ui/page-and-placement`
|
|
369
369
|
- Keywords: `component`, `navigation`, `outlet`, `page`, `placement`, `routes`, `section`, `shell`, `subpages`, `vue`
|
|
370
|
-
- Owner: `@jskit-ai/shell-web@0.2.
|
|
370
|
+
- Owner: `@jskit-ai/shell-web@0.2.13`
|
|
371
371
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/ui/page-and-placement/PATTERN.md)
|
|
372
372
|
- Examples: [example/](../../skills/jskit/references/patterns/ui/page-and-placement/example/)
|
|
373
373
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -378,7 +378,7 @@ Compose an account settings route and profile, preference, notification, and sig
|
|
|
378
378
|
|
|
379
379
|
- Id: `users/account-settings`
|
|
380
380
|
- Keywords: `account`, `link provider`, `notifications`, `oauth`, `preferences`, `profile`, `settings`, `sign-in methods`, `user`, `vue`
|
|
381
|
-
- Owner: `@jskit-ai/users-web@0.2.
|
|
381
|
+
- Owner: `@jskit-ai/users-web@0.2.20`
|
|
382
382
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/users/account-settings/PATTERN.md)
|
|
383
383
|
- Examples: [example/](../../skills/jskit/references/patterns/users/account-settings/example/)
|
|
384
384
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/users-core`, `@jskit-ai/users-web`
|
|
@@ -411,7 +411,7 @@ Compose workspace selection, invitation, member administration, settings, and re
|
|
|
411
411
|
|
|
412
412
|
- Id: `workspaces/workspace-surfaces`
|
|
413
413
|
- Keywords: `admin`, `invite`, `member`, `navigation`, `settings`, `surface`, `switcher`, `workspace`
|
|
414
|
-
- Owner: `@jskit-ai/workspaces-web@0.2.
|
|
414
|
+
- Owner: `@jskit-ai/workspaces-web@0.2.20`
|
|
415
415
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/workspaces/workspace-surfaces/PATTERN.md)
|
|
416
416
|
- Examples: [example/](../../skills/jskit/references/patterns/workspaces/workspace-surfaces/example/)
|
|
417
417
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/workspaces-core`, `@jskit-ai/workspaces-web`
|
|
@@ -52,7 +52,7 @@ Local functions
|
|
|
52
52
|
- `resolveSetupCode(env, { isProduction })`
|
|
53
53
|
- `resolveAppPublicUrl(env, { emailRecovery, emailedConfirmation, oauthEnabled })`
|
|
54
54
|
- `resolveRecoveryDelivery(env, { emailRecovery, isProduction })`
|
|
55
|
-
- `resolveConfirmationDelivery(env, { emailConfirmationSender, isProduction })`
|
|
55
|
+
- `resolveConfirmationDelivery(env, { emailConfirmationSender, isProduction, selfRegistration })`
|
|
56
56
|
- `resolvePasswordMinLength(env)`
|
|
57
57
|
|
|
58
58
|
### `src/server/lib/emailConfirmation.js`
|
|
@@ -182,6 +182,10 @@ Exports
|
|
|
182
182
|
- `shellNavigationLinkProps`
|
|
183
183
|
- `useShellNavigationLink(props)`
|
|
184
184
|
|
|
185
|
+
### `src/client/composables/useShellOutletPlacements.js`
|
|
186
|
+
Exports
|
|
187
|
+
- `useShellOutletPlacements(target, context = {})`
|
|
188
|
+
|
|
185
189
|
### `src/client/composables/useShellPageTitle.js`
|
|
186
190
|
Exports
|
|
187
191
|
- `useShellPageTitle(title)`
|
|
@@ -327,7 +331,7 @@ Local functions
|
|
|
327
331
|
|
|
328
332
|
### `src/client/navigation/documentNavigation.js`
|
|
329
333
|
Exports
|
|
330
|
-
- `leaveApp(url)`
|
|
334
|
+
- `leaveApp(url, { replace = false } = {})`
|
|
331
335
|
- `reloadAppPage(target)`
|
|
332
336
|
|
|
333
337
|
### `src/client/navigation/linkResolver.js`
|
|
@@ -335,7 +339,7 @@ Exports
|
|
|
335
339
|
- `resolveShellLinkPath({ context = null, surface = "", explicitTo = "", relativePath = "/", surfaceRelativePath = "", params = {}, strictParams = true } = {})`
|
|
336
340
|
- `useShellLinkResolver({ surface = "" } = {})`
|
|
337
341
|
Local functions
|
|
338
|
-
- `
|
|
342
|
+
- `fillPathParams(pathTemplate = "/", { params = {}, strictParams = true, label = "route params" } = {})`
|
|
339
343
|
- `resolveSurfaceBasePath(context = null, surface = "", { params = {}, strictParams = true } = {})`
|
|
340
344
|
|
|
341
345
|
### `src/client/navigation/shellNavigationRuntime.js`
|
|
@@ -547,6 +551,7 @@ Exports
|
|
|
547
551
|
- `normalizeDesktopDrawerClosedMode(value = "rail")`
|
|
548
552
|
- `resolveShellDrawerPresentation({ modal = false, open = false, desktopClosedMode = "rail" } = {})`
|
|
549
553
|
- `resolveShellDrawerToggleLabel({ modal = false, open = false } = {})`
|
|
554
|
+
- `shellLayoutHasDrawer({ menuSlot = false, menuCount = 0, identityCount = 0, bottomNavigationCount = 0 } = {})`
|
|
550
555
|
|
|
551
556
|
### `src/client/support/drawerWidth.js`
|
|
552
557
|
Exports
|
|
@@ -653,12 +658,14 @@ Exports
|
|
|
653
658
|
Exports
|
|
654
659
|
- None
|
|
655
660
|
|
|
661
|
+
### `fixtures/adaptive-shell/src/ButtonsPage.vue`
|
|
662
|
+
Exports
|
|
663
|
+
- None
|
|
664
|
+
|
|
656
665
|
### `fixtures/adaptive-shell/src/main.js`
|
|
657
666
|
Exports
|
|
658
667
|
- None
|
|
659
668
|
Local functions
|
|
660
|
-
- `createSurfacePlacement(surface, order, label, suffix)`
|
|
661
|
-
- `createSurfacePlacements(surface)`
|
|
662
669
|
- `refuseBlockedRecord(to)`
|
|
663
670
|
|
|
664
671
|
### `fixtures/adaptive-shell/src/OwnBarLayout.vue`
|
|
@@ -131,6 +131,7 @@ Exports
|
|
|
131
131
|
- `checkScriptBackNames(code, offset, report)`
|
|
132
132
|
- `isInAppPath(value)`
|
|
133
133
|
- `isPageFile(file)`
|
|
134
|
+
- `readTitledFiles({ root, appFiles })`
|
|
134
135
|
Local functions
|
|
135
136
|
- `compact(text)`
|
|
136
137
|
- `isPlacementLink(code, offset)`
|
|
@@ -146,6 +147,7 @@ Local functions
|
|
|
146
147
|
- `enclosingObject(text, offset)`
|
|
147
148
|
- `stringValue(text, key)`
|
|
148
149
|
- `readMainNavigation(sources)`
|
|
150
|
+
- `computedPlacementPart(placement)`
|
|
149
151
|
- `normalisePath(value)`
|
|
150
152
|
- `routeOf(file)`
|
|
151
153
|
- `routePattern(route)`
|
|
@@ -153,7 +155,7 @@ Local functions
|
|
|
153
155
|
- `surfaceOf(route, surfaces)`
|
|
154
156
|
- `routeDeclarations(source)`
|
|
155
157
|
- `readPage(file, source)`
|
|
156
|
-
- `createShellBarReader(appFiles, read)`
|
|
158
|
+
- `createShellBarReader(appFiles, read, tag = SHELL_UP_TAG)`
|
|
157
159
|
- `localComponent(file, specifier, known)`
|
|
158
160
|
- `pageKey(file)`
|
|
159
161
|
|
|
@@ -82,7 +82,10 @@ Exactly this, and nothing more:
|
|
|
82
82
|
2. **Each top-level destination is a main-navigation item** (a `kind: "link"`
|
|
83
83
|
placement with `target: "shell.primary-nav"` or `"shell.secondary-nav"`) and
|
|
84
84
|
declares no parent; nor do its tabs. A shell page with no parent is
|
|
85
|
-
top-level: no arrow, a fresh trail.
|
|
85
|
+
top-level: no arrow, a fresh trail. Placements are literal declarative data,
|
|
86
|
+
one `addPlacement({ ... })` per destination with plain string `surface`,
|
|
87
|
+
`scopedSuffix` and `unscopedSuffix`, never built by a helper, a spread or a
|
|
88
|
+
template, so a reader and `jskit check` can map every destination.
|
|
86
89
|
3. **Every in-app link and navigation goes through JSKIT navigation:**
|
|
87
90
|
`:to="paths.page('/suppliers')"` and `router.push(paths.page(...))` with
|
|
88
91
|
`usePaths()`, the CRUD runtime's `resolveViewUrl()`, `resolveEditUrl()` and
|
|
@@ -98,7 +101,10 @@ Exactly this, and nothing more:
|
|
|
98
101
|
5. **A full page load goes through the shell too:** `reloadAppPage(path)`
|
|
99
102
|
(after sign-in or a user switch, to rebuild client state) and
|
|
100
103
|
`leaveApp(url)` (an external site in the same tab, such as a payment page),
|
|
101
|
-
from `@jskit-ai/shell-web/client/navigation/documentNavigation`.
|
|
104
|
+
from `@jskit-ai/shell-web/client/navigation/documentNavigation`. `leaveApp`
|
|
105
|
+
opens the site with a push, so Back returns to the page; a hand-off page
|
|
106
|
+
that only forwards (to an OAuth consent screen) uses
|
|
107
|
+
`leaveApp(url, { replace: true })`, so Back from the site doesn't rerun it.
|
|
102
108
|
|
|
103
109
|
### Forbidden in app code
|
|
104
110
|
|
|
@@ -107,9 +113,11 @@ Exactly this, and nothing more:
|
|
|
107
113
|
| `nav/history` | `history.back()`, `history.go()`, `history.pushState()`/`replaceState()`, `router.back()`, `router.go()` |
|
|
108
114
|
| `nav/window-location` | `window.location` assignments, `.href =`, `location.assign()`, `location.replace()` |
|
|
109
115
|
| `nav/raw-link` | a hand-built in-app path in `to`, `href`, `router.push()`, `router.replace()` or a `to:`/`href:` object key outside a placement |
|
|
110
|
-
| `nav/back-control` | any back control but the shell's Up
|
|
116
|
+
| `nav/back-control` | any back control but the shell's Up that navigates the app: "Back to X", "← Suppliers", back arrows and navigating chevrons, breadcrumbs, a custom app-bar back button, a back component, a `goBack()`-style handler |
|
|
111
117
|
| `nav/missing-parent` | an inner page of a shell surface without a declared parent |
|
|
112
118
|
| `nav/top-level-parent` | a main-navigation destination that declares a parent |
|
|
119
|
+
| `nav/placement-data` | a main-navigation placement that isn't literal data (no page is judged for a missing parent until it is) |
|
|
120
|
+
| `nav/missing-shell-layout` | a page that declares a parent with no shell layout rendering it, so its title, Up and actions never show |
|
|
113
121
|
| `nav/allow` | any `m3-check: allow nav/...` comment: nothing excuses a navigation rule |
|
|
114
122
|
|
|
115
123
|
### Each rule, right and wrong
|
|
@@ -140,9 +148,15 @@ Exactly this, and nothing more:
|
|
|
140
148
|
`finish(recordUrl)`; the record shows, and Up goes where the record's Up went
|
|
141
149
|
before. Wrong: `router.push(recordUrl)` after Save, so Up or Back reopens the
|
|
142
150
|
form.
|
|
143
|
-
- **Steps inside a page are named actions
|
|
144
|
-
|
|
145
|
-
(
|
|
151
|
+
- **Steps and drill-downs inside a page are named actions.** A wizard step or
|
|
152
|
+
a panel the page opens in place is not a page, so it has no Up. Right:
|
|
153
|
+
"Previous step", or the destination's name ("Dashboard"), with no back
|
|
154
|
+
arrow. Wrong: "Back" or a back arrow. `nav/back-control` flags only controls
|
|
155
|
+
that navigate the app: a link into it, or a handler that reaches the router,
|
|
156
|
+
JSKIT paths, `up()`, `finish()` or the browser's history or location. Prose
|
|
157
|
+
("back from version 2"), a variable named `back` and an embedded frame's own
|
|
158
|
+
Back and Forward (`frame.contentWindow.history.back()`, as in a preview
|
|
159
|
+
browser) are not back controls.
|
|
146
160
|
|
|
147
161
|
## Foundation
|
|
148
162
|
|
|
@@ -176,10 +190,16 @@ JSKIT ships these exact sizes; an app never re-implements or overrides them,
|
|
|
176
190
|
and needs no Sass and no `!important` (Vuetify 4 keeps its CSS in cascade
|
|
177
191
|
layers):
|
|
178
192
|
|
|
179
|
-
- 40dp buttons with a 48dp touch target, icon buttons included;
|
|
180
|
-
-
|
|
193
|
+
- 40dp buttons with a 48dp touch target, icon buttons included; a smaller
|
|
194
|
+
button is `size="small"` or `size="x-small"`, which keeps its smaller look
|
|
195
|
+
and the 48dp target;
|
|
196
|
+
- one-line button labels: a label longer than its button ends in an ellipsis.
|
|
197
|
+
Keep labels short, and give a button whose label can run long, such as a
|
|
198
|
+
name, the full label as its `title`;
|
|
199
|
+
- 12dp cards: elevated (the default) at level 1, flat and tonal at level 0;
|
|
181
200
|
- 28dp dialogs and bottom-sheet top corners, square full-screen dialogs;
|
|
182
|
-
- 8dp chips and
|
|
201
|
+
- 8dp chips, and FABs of 56dp (small 40dp, large 96dp; extended 56dp tall)
|
|
202
|
+
with 16dp corners;
|
|
183
203
|
- emphasized easing, with reduced motion honoured.
|
|
184
204
|
|
|
185
205
|
So never set `height` or `min-height` on a button, or a radius on a card,
|
|
@@ -191,12 +211,22 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
191
211
|
`useShellPageTitle(title)` (`@jskit-ai/shell-web/client/composables/useShellPageTitle`)
|
|
192
212
|
for a runtime title such as the record's name. The shell renders it as the
|
|
193
213
|
app bar's only `h1`; pages add no `h1`, page header, title block or
|
|
194
|
-
standalone heading. A section inside a page uses a title role.
|
|
214
|
+
standalone heading. A section inside a page uses a title role. A page with
|
|
215
|
+
no top app bar (a hero front page, an intro, an invite or hand-off page)
|
|
216
|
+
has its own one `h1`.
|
|
195
217
|
- **Up** sits in the bar on every inner page (see Navigation and Up). On phones
|
|
196
218
|
it replaces the menu icon.
|
|
197
|
-
- **A layout
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
- **A layout that draws its own top app bar** (a workspace bar with the
|
|
220
|
+
app's own controls, instead of `ShellLayout`) builds it from `ShellLayout`'s
|
|
221
|
+
own pieces, from `@jskit-ai/shell-web/client`. It calls `useShellAppBar()`
|
|
222
|
+
once, so its pages enter the trail and their `ShellPageActions` show in its
|
|
223
|
+
bar, and renders `ShellUpButton` first, then `ShellPageTitle` (the page's one
|
|
224
|
+
`h1`: `useShellPageTitle()`, else the route's `jskit.title`, else its `title`
|
|
225
|
+
prop) and `ShellPageActionsTarget`. A title that is also a switcher, such as a
|
|
226
|
+
project menu, goes in `ShellPageTitle`'s default slot (given `{ title }`) as
|
|
227
|
+
the menu's activator, so it stays the one `h1`. `jskit check` counts it as a shell
|
|
228
|
+
layout, so its inner pages need parents; an Up the app draws itself is a
|
|
229
|
+
`nav/back-control` finding.
|
|
200
230
|
- **Actions:** a screen's actions go in the bar inside `ShellPageActions`
|
|
201
231
|
(`@jskit-ai/shell-web/client/components/ShellPageActions`), each a
|
|
202
232
|
`ShellPageAction` with `icon`, `label` (also its accessible name and compact
|
|
@@ -204,7 +234,9 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
204
234
|
On compact widths every action shows only its icon except the single
|
|
205
235
|
`primary` one.
|
|
206
236
|
- **Window size classes:** compact under 600 (navigation bar), medium 600–839
|
|
207
|
-
(navigation rail), expanded 840–1199 and large from 1200 (drawer).
|
|
237
|
+
(navigation rail), expanded 840–1199 and large from 1200 (drawer). A surface
|
|
238
|
+
with no navigation destinations, such as an account surface, draws no
|
|
239
|
+
navigation bar, rail or drawer; its pages keep the app bar. Read them
|
|
208
240
|
from `useShellWindowSizeClass()`
|
|
209
241
|
(`@jskit-ai/shell-web/client/composables/useShellWindowSizeClass`), never from
|
|
210
242
|
copied breakpoint numbers.
|
|
@@ -304,8 +336,8 @@ and so every app's verify, fail on them too:
|
|
|
304
336
|
|
|
305
337
|
| Rule | Finds |
|
|
306
338
|
|---|---|
|
|
307
|
-
| `m3/duplicate-h1` | a second `h1`, or an in-page `h1`
|
|
308
|
-
| `m3/raw-hex` | a hex colour outside `src/theme/` |
|
|
339
|
+
| `m3/duplicate-h1` | a second `h1`, or an in-page `h1` under the shell's page title |
|
|
340
|
+
| `m3/raw-hex` | a hex colour outside `src/theme/` (`palettes.js` holds content colours) |
|
|
309
341
|
| `m3/dark-scheme` | no dark scheme, or the theme pinned to light |
|
|
310
342
|
| `m3/outlined-card` | `variant="outlined"` or `border` on a card or sheet |
|
|
311
343
|
| `m3/mdi-icon` | `mdi-*` icon strings and `@mdi/js` imports |
|
|
@@ -323,16 +355,39 @@ Take the approved route first; none needs an exception:
|
|
|
323
355
|
|
|
324
356
|
- **Brand or partner colours** are theme custom colours, used by name:
|
|
325
357
|
`colors: { partner: "#0A7D3E" }` in `src/theme/index.js`, then
|
|
326
|
-
`<v-chip color="partner">`.
|
|
327
|
-
its hue
|
|
328
|
-
|
|
329
|
-
|
|
358
|
+
`<v-chip color="partner">`. A hex string is harmonized toward the seed; a
|
|
359
|
+
colour that must keep its hue is `{ value: "#F5C518", blend: false }`
|
|
360
|
+
(Material Theme Builder's Blend switched off), with the same four roles.
|
|
361
|
+
- **Content colours**, colours that are content rather than UI, keep one
|
|
362
|
+
value in both schemes: an identity palette a person picks and the server
|
|
363
|
+
stores, avatar and illustration artwork, brand marks (a language's
|
|
364
|
+
file-type tint), fixed chart series, QR codes, colours written into
|
|
365
|
+
exported files. They are named exports of plain hex values in
|
|
366
|
+
`src/theme/palettes.js`, used as they are, never for UI chrome (a theme
|
|
367
|
+
colour is toned per scheme, so it can't keep an identity the same).
|
|
368
|
+
Components read them through bindings:
|
|
369
|
+
|
|
370
|
+
```vue
|
|
371
|
+
<script setup>
|
|
372
|
+
// src/theme/palettes.js: export const botColours = ["#6750A4", "#B3261E"];
|
|
373
|
+
import { botColours } from "@/theme/palettes.js";
|
|
374
|
+
const props = defineProps({ bot: Object });
|
|
375
|
+
const ring = botColours[props.bot.colour];
|
|
376
|
+
</script>
|
|
377
|
+
<template>
|
|
378
|
+
<v-avatar :style="{ backgroundColor: ring }"><svg><path :fill="ring" /></svg></v-avatar>
|
|
379
|
+
</template>
|
|
380
|
+
<style scoped>.v-avatar { outline: 2px solid v-bind(ring); }</style>
|
|
381
|
+
```
|
|
382
|
+
- **Chart and data colours** that follow the scheme come from the theme:
|
|
383
|
+
`const theme = useTheme()`, then
|
|
384
|
+
`["primary", "tertiary"].map((role) => theme.current.value.colors[role])`.
|
|
330
385
|
- **A third-party widget** lives in one wrapper component, such as
|
|
331
386
|
`src/components/RouteMap.vue`, that hands it theme colours; pages use only
|
|
332
387
|
the wrapper.
|
|
333
388
|
|
|
334
|
-
What is left
|
|
335
|
-
before: `<!-- m3-check: allow m3/raw-hex - the partner's contractual logo colour -->`
|
|
389
|
+
What is left, such as a colour inside static SVG markup that can't import,
|
|
390
|
+
may be excused one line at a time, on its line or the line before: `<!-- m3-check: allow m3/raw-hex - the partner's contractual logo colour -->`
|
|
336
391
|
(`// m3-check: ...` in scripts, `/* ... */` in CSS). **Never add one on your
|
|
337
392
|
own:** ask the person first, naming the rule and the reason. A comment with no
|
|
338
393
|
reason (`m3/allow-reason`) or an unknown rule (`m3/allow-rule`), and any
|
|
@@ -15,7 +15,7 @@ A concrete Fastify, Vue, and JSKIT application foundation for products that do n
|
|
|
15
15
|
|
|
16
16
|
- Id: `app/minimal-foundation`
|
|
17
17
|
- Keywords: `app`, `fastify`, `foundation`, `minimal`, `server`, `vite`, `vue`
|
|
18
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
18
|
+
- Owner: `@jskit-ai/agent-docs@0.1.279`
|
|
19
19
|
- Read: [PATTERN.md](patterns/app/minimal-foundation/PATTERN.md)
|
|
20
20
|
- Examples: [example/](patterns/app/minimal-foundation/example/)
|
|
21
21
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`
|
|
@@ -26,7 +26,7 @@ A concrete JSKIT web application foundation with responsive shell navigation, se
|
|
|
26
26
|
|
|
27
27
|
- Id: `app/shell-foundation`
|
|
28
28
|
- Keywords: `app`, `foundation`, `material`, `navigation`, `placements`, `shell`, `vite`, `vue`
|
|
29
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
29
|
+
- Owner: `@jskit-ai/agent-docs@0.1.279`
|
|
30
30
|
- Read: [PATTERN.md](patterns/app/shell-foundation/PATTERN.md)
|
|
31
31
|
- Examples: [example/](patterns/app/shell-foundation/example/)
|
|
32
32
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -37,7 +37,7 @@ Configure an assistant runtime for one application surface and expose its chat a
|
|
|
37
37
|
|
|
38
38
|
- Id: `assistant/assistant-surface`
|
|
39
39
|
- Keywords: `ai`, `assistant`, `chat`, `config`, `environment`, `page`, `placement`, `settings`, `surface`
|
|
40
|
-
- Owner: `@jskit-ai/assistant-runtime@0.2.
|
|
40
|
+
- Owner: `@jskit-ai/assistant-runtime@0.2.26`
|
|
41
41
|
- Read: [PATTERN.md](patterns/assistant/assistant-surface/PATTERN.md)
|
|
42
42
|
- Examples: [example/](patterns/assistant/assistant-surface/example/)
|
|
43
43
|
- Requires: `@jskit-ai/assistant-runtime`, `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`, `@jskit-ai/shell-web`
|
|
@@ -48,7 +48,7 @@ Run one OpenID Connect sign-in for all of an owner's apps as its own JSKIT proje
|
|
|
48
48
|
|
|
49
49
|
- Id: `auth/accounts-hub`
|
|
50
50
|
- Keywords: `accounts hub`, `auth`, `authentication`, `issuer`, `master login`, `oidc`, `openid connect`, `single sign-on`, `sso`
|
|
51
|
-
- Owner: `@jskit-ai/oidc-issuer-core@0.1.
|
|
51
|
+
- Owner: `@jskit-ai/oidc-issuer-core@0.1.18`
|
|
52
52
|
- Read: [PATTERN.md](patterns/auth/accounts-hub/PATTERN.md)
|
|
53
53
|
- Examples: [example/](patterns/auth/accounts-hub/example/)
|
|
54
54
|
- Requires: `@jskit-ai/oidc-issuer-core`
|
|
@@ -59,7 +59,7 @@ Compose JSKIT authentication routes, views, profile controls, and public surface
|
|
|
59
59
|
|
|
60
60
|
- Id: `auth/auth-surface`
|
|
61
61
|
- Keywords: `account`, `auth`, `login`, `logout`, `password`, `placement`, `profile`, `reset`, `surface`
|
|
62
|
-
- Owner: `@jskit-ai/auth-web@0.2.
|
|
62
|
+
- Owner: `@jskit-ai/auth-web@0.2.15`
|
|
63
63
|
- Read: [PATTERN.md](patterns/auth/auth-surface/PATTERN.md)
|
|
64
64
|
- Examples: [example/](patterns/auth/auth-surface/example/)
|
|
65
65
|
- Requires: `@jskit-ai/auth-core`, `@jskit-ai/auth-web`, `@jskit-ai/shell-web`
|
|
@@ -70,7 +70,7 @@ Let people sign in with the accounts they already have in an accounts hub or ano
|
|
|
70
70
|
|
|
71
71
|
- Id: `auth/oidc-sign-in`
|
|
72
72
|
- Keywords: `accounts hub`, `auth`, `authentication`, `back-channel logout`, `dynamic client registration`, `issuer`, `master login`, `oidc`, `openid connect`, `single sign-on`, `sso`
|
|
73
|
-
- Owner: `@jskit-ai/auth-provider-oidc-core@0.2.
|
|
73
|
+
- Owner: `@jskit-ai/auth-provider-oidc-core@0.2.17`
|
|
74
74
|
- Read: [PATTERN.md](patterns/auth/oidc-sign-in/PATTERN.md)
|
|
75
75
|
- Examples: [example/](patterns/auth/oidc-sign-in/example/)
|
|
76
76
|
- Requires: `@jskit-ai/auth-provider-oidc-core`, `@jskit-ai/auth-web`
|
|
@@ -246,7 +246,7 @@ Add a protected administration surface, settings shell, and semantic navigation
|
|
|
246
246
|
|
|
247
247
|
- Id: `console/console-surface`
|
|
248
248
|
- Keywords: `admin`, `console`, `navigation`, `owner`, `placement`, `settings`, `surface`
|
|
249
|
-
- Owner: `@jskit-ai/console-web@0.1.
|
|
249
|
+
- Owner: `@jskit-ai/console-web@0.1.237`
|
|
250
250
|
- Read: [PATTERN.md](patterns/console/console-surface/PATTERN.md)
|
|
251
251
|
- Examples: [example/](patterns/console/console-surface/example/)
|
|
252
252
|
- Requires: `@jskit-ai/console-core`, `@jskit-ai/console-web`, `@jskit-ai/shell-web`
|
|
@@ -257,7 +257,7 @@ Build a routed CRUD user interface as thin application pages over JSKIT's shared
|
|
|
257
257
|
|
|
258
258
|
- Id: `crud/crud-screen-set`
|
|
259
259
|
- Keywords: `actions`, `add`, `crud`, `delete`, `edit`, `filters`, `list`, `material`, `routes`, `view`, `vue`
|
|
260
|
-
- Owner: `@jskit-ai/http-web@0.2.
|
|
260
|
+
- Owner: `@jskit-ai/http-web@0.2.18`
|
|
261
261
|
- Read: [PATTERN.md](patterns/crud/crud-screen-set/PATTERN.md)
|
|
262
262
|
- Examples: [example/](patterns/crud/crud-screen-set/example/)
|
|
263
263
|
- Requires: `@jskit-ai/http-web`, `@jskit-ai/resource-crud-core`
|
|
@@ -312,7 +312,7 @@ Wrap a JSKIT web application in a Capacitor Android shell using native Capacitor
|
|
|
312
312
|
|
|
313
313
|
- Id: `mobile/android-application`
|
|
314
314
|
- Keywords: `android`, `capacitor`, `device`, `mobile`, `native`, `shell`, `webview`
|
|
315
|
-
- Owner: `@jskit-ai/mobile-capacitor@0.2.
|
|
315
|
+
- Owner: `@jskit-ai/mobile-capacitor@0.2.13`
|
|
316
316
|
- Read: [PATTERN.md](patterns/mobile/android-application/PATTERN.md)
|
|
317
317
|
- Examples: [example/](patterns/mobile/android-application/example/)
|
|
318
318
|
- Requires: `@capacitor/android`, `@capacitor/app`, `@capacitor/cli`, `@jskit-ai/mobile-capacitor`
|
|
@@ -323,7 +323,7 @@ Add JSKIT realtime events with an optional Redis backplane and an explicit shell
|
|
|
323
323
|
|
|
324
324
|
- Id: `realtime/realtime-application`
|
|
325
325
|
- Keywords: `realtime`, `redis`, `socket.io`, `sockets`, `status`, `websocket`
|
|
326
|
-
- Owner: `@jskit-ai/realtime@0.2.
|
|
326
|
+
- Owner: `@jskit-ai/realtime@0.2.16`
|
|
327
327
|
- Read: [PATTERN.md](patterns/realtime/realtime-application/PATTERN.md)
|
|
328
328
|
- Examples: [example/](patterns/realtime/realtime-application/example/)
|
|
329
329
|
- Requires: `@jskit-ai/realtime`, `@jskit-ai/shell-web`
|
|
@@ -334,7 +334,7 @@ Compose application-owned Google Publisher Tag delivery with the generic rewarde
|
|
|
334
334
|
|
|
335
335
|
- Id: `rewards/google-rewarded`
|
|
336
336
|
- Keywords: `ads`, `google`, `publisher tag`, `rewarded`, `unlock`
|
|
337
|
-
- Owner: `@jskit-ai/rewarded-web@0.2.
|
|
337
|
+
- Owner: `@jskit-ai/rewarded-web@0.2.15`
|
|
338
338
|
- Read: [PATTERN.md](patterns/rewards/google-rewarded/PATTERN.md)
|
|
339
339
|
- Examples: [example/](patterns/rewards/google-rewarded/example/)
|
|
340
340
|
- Requires: `@jskit-ai/rewarded-web`
|
|
@@ -345,7 +345,7 @@ Define a server feature through explicit capabilities and first-class actions, a
|
|
|
345
345
|
|
|
346
346
|
- Id: `server/feature-package`
|
|
347
347
|
- Keywords: `actions`, `feature`, `json-rest`, `knex`, `orchestration`, `package`, `provider`, `repository`, `routes`, `server`
|
|
348
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
348
|
+
- Owner: `@jskit-ai/agent-docs@0.1.279`
|
|
349
349
|
- Read: [PATTERN.md](patterns/server/feature-package/PATTERN.md)
|
|
350
350
|
- Examples: [example/](patterns/server/feature-package/example/)
|
|
351
351
|
- Requires: `@jskit-ai/kernel`
|
|
@@ -356,7 +356,7 @@ Compose the JSKIT responsive shell, semantic placements, settings navigation, an
|
|
|
356
356
|
|
|
357
357
|
- Id: `shell/application-shell`
|
|
358
358
|
- Keywords: `adaptive`, `app`, `layout`, `navigation`, `placement`, `responsive`, `settings`, `shell`
|
|
359
|
-
- Owner: `@jskit-ai/shell-web@0.2.
|
|
359
|
+
- Owner: `@jskit-ai/shell-web@0.2.13`
|
|
360
360
|
- Read: [PATTERN.md](patterns/shell/application-shell/PATTERN.md)
|
|
361
361
|
- Examples: [example/](patterns/shell/application-shell/example/)
|
|
362
362
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -367,7 +367,7 @@ Add product routes and shell extensions through file routing, semantic placement
|
|
|
367
367
|
|
|
368
368
|
- Id: `ui/page-and-placement`
|
|
369
369
|
- Keywords: `component`, `navigation`, `outlet`, `page`, `placement`, `routes`, `section`, `shell`, `subpages`, `vue`
|
|
370
|
-
- Owner: `@jskit-ai/shell-web@0.2.
|
|
370
|
+
- Owner: `@jskit-ai/shell-web@0.2.13`
|
|
371
371
|
- Read: [PATTERN.md](patterns/ui/page-and-placement/PATTERN.md)
|
|
372
372
|
- Examples: [example/](patterns/ui/page-and-placement/example/)
|
|
373
373
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -378,7 +378,7 @@ Compose an account settings route and profile, preference, notification, and sig
|
|
|
378
378
|
|
|
379
379
|
- Id: `users/account-settings`
|
|
380
380
|
- Keywords: `account`, `link provider`, `notifications`, `oauth`, `preferences`, `profile`, `settings`, `sign-in methods`, `user`, `vue`
|
|
381
|
-
- Owner: `@jskit-ai/users-web@0.2.
|
|
381
|
+
- Owner: `@jskit-ai/users-web@0.2.20`
|
|
382
382
|
- Read: [PATTERN.md](patterns/users/account-settings/PATTERN.md)
|
|
383
383
|
- Examples: [example/](patterns/users/account-settings/example/)
|
|
384
384
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/users-core`, `@jskit-ai/users-web`
|
|
@@ -411,7 +411,7 @@ Compose workspace selection, invitation, member administration, settings, and re
|
|
|
411
411
|
|
|
412
412
|
- Id: `workspaces/workspace-surfaces`
|
|
413
413
|
- Keywords: `admin`, `invite`, `member`, `navigation`, `settings`, `surface`, `switcher`, `workspace`
|
|
414
|
-
- Owner: `@jskit-ai/workspaces-web@0.2.
|
|
414
|
+
- Owner: `@jskit-ai/workspaces-web@0.2.20`
|
|
415
415
|
- Read: [PATTERN.md](patterns/workspaces/workspace-surfaces/PATTERN.md)
|
|
416
416
|
- Examples: [example/](patterns/workspaces/workspace-surfaces/example/)
|
|
417
417
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/workspaces-core`, `@jskit-ai/workspaces-web`
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@local/main": "0.1.0",
|
|
36
36
|
"@fastify/static": "^10.1.3",
|
|
37
37
|
"@jskit-ai/kernel": "0.2.10",
|
|
38
|
-
"@jskit-ai/material-web": "0.1.
|
|
38
|
+
"@jskit-ai/material-web": "0.1.2",
|
|
39
39
|
"@tanstack/vue-query": "^5.101.0",
|
|
40
40
|
"fastify": "^5.12.7",
|
|
41
41
|
"pino": "^10.3.1",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@jskit-ai/config-eslint": "0.1.245",
|
|
53
|
-
"@jskit-ai/jskit-catalog": "0.2.
|
|
53
|
+
"@jskit-ai/jskit-catalog": "0.2.31",
|
|
54
54
|
"@playwright/test": "1.61.1",
|
|
55
55
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
56
56
|
"eslint": "^10.8.0",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@local/main": "0.1.0",
|
|
36
36
|
"@fastify/static": "^10.1.3",
|
|
37
37
|
"@jskit-ai/kernel": "0.2.10",
|
|
38
|
-
"@jskit-ai/material-web": "0.1.
|
|
38
|
+
"@jskit-ai/material-web": "0.1.2",
|
|
39
39
|
"@tanstack/vue-query": "^5.101.0",
|
|
40
40
|
"fastify": "^5.12.7",
|
|
41
41
|
"pino": "^10.3.1",
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
"vue-router": "^5.3.1",
|
|
46
46
|
"vuetify": "^4.3.0",
|
|
47
47
|
"@jskit-ai/http-runtime": "0.2.10",
|
|
48
|
-
"@jskit-ai/shell-web": "0.2.
|
|
48
|
+
"@jskit-ai/shell-web": "0.2.13",
|
|
49
49
|
"@fastify/fast-json-stringify-compiler": "^5.1.0",
|
|
50
50
|
"@vue/devtools-api": "^8.2.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@jskit-ai/config-eslint": "0.1.245",
|
|
54
|
-
"@jskit-ai/jskit-catalog": "0.2.
|
|
54
|
+
"@jskit-ai/jskit-catalog": "0.2.31",
|
|
55
55
|
"@playwright/test": "1.61.1",
|
|
56
56
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
57
57
|
"eslint": "^10.8.0",
|
|
@@ -57,10 +57,15 @@ provider offers provider linking (`providerLinking` in its capabilities).
|
|
|
57
57
|
- Loading uses layout-stable skeletons, never an indeterminate spinner.
|
|
58
58
|
- Pending controls keep stable labels and prevent duplicate submission.
|
|
59
59
|
- The route and placement owner agree.
|
|
60
|
+
- The account surface renders in its own layout, `src/pages/account.vue`
|
|
61
|
+
(`ShellLayout` around `<RouterView />`, `meta.jskit.surface: "account"`), so
|
|
62
|
+
the settings page's title, Up arrow and Done action are in the top app bar.
|
|
63
|
+
With no navigation items, the surface shows no navigation bar, rail or drawer.
|
|
60
64
|
|
|
61
65
|
## Example files
|
|
62
66
|
|
|
63
|
-
`example/` contains an account route and four
|
|
67
|
+
`example/` contains the account surface's layout, an account route and four
|
|
68
|
+
concrete settings sections.
|
|
64
69
|
Adapt their fields and copy while retaining the shared account runtime.
|
|
65
70
|
|
|
66
71
|
## Variation points
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<route lang="json">
|
|
2
|
+
{
|
|
3
|
+
"meta": {
|
|
4
|
+
"jskit": {
|
|
5
|
+
"surface": "account"
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
</route>
|
|
10
|
+
|
|
11
|
+
<script setup>
|
|
12
|
+
// The account surface's layout: the shell's top app bar carries the settings page's title, its Up arrow back to home
|
|
13
|
+
// and its Done action. The surface has no navigation items, so the shell draws no navigation bar, rail or drawer.
|
|
14
|
+
import ShellLayout from "@/components/ShellLayout.vue";
|
|
15
|
+
import { RouterView } from "vue-router";
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<ShellLayout title="" subtitle="">
|
|
20
|
+
<RouterView />
|
|
21
|
+
</ShellLayout>
|
|
22
|
+
</template>
|