@jskit-ai/agent-docs 0.1.279 → 0.1.280
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-extras/assistant.md +123 -0
- package/guide/agent/app-setup/authentication.md +34 -3
- package/guide/agent/app-setup/database-layer.md +35 -6
- package/guide/agent/app-setup/material-3-migration.md +38 -9
- package/guide/agent/app-setup/multi-homing.md +8 -2
- package/guide/agent/app-setup/upgrading-jskit.md +30 -0
- package/guide/agent/app-setup/users.md +9 -1
- package/guide/agent/framework/material-3.md +111 -71
- package/guide/agent/framework/sanity-checks.md +180 -0
- package/guide/agent/framework/translation.md +4 -0
- package/guide/agent/framework/typed-features.md +158 -105
- package/guide/agent/framework/ui-operations.md +3 -1
- package/guide/agent/index.md +3 -0
- package/package.json +2 -2
- package/patterns/feature-package/example/booking-engine/package.json +1 -1
- package/patterns/minimal-foundation/PATTERN.md +6 -2
- package/patterns/minimal-foundation/example/AGENTS.md +10 -0
- package/patterns/minimal-foundation/example/package.json +6 -6
- package/patterns/minimal-foundation/example/playwright.config.mjs +3 -0
- package/patterns/minimal-foundation/example/src/main.js +3 -2
- package/patterns/minimal-foundation/example/vite.config.mjs +3 -1
- package/patterns/shell-foundation/PATTERN.md +4 -1
- package/patterns/shell-foundation/example/AGENTS.md +10 -0
- package/patterns/shell-foundation/example/package.json +7 -7
- package/patterns/shell-foundation/example/packages/main/package.json +1 -1
- package/patterns/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +3 -0
- package/patterns/shell-foundation/example/playwright.config.mjs +3 -0
- package/patterns/shell-foundation/example/src/components/menus/SectionTabLinkItem.vue +42 -0
- package/patterns/shell-foundation/example/src/main.js +3 -2
- package/patterns/shell-foundation/example/src/pages/home.vue +1 -1
- package/patterns/shell-foundation/example/src/views/NotFound.vue +1 -1
- package/patterns/shell-foundation/example/vite.config.mjs +3 -1
- package/reference/autogen/PATTERN_INDEX.md +37 -37
- package/reference/autogen/packages/agent-docs.md +4 -0
- package/reference/autogen/packages/assistant-runtime.md +27 -2
- package/reference/autogen/packages/auth-web.md +10 -0
- package/reference/autogen/packages/crud-core.md +3 -0
- package/reference/autogen/packages/http-web.md +0 -4
- package/reference/autogen/packages/json-rest-api-core.md +17 -4
- package/reference/autogen/packages/kernel.md +10 -1
- package/reference/autogen/packages/material-web.md +2 -1
- package/reference/autogen/packages/shell-web.md +84 -0
- package/reference/autogen/packages/users-web.md +5 -2
- package/reference/autogen/packages/workspaces-core.md +2 -0
- package/reference/autogen/tooling/jskit-catalog.md +52 -5
- package/reference/autogen/tooling/testUtils.md +15 -1
- package/skills/jskit/SKILL.md +15 -5
- package/skills/jskit/references/heuristics/INDEX.md +3 -1
- package/skills/jskit/references/heuristics/row-policies.md +3 -3
- package/skills/jskit/references/heuristics/typed-features.md +7 -7
- package/skills/jskit/references/heuristics/ui-testing.md +8 -7
- package/skills/jskit/references/material-3.md +111 -71
- package/skills/jskit/references/multi-homing.md +8 -2
- package/skills/jskit/references/pattern-index.md +37 -37
- package/skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md +6 -2
- package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +10 -0
- package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +6 -6
- package/skills/jskit/references/patterns/app/minimal-foundation/example/playwright.config.mjs +3 -0
- package/skills/jskit/references/patterns/app/minimal-foundation/example/src/main.js +3 -2
- package/skills/jskit/references/patterns/app/minimal-foundation/example/vite.config.mjs +3 -1
- package/skills/jskit/references/patterns/app/shell-foundation/PATTERN.md +4 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +10 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +7 -7
- package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +3 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/playwright.config.mjs +3 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/src/components/menus/SectionTabLinkItem.vue +42 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/src/main.js +3 -2
- package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home.vue +1 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/src/views/NotFound.vue +1 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/vite.config.mjs +3 -1
- package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/auth-surface/PATTERN.md +18 -5
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/components/AppBrand.vue +17 -0
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/pages/auth/login.vue +2 -2
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/pages/auth/reset-password.vue +2 -2
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/pages/auth/signout.vue +2 -2
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/views/auth/LoginView.vue +6 -1
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/views/auth/ResetPasswordView.vue +6 -1
- package/skills/jskit/references/patterns/auth/auth-surface/example/src/views/auth/SignOutView.vue +6 -1
- package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
- package/skills/jskit/references/patterns/connectors/aws-storage-queries/example/formats/package.json +1 -1
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
- package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console.vue +1 -1
- package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
- package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
- package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
- package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
- package/skills/jskit/references/patterns/rewards/google-rewarded/example/googlePublisherTag.js +5 -2
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
- package/skills/jskit/references/patterns/shell/application-shell/PATTERN.md +11 -6
- package/skills/jskit/references/patterns/shell/application-shell/example/src/components/menus/SectionTabLinkItem.vue +42 -0
- package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home.vue +1 -1
- package/skills/jskit/references/patterns/shell/application-shell/example/src/views/NotFound.vue +1 -1
- package/skills/jskit/references/patterns/ui/page-and-placement/PATTERN.md +6 -0
- package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports.vue +9 -4
- package/skills/jskit/references/patterns/ui/page-and-placement/example/src/placementTopology.js +5 -3
- package/skills/jskit/references/patterns/users/account-settings/PATTERN.md +24 -3
- package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsNotificationsSection.vue +1 -1
- package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsPreferencesSection.vue +2 -1
- package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsProfileSection.vue +3 -2
- package/skills/jskit/references/patterns/users/account-settings/example/src/pages/account/[section].vue +23 -0
- package/skills/jskit/references/patterns/users/account-settings/example/src/pages/account.vue +4 -3
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
- package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/packages/main/src/client/components/AccountPendingInvitesCue.vue +3 -3
- package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/admin/root.vue +1 -1
- package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/app/root.vue +1 -1
- package/skills/jskit/references/sanity-checks.md +180 -0
- package/skills/jskit/references/translation.md +4 -0
- package/skills/jskit/references/typed-features.md +158 -105
- package/skills/jskit/references/ui-operations.md +3 -1
|
@@ -42,7 +42,8 @@ app and never leaves it.
|
|
|
42
42
|
- **What the person sees:** one Up arrow on every inner page, also when opened
|
|
43
43
|
directly: icon only (`$arrowBack`), accessible name "Back" (localized), a
|
|
44
44
|
tooltip on pointer devices. None on top-level destinations, and no other
|
|
45
|
-
back control anywhere; the bar title says where the person is. A
|
|
45
|
+
back control anywhere; the bar title says where the person is. A new or edit
|
|
46
|
+
form shows a close (X) in the arrow's place, which cancels. A list-detail
|
|
46
47
|
layout showing the parent beside the page needs no arrow for that step;
|
|
47
48
|
collapsed to one pane, the record pane gets it back.
|
|
48
49
|
- **Where Up goes:** to the previous trail entry while it is valid, so inside
|
|
@@ -74,11 +75,17 @@ Exactly this, and nothing more:
|
|
|
74
75
|
</script>
|
|
75
76
|
```
|
|
76
77
|
|
|
77
|
-
The same key works in a `<route lang="json">` block.
|
|
78
|
-
list, an edit page its record, a sub-page its page. Tabs under a layout
|
|
78
|
+
The same key works in a `<route lang="json">` block. Tabs under a layout
|
|
79
79
|
(`settings.vue` rendering `<RouterView>` for `settings/`) declare nothing:
|
|
80
80
|
they inherit the nearest layout's declaration, and moving between them keeps
|
|
81
|
-
the trail.
|
|
81
|
+
the trail and the scroll. A folder without a layout (`bookings/` with no
|
|
82
|
+
`bookings.vue`) only groups routes: its pages are different pages, each
|
|
83
|
+
opening at the top. The parent is read from the page up to its surface root, the
|
|
84
|
+
record that declares `jskit.surface`, and stops there. So the surface goes
|
|
85
|
+
only on the surface's layout page (`account.vue`: `ShellLayout` around
|
|
86
|
+
`<RouterView />`) and the parent on the page it renders
|
|
87
|
+
(`account/index.vue`). A package route declares its parent in its
|
|
88
|
+
`package.json` `meta`; under no layout, its component draws `ShellLayout`.
|
|
82
89
|
2. **Each top-level destination is a main-navigation item** (a `kind: "link"`
|
|
83
90
|
placement with `target: "shell.primary-nav"` or `"shell.secondary-nav"`) and
|
|
84
91
|
declares no parent; nor do its tabs. A shell page with no parent is
|
|
@@ -90,14 +97,20 @@ Exactly this, and nothing more:
|
|
|
90
97
|
`:to="paths.page('/suppliers')"` and `router.push(paths.page(...))` with
|
|
91
98
|
`usePaths()`, the CRUD runtime's `resolveViewUrl()`, `resolveEditUrl()` and
|
|
92
99
|
`resolveParams()`, and link placements (`surface` with `scopedSuffix` and
|
|
93
|
-
`unscopedSuffix`; `to` only for a global route
|
|
94
|
-
|
|
100
|
+
`unscopedSuffix`; `to` only for a global route). A global route
|
|
101
|
+
(`scope: "global"`, on no surface) is
|
|
102
|
+
`paths.page("/auth/login", { scope: "global" })`; `explicitTo` only passes
|
|
103
|
+
through a finished target that arrives as data, never a hand-written path.
|
|
104
|
+
The trail follows the router, so there is no special link component.
|
|
95
105
|
4. **A custom new or edit page finishes through the shell:**
|
|
96
106
|
`useShellNavigation()` (`@jskit-ai/shell-web/client/navigation/useShellNavigation`)
|
|
97
107
|
gives `finish(target)` for Save (the target replaces the form in the trail)
|
|
98
108
|
and `finish()` for Cancel (back to where the form was opened, else its
|
|
99
|
-
parent)
|
|
100
|
-
`
|
|
109
|
+
parent); `useShellPageClose({ label, close })`
|
|
110
|
+
(`@jskit-ai/shell-web/client/composables/useShellPageClose`) makes the
|
|
111
|
+
arrow its Cancel, never an X beside it. A page whose
|
|
112
|
+
record turns out deleted or forbidden calls `pageUnavailable()`. JSKIT's
|
|
113
|
+
CRUD screens already do all three.
|
|
101
114
|
5. **A full page load goes through the shell too:** `reloadAppPage(path)`
|
|
102
115
|
(after sign-in or a user switch, to rebuild client state) and
|
|
103
116
|
`leaveApp(url)` (an external site in the same tab, such as a payment page),
|
|
@@ -113,11 +126,12 @@ Exactly this, and nothing more:
|
|
|
113
126
|
| `nav/history` | `history.back()`, `history.go()`, `history.pushState()`/`replaceState()`, `router.back()`, `router.go()` |
|
|
114
127
|
| `nav/window-location` | `window.location` assignments, `.href =`, `location.assign()`, `location.replace()` |
|
|
115
128
|
| `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 |
|
|
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 |
|
|
117
|
-
| `nav/missing-parent` | an inner page of a shell surface without a declared parent |
|
|
129
|
+
| `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 (`<ContextBackButton />` or `<page-back-link>`, and its import), a `goBack()`-style handler |
|
|
130
|
+
| `nav/missing-parent` | an inner page of a shell surface without a declared parent, when it always renders under the shell's top app bar (a layout that also renders its pages without `ShellLayout`, such as a shop device's sign-in in a `v-if`, leaves its pages unjudged) |
|
|
118
131
|
| `nav/top-level-parent` | a main-navigation destination that declares a parent |
|
|
119
132
|
| `nav/placement-data` | a main-navigation placement that isn't literal data (no page is judged for a missing parent until it is) |
|
|
120
133
|
| `nav/missing-shell-layout` | a page that declares a parent with no shell layout rendering it, so its title, Up and actions never show |
|
|
134
|
+
| `nav/surface-parent` | a parent declared beside `jskit.surface`, which the shell never reads |
|
|
121
135
|
| `nav/allow` | any `m3-check: allow nav/...` comment: nothing excuses a navigation rule |
|
|
122
136
|
|
|
123
137
|
### Each rule, right and wrong
|
|
@@ -175,35 +189,43 @@ Exactly this, and nothing more:
|
|
|
175
189
|
- **Type:** Vuetify 4 Material 3 roles (`text-headline-small`,
|
|
176
190
|
`text-title-large`, `text-body-medium`, `text-label-large`). Never the
|
|
177
191
|
Material 2 scale (`text-h5`, `text-body-2`) or a page-local type system.
|
|
178
|
-
Roboto Flex
|
|
192
|
+
Material 3 has two typefaces, both Roboto Flex unless the app names its own
|
|
193
|
+
in `src/theme/index.js`:
|
|
194
|
+
`typography: { brand: '"Fraunces", serif', plain: '"Inter", sans-serif' }`.
|
|
195
|
+
`brand` sets display, headline and title-large, `plain` the rest (title-medium
|
|
196
|
+
and -small, body, label); each is a CSS font-family value, and the app loads
|
|
197
|
+
the font. Never set `font-family` or `--v-font-body` in app CSS.
|
|
179
198
|
- **Icons:** Material Symbols Rounded through Vuetify `$` aliases: Vuetify's
|
|
180
199
|
standard ones (`$close`, `$menu`, `$delete`, `$prev`, `$next`) and JSKIT's
|
|
181
200
|
camelCase names (`$add`, `$edit`, `$search`, `$moreVert`, `$filterList`,
|
|
182
201
|
`$arrowBack`); `$homeFilled`-style `Filled` variants mark active navigation.
|
|
183
202
|
An app adds an icon under `theme.icons` in `src/theme/index.js` as
|
|
184
203
|
`{ name: "<24x24 path data>" }` from Material Symbols Rounded, then uses
|
|
185
|
-
`$name`. No `mdi-*` strings and no `@mdi/js` imports in app code.
|
|
204
|
+
`$name`. No `mdi-*` strings and no `@mdi/js` imports in app code. Material
|
|
205
|
+
Symbols has no brand marks (Google, GitHub, a payment network): a brand's
|
|
206
|
+
logo is the brand's own artwork, a content image or SVG used as its owner
|
|
207
|
+
publishes it, not an icon alias.
|
|
186
208
|
|
|
187
209
|
## Exact sizes
|
|
188
210
|
|
|
189
|
-
JSKIT ships these exact sizes; an app never re-implements or overrides them
|
|
190
|
-
and needs no Sass and no `!important` (Vuetify 4 keeps its CSS in cascade
|
|
191
|
-
layers):
|
|
211
|
+
JSKIT ships these exact sizes; an app never re-implements or overrides them:
|
|
192
212
|
|
|
193
213
|
- 40dp buttons with a 48dp touch target, icon buttons included; a smaller
|
|
194
214
|
button is `size="small"` or `size="x-small"`, which keeps its smaller look
|
|
195
|
-
and the 48dp target
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
215
|
+
and the 48dp target. No icon button is under 32dp, and a target stops at
|
|
216
|
+
the edge of a button beside it, so each of a row's touching icon buttons
|
|
217
|
+
answers its own press;
|
|
218
|
+
- one-line button labels, ending in an ellipsis: keep labels short, and give
|
|
219
|
+
one that can run long, such as a name, its full label as `title`;
|
|
220
|
+
- 12dp cards: flat (the default) and tonal at level 0, `variant="elevated"`
|
|
221
|
+
at level 1; flat expansion panels;
|
|
200
222
|
- 28dp dialogs and bottom-sheet top corners, square full-screen dialogs;
|
|
201
223
|
- 8dp chips, and FABs of 56dp (small 40dp, large 96dp; extended 56dp tall)
|
|
202
224
|
with 16dp corners;
|
|
203
225
|
- emphasized easing, with reduced motion honoured.
|
|
204
226
|
|
|
205
227
|
So never set `height` or `min-height` on a button, or a radius on a card,
|
|
206
|
-
dialog, chip or FAB.
|
|
228
|
+
dialog, chip or FAB.
|
|
207
229
|
|
|
208
230
|
## The top app bar carries the page
|
|
209
231
|
|
|
@@ -211,35 +233,46 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
211
233
|
`useShellPageTitle(title)` (`@jskit-ai/shell-web/client/composables/useShellPageTitle`)
|
|
212
234
|
for a runtime title such as the record's name. The shell renders it as the
|
|
213
235
|
app bar's only `h1`; pages add no `h1`, page header, title block or
|
|
214
|
-
standalone heading.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
-
|
|
218
|
-
|
|
236
|
+
standalone heading. Route pages own the title: a section or a nested
|
|
237
|
+
component uses a title role (a component's claim gives the title back when
|
|
238
|
+
it goes). A page with no top app bar (a hero front page, an intro, an invite
|
|
239
|
+
or hand-off page) has its own one `h1`.
|
|
240
|
+
- **Up** leads the bar on every inner page; on phones it replaces the menu
|
|
241
|
+
icon.
|
|
219
242
|
- **A layout that draws its own top app bar** (a workspace bar with the
|
|
220
243
|
app's own controls, instead of `ShellLayout`) builds it from `ShellLayout`'s
|
|
221
244
|
own pieces, from `@jskit-ai/shell-web/client`. It calls `useShellAppBar()`
|
|
222
245
|
once, so its pages enter the trail and their `ShellPageActions` show in its
|
|
223
246
|
bar, and renders `ShellUpButton` first, then `ShellPageTitle` (the page's one
|
|
224
|
-
`h1
|
|
225
|
-
prop) and `ShellPageActionsTarget`. A title that is also a switcher, such as a
|
|
247
|
+
`h1`) and `ShellPageActionsTarget`. A title that is also a switcher, such as a
|
|
226
248
|
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
|
|
228
|
-
layout, so its inner pages need parents
|
|
229
|
-
`nav/back-control` finding.
|
|
249
|
+
the menu's activator, so it stays the one `h1`. `jskit check` counts it as a
|
|
250
|
+
shell layout, so its inner pages need parents.
|
|
230
251
|
- **Actions:** a screen's actions go in the bar inside `ShellPageActions`
|
|
231
252
|
(`@jskit-ai/shell-web/client/components/ShellPageActions`), each a
|
|
232
253
|
`ShellPageAction` with `icon`, `label` (also its accessible name and compact
|
|
233
|
-
tooltip), and `primary`, `to`, `replace`, `
|
|
234
|
-
|
|
235
|
-
`
|
|
254
|
+
tooltip), and `primary`, `to`, `replace`, `href` (with `download` for a
|
|
255
|
+
file, such as a CSV export), `disabled`, `loading` or `color` (`error` for a
|
|
256
|
+
destructive one); attributes such as `target` reach its button. On compact
|
|
257
|
+
widths the bar keeps one trailing item after the title: the single
|
|
258
|
+
`primary` action when the page has one (a form's Save), otherwise its own
|
|
259
|
+
item nearest the corner (a top-right placement such as the account avatar).
|
|
260
|
+
Every other action and the bar's other items (a notification bell, tools)
|
|
261
|
+
go to its "More actions" menu, where `overflow` actions always are. Medium
|
|
262
|
+
and wider bars show them all.
|
|
236
263
|
- **Window size classes:** compact under 600 (navigation bar), medium 600–839
|
|
237
|
-
(navigation rail), expanded 840–1199 and large from 1200 (drawer)
|
|
238
|
-
|
|
239
|
-
navigation bar, rail or drawer; its pages keep the app bar. Read them
|
|
240
|
-
from `useShellWindowSizeClass()`
|
|
264
|
+
(navigation rail), expanded 840–1199 and large from 1200 (drawer), read from
|
|
265
|
+
`useShellWindowSizeClass()`
|
|
241
266
|
(`@jskit-ai/shell-web/client/composables/useShellWindowSizeClass`), never from
|
|
242
|
-
copied breakpoint numbers.
|
|
267
|
+
copied breakpoint numbers. A surface with fewer than two navigation
|
|
268
|
+
destinations (none, as on an account surface, or Home alone) draws no
|
|
269
|
+
navigation bar, rail or drawer; its pages keep the app bar.
|
|
270
|
+
- **Section tabs:** a page's own sections (`page.section-nav`) are Material 3
|
|
271
|
+
primary tabs: the topology names `ShellSectionTabLinkItem`'s token (the
|
|
272
|
+
starter registers it as `local.main.ui.section-tab-link-item`), and the page
|
|
273
|
+
draws one tab row, `display: flex; overflow-x: auto` over a 1dp
|
|
274
|
+
`outline-variant` bottom border. `ShellTabLinkItem` is the navigation bar's
|
|
275
|
+
destination; placed in a page it draws a section tab.
|
|
243
276
|
|
|
244
277
|
## Colour
|
|
245
278
|
|
|
@@ -262,35 +295,41 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
262
295
|
control; never a permanent panel of outlined fields. A card opens its record
|
|
263
296
|
when tapped (a stretched title link); a table row opens on click. Row actions
|
|
264
297
|
are trailing icon buttons (edit, a `$moreVert` overflow menu, a chevron to
|
|
265
|
-
open), never "View" or "Edit" text buttons on every row. "New" is
|
|
266
|
-
|
|
267
|
-
and
|
|
298
|
+
open), never "View" or "Edit" text buttons on every row. "New" is
|
|
299
|
+
`ShellPrimaryAction` (`label`, and `to` or a click handler): an extended FAB
|
|
300
|
+
on compact and medium widths, a filled bar button on expanded. On/off filters
|
|
301
|
+
are `aria-pressed` chips, or chips in a `v-chip-group`; JSKIT draws them as
|
|
302
|
+
filter chips. Empty and error states carry an icon.
|
|
268
303
|
- **A list never scrolls sideways, at any width.** The list's own width (a
|
|
269
304
|
container query, not the window) chooses cards or table. Cards flow into a
|
|
270
305
|
grid; tables use a fixed layout with an ellipsis on long values, and fold
|
|
271
306
|
low-priority columns into a stronger column's second line. Lists show figures
|
|
272
307
|
("120 kg", tabular and right-aligned) and names, never ids.
|
|
273
308
|
- **Record:** a header (avatar, title, status chips) and value-first detail
|
|
274
|
-
lists, never a grid of label/value text. Edit sits in the bar
|
|
309
|
+
lists, never a grid of label/value text. Edit sits in the bar, its secondary
|
|
310
|
+
actions in the bar's overflow menu, never in the content; the record's
|
|
275
311
|
next workflow step is the one filled button, shown in context rather than a
|
|
276
312
|
row of mostly disabled actions.
|
|
277
|
-
- **Form:**
|
|
278
|
-
Nothing moves under a finger: a multi-select chip
|
|
279
|
-
when it loses focus. A pick-one-of-N choice is a
|
|
280
|
-
|
|
313
|
+
- **Form:** the bar's close (X) cancels and Save is its filled action. Fields
|
|
314
|
+
use `hideDetails: "auto"`. Nothing moves under a finger: a multi-select chip
|
|
315
|
+
field keeps its input width when it loses focus. A pick-one-of-N choice is a
|
|
316
|
+
segmented button (`v-btn-toggle`, drawn by JSKIT, with 12dp segment sides as
|
|
317
|
+
in any `v-btn-group`) with `role="radiogroup"` and
|
|
318
|
+
`role="radio"`/`aria-checked` buttons.
|
|
281
319
|
- **Dialogs:** plain `v-dialog` and `v-bottom-sheet`; JSKIT gives them their
|
|
282
320
|
Material 3 shapes. A full-screen dialog (compact and medium) puts close, title
|
|
283
321
|
and its confirm action in a top bar, never at the bottom where a snackbar
|
|
284
322
|
covers them.
|
|
285
323
|
- **Menus and badges:** a menu's list has `role="menu"` and its items
|
|
286
324
|
`role="menuitem"`, with `aria-disabled` on unavailable ones; a badge has a
|
|
287
|
-
`label` such as "3 batches".
|
|
325
|
+
`label` such as "3 batches". JSKIT draws a menu's list and a dialog's card;
|
|
326
|
+
an app sets no `VMenu` or `VDialog` defaults, under which
|
|
327
|
+
Vuetify 4.2.1 to 4.3.2 loses a `v-select`'s typeahead match, or a dialog's
|
|
328
|
+
virtual list, when an ancestor re-renders.
|
|
288
329
|
|
|
289
330
|
## Components, state, and feedback
|
|
290
331
|
|
|
291
|
-
- Choose components by purpose
|
|
292
|
-
tables, sheets, dialogs, menus, navigation, progress, alerts, snackbars, and
|
|
293
|
-
tooltips over custom imitations.
|
|
332
|
+
- Choose standard components by purpose over custom imitations.
|
|
294
333
|
- Give one primary action emphasis. Distinguish destructive, secondary, and
|
|
295
334
|
icon-only actions without relying on color; give icon controls accessible
|
|
296
335
|
names and fields meaningful labels, errors, and autocomplete behavior.
|
|
@@ -307,6 +346,11 @@ dialog, chip or FAB. A missing size is a JSKIT defect.
|
|
|
307
346
|
field. A user-triggered command uses JSKIT's shared action
|
|
308
347
|
feedback/snackbar path. Never insert a transient command-error alert above
|
|
309
348
|
page content where it shifts the working layout.
|
|
349
|
+
- A snackbar never covers the FAB or the actions it reports on. `ShellErrorHost`
|
|
350
|
+
centres it above the navigation bar on compact windows and starts it at the
|
|
351
|
+
content's start edge, at most half its width, on wider ones. A FAB takes
|
|
352
|
+
layout room (`<v-fab app layout>`, as `ShellPrimaryAction`'s does), so the
|
|
353
|
+
snackbar shows above it.
|
|
310
354
|
|
|
311
355
|
## Adaptive layout
|
|
312
356
|
|
|
@@ -328,16 +372,15 @@ npx jskit check m3 src/pages/home/books # a section
|
|
|
328
372
|
npx jskit check m3 $(git diff --name-only --diff-filter=d main) # changed files
|
|
329
373
|
```
|
|
330
374
|
|
|
331
|
-
Plain `jskit check` fails on the [navigation rules](#forbidden-in-app-code)
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
and so every app's verify, fail on them too:
|
|
375
|
+
Plain `jskit check` fails on the [navigation rules](#forbidden-in-app-code).
|
|
376
|
+
`jskit check m3` lists those and the visual rules below. The visual rules are a
|
|
377
|
+
report until every JSKIT app has been converted to them; the JSKIT release after
|
|
378
|
+
that makes plain `jskit check`, and so every app's verify, fail on them too:
|
|
336
379
|
|
|
337
380
|
| Rule | Finds |
|
|
338
381
|
|---|---|
|
|
339
|
-
| `m3/duplicate-h1` | a second `h1
|
|
340
|
-
| `m3/raw-hex` | a hex colour outside `src/theme/` (`palettes.js` holds content colours) |
|
|
382
|
+
| `m3/duplicate-h1` | a second `h1` that can show beside the first (one per `v-if` branch is one), or an in-page `h1` under a layout that always shows the shell's page title |
|
|
383
|
+
| `m3/raw-hex` | a hex colour, or one written as channels (`rgba(0, 0, 0, 0.15)`, as in a hand-made shadow), outside `src/theme/` (`palettes.js` holds content colours); `rgba(var(--v-theme-shadow), 0.2)` reads a role and passes |
|
|
341
384
|
| `m3/dark-scheme` | no dark scheme, or the theme pinned to light |
|
|
342
385
|
| `m3/outlined-card` | `variant="outlined"` or `border` on a card or sheet |
|
|
343
386
|
| `m3/mdi-icon` | `mdi-*` icon strings and `@mdi/js` imports |
|
|
@@ -390,9 +433,9 @@ What is left, such as a colour inside static SVG markup that can't import,
|
|
|
390
433
|
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 -->`
|
|
391
434
|
(`// m3-check: ...` in scripts, `/* ... */` in CSS). **Never add one on your
|
|
392
435
|
own:** ask the person first, naming the rule and the reason. A comment with no
|
|
393
|
-
reason (`m3/allow-reason`) or an unknown rule (`m3/allow-rule`)
|
|
394
|
-
|
|
395
|
-
|
|
436
|
+
reason (`m3/allow-reason`) or an unknown rule (`m3/allow-rule`) is itself a
|
|
437
|
+
finding, as any `nav/allow` is; nothing turns the check off for a file, a
|
|
438
|
+
folder or the app. `jskit check m3` lists every
|
|
396
439
|
exception with its file, line and reason, and their total.
|
|
397
440
|
|
|
398
441
|
## Material 3 audit
|
|
@@ -401,19 +444,16 @@ Run this behavior-preserving audit over every affected screen:
|
|
|
401
444
|
|
|
402
445
|
1. Identify the owning JSKIT surface, shared screen, shell, placement, theme,
|
|
403
446
|
and Vuetify components before judging local markup.
|
|
404
|
-
2. Check navigation and Up first, as must-fix: plain `jskit check` passes
|
|
405
|
-
every
|
|
406
|
-
destinations have none; no inner link is hand-built; nothing writes back
|
|
407
|
-
logic.
|
|
447
|
+
2. Check navigation and Up first, as must-fix: plain `jskit check` passes and
|
|
448
|
+
every rule in Navigation and Up holds.
|
|
408
449
|
3. Find parallel components, duplicated state chrome, page-local themes, raw
|
|
409
450
|
visual constants, CSS against Vuetify internals, nested generic cards,
|
|
410
|
-
borders instead of tones, Material 2 typography, and desktop-only layout
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
5. Correct issues at the narrowest established owner. Consolidate only truly
|
|
451
|
+
borders instead of tones, Material 2 typography, and desktop-only layout;
|
|
452
|
+
check states, focus, labels, targets, contrast and reduced motion against
|
|
453
|
+
the rules above.
|
|
454
|
+
4. Correct issues at the narrowest established owner. Consolidate only truly
|
|
415
455
|
repeated policy; avoid pass-through wrappers and speculative abstractions.
|
|
416
|
-
|
|
456
|
+
5. Run `jskit check` and `jskit check m3` on the affected files, then focused
|
|
417
457
|
tests and Playwright at compact, medium, and expanded widths in light and
|
|
418
458
|
dark (`shellBackButton(page)` and `pressShellBack(page)` from
|
|
419
459
|
`@jskit-ai/shell-web/test/shellNavigation` drive Up).
|
|
@@ -174,6 +174,12 @@ capability provides:
|
|
|
174
174
|
| `workspaces.repositories.workspaces`, `.workspaceMemberships`, `.workspaceSettings`, `.workspaceInvites` | Repository access inside the application's own transactions |
|
|
175
175
|
| `workspaces.tenancyProfile` | The resolved tenancy mode and workspace policy |
|
|
176
176
|
|
|
177
|
+
To check one person's membership, for example a notification recipient, call
|
|
178
|
+
`workspaces.services.members.getMember(workspace, userId, options)`. It answers
|
|
179
|
+
that member's `listMembers` entry, or `null` for a removed or unknown member,
|
|
180
|
+
and reads only that membership. Do not list every member to find one: the list
|
|
181
|
+
grows with the workspace, and a lookup per row multiplies it.
|
|
182
|
+
|
|
177
183
|
### Invitation email
|
|
178
184
|
|
|
179
185
|
To send invitation email, provide the optional `workspaces.invite-mailer`
|
|
@@ -452,9 +458,9 @@ Use only a verified empty disposable database named
|
|
|
452
458
|
reports its engine version, applies package migrations and drops fixture tables.
|
|
453
459
|
|
|
454
460
|
```sh
|
|
455
|
-
|
|
461
|
+
npx jskit test packages/workspaces-core/test/*.test.js
|
|
456
462
|
# Set JSKIT_REPOSITORY_TEST_DATABASE_URL to the verified empty disposable target.
|
|
457
|
-
|
|
463
|
+
npx jskit test packages/workspaces-core/test/repositories.integration.test.js
|
|
458
464
|
npm run verify
|
|
459
465
|
```
|
|
460
466
|
|