@jskit-ai/shell-web 0.1.250 → 0.1.252
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/fixtures/adaptive-shell/src/main.js +6 -3
- package/package.json +2 -2
- package/patterns/application-shell/PATTERN.md +18 -4
- package/patterns/application-shell/example/src/pages/home/index.vue +15 -5
- package/patterns/application-shell/example/tests/e2e/adaptive-shell.spec.ts +1 -1
- package/src/architecture/inspectVueArchitecture.js +1092 -336
- package/src/client/asyncModuleRecovery/runtime.js +116 -0
- package/src/client/components/ShellLayout.vue +18 -288
- package/src/client/components/ShellMenuLinkItem.vue +3 -21
- package/src/client/components/ShellOutlet.vue +2 -24
- package/src/client/components/ShellRouteTransition.vue +16 -114
- package/src/client/components/ShellSurfaceAwareMenuLinkItem.vue +5 -100
- package/src/client/components/ShellTabLinkItem.vue +5 -101
- package/src/client/composables/useShellNavigationLink.js +85 -0
- package/src/client/composables/useShellPullToRefresh.js +260 -0
- package/src/client/error/index.js +1 -1
- package/src/client/error/inject.js +4 -1
- package/src/client/error/policy.js +4 -13
- package/src/client/error/presenters.js +4 -9
- package/src/client/error/store.js +1 -1
- package/src/client/navigation/linkResolver.js +5 -27
- package/src/client/navigation/usePaths.js +1 -21
- package/src/client/placement/index.js +2 -0
- package/src/client/placement/inject.js +4 -1
- package/src/client/placement/runtime.js +2 -4
- package/src/client/placement/surfaceContext.js +11 -8
- package/src/client/placement/validators.js +18 -65
- package/src/client/providers/ShellWebClientProvider.js +100 -356
- package/src/client/requestRecovery/runtime.js +29 -77
- package/src/client/runtime/bootstrapRuntime.js +5 -4
- package/src/client/runtime/refreshRuntime.js +122 -0
- package/src/client/support/gestureTargets.js +26 -0
- package/src/client/support/menuLinkTarget.js +35 -19
- package/src/client/support/routeParams.js +26 -0
- package/src/client/support/routeSwipeGesture.js +88 -0
- package/src/client/support/routeTransitionKey.js +1 -3
- package/src/client/support/shellLayoutClass.js +32 -0
- package/test/bootstrapRuntime.test.js +98 -0
- package/test/errorActions.test.js +2 -1
- package/test/errorRuntime.test.js +30 -0
- package/test/linkResolver.test.js +23 -1
- package/test/menuLinkTarget.test.js +77 -0
- package/test/routeSwipeGesture.test.js +49 -0
- package/test/settingsPlacementContract.test.js +16 -6
- package/test/shellGestureSupport.test.js +46 -0
- package/test/surfaceContext.test.js +53 -0
- package/test/useShellPullToRefresh.test.js +123 -0
|
@@ -13,6 +13,9 @@ import ShellSurfaceAwareMenuLinkItem from "@jskit-ai/shell-web/client/components
|
|
|
13
13
|
import ShellTabLinkItem from "@jskit-ai/shell-web/client/components/ShellTabLinkItem";
|
|
14
14
|
import { useShellLayoutStore } from "../../../src/client/stores/useShellLayoutStore.js";
|
|
15
15
|
import { createWebPlacementRuntime } from "../../../src/client/placement/runtime.js";
|
|
16
|
+
import { SHELL_WEB_PLACEMENT_RUNTIME_KEY } from "../../../src/client/placement/inject.js";
|
|
17
|
+
import { SHELL_WEB_ERROR_RUNTIME_KEY } from "../../../src/client/error/inject.js";
|
|
18
|
+
import { SHELL_WEB_REFRESH_RUNTIME_KEY } from "../../../src/client/runtime/refreshRuntime.js";
|
|
16
19
|
import { createErrorRuntime } from "../../../src/client/error/runtime.js";
|
|
17
20
|
import { createDefaultMaterialErrorPresenters } from "../../../src/client/error/presenters.js";
|
|
18
21
|
import { createErrorPresentationStore } from "../../../src/client/error/store.js";
|
|
@@ -183,21 +186,21 @@ const app = createApp(App);
|
|
|
183
186
|
app.use(pinia);
|
|
184
187
|
app.use(router);
|
|
185
188
|
app.use(vuetify);
|
|
186
|
-
app.provide(
|
|
189
|
+
app.provide(SHELL_WEB_PLACEMENT_RUNTIME_KEY, placementRuntime);
|
|
187
190
|
const errorStore = createErrorPresentationStore();
|
|
188
191
|
const errorRuntime = createErrorRuntime({
|
|
189
192
|
presenters: createDefaultMaterialErrorPresenters({ store: errorStore }),
|
|
190
193
|
defaultPresenterId: "material.snackbar"
|
|
191
194
|
});
|
|
192
195
|
useShellErrorPresentationStore(pinia).attachRuntimeStore(errorStore);
|
|
193
|
-
app.provide(
|
|
196
|
+
app.provide(SHELL_WEB_ERROR_RUNTIME_KEY, errorRuntime);
|
|
194
197
|
window.__shellFixtureReportBanner = (message) => errorRuntime.report({
|
|
195
198
|
source: "shell-web.fixture",
|
|
196
199
|
message,
|
|
197
200
|
severity: "error",
|
|
198
201
|
channel: "banner"
|
|
199
202
|
});
|
|
200
|
-
app.provide(
|
|
203
|
+
app.provide(SHELL_WEB_REFRESH_RUNTIME_KEY, {
|
|
201
204
|
async refresh() {
|
|
202
205
|
await fetch("/api/bootstrap?reason=pull-to-refresh");
|
|
203
206
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/shell-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.252",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test --test-concurrency=1"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@vue/compiler-sfc": "3.5.44"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@jskit-ai/kernel": "0.1.
|
|
37
|
+
"@jskit-ai/kernel": "0.1.246",
|
|
38
38
|
"pinia": "^4.0.3",
|
|
39
39
|
"vue": "^3.5.44",
|
|
40
40
|
"vue-router": "^5.3.1",
|
|
@@ -43,10 +43,24 @@ placement registry, topology, and adaptive smoke helper exported by
|
|
|
43
43
|
above the content so they never cover it. A full-viewport fixed screen on
|
|
44
44
|
such a surface starts at `var(--shell-error-banners-inline-height, 0px)`, as
|
|
45
45
|
`@jskit-ai/auth-web`'s login and reset views do.
|
|
46
|
-
- Restyle shell chrome through its
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
- Restyle shell chrome through its custom properties, not by overriding
|
|
47
|
+
Vuetify internals: `--shell-chrome-border-width` and
|
|
48
|
+
`--shell-chrome-border-color` for the shared dividers,
|
|
49
|
+
`--shell-app-bar-border-width`, `--shell-navigation-border-width` and
|
|
50
|
+
`--shell-bottom-navigation-border-width` per edge, and
|
|
51
|
+
`--shell-app-bar-background`, `--shell-navigation-background` and
|
|
52
|
+
`--shell-bottom-navigation-background` for the surfaces. The defaults keep
|
|
53
|
+
one thin divider on each separating edge, because Vuetify's default themes
|
|
54
|
+
define no Material 3 surface-container roles. A Material 3 restyle sets the
|
|
55
|
+
border widths to `0` and gives navigation a tonal surface, for example
|
|
56
|
+
`rgb(var(--v-theme-surface-container-low))` when the theme defines it.
|
|
57
|
+
- `createShellRouter()` from `@jskit-ai/kernel/client` installs
|
|
58
|
+
`shellScrollBehavior`: a new screen opens at the top (or its hash target),
|
|
59
|
+
Back/Forward restore the saved position, and query, hash, tab or sub-view
|
|
60
|
+
changes within the same page keep it. A tab or sub-view is the same page when
|
|
61
|
+
both locations share a parent page record below the surface root. Pass
|
|
62
|
+
`scrollBehavior` to replace it, or `scrollBehavior: false` to disable it; do
|
|
63
|
+
not wrap the router or reset scroll in page components.
|
|
50
64
|
- The adaptive browser check closes navigation through its public close control.
|
|
51
65
|
|
|
52
66
|
## Example files
|
|
@@ -15,16 +15,16 @@ const healthQuery = useQuery({
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
const health = computed(() => {
|
|
18
|
-
if (healthQuery.isPending.value || healthQuery.isFetching.value) {
|
|
19
|
-
return "loading...";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
18
|
if (healthQuery.error.value) {
|
|
23
19
|
return "unreachable";
|
|
24
20
|
}
|
|
25
21
|
|
|
26
22
|
return healthQuery.data.value?.ok ? "ok" : "unhealthy";
|
|
27
23
|
});
|
|
24
|
+
|
|
25
|
+
const healthPending = computed(
|
|
26
|
+
() => healthQuery.isPending.value || healthQuery.isFetching.value
|
|
27
|
+
);
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
30
|
<template>
|
|
@@ -36,7 +36,13 @@ const health = computed(() => {
|
|
|
36
36
|
<v-sheet rounded="lg" border class="home-surface-screen__panel">
|
|
37
37
|
<div class="home-surface-screen__status">
|
|
38
38
|
<span class="text-caption text-medium-emphasis">Service health</span>
|
|
39
|
-
<
|
|
39
|
+
<v-skeleton-loader
|
|
40
|
+
v-if="healthPending"
|
|
41
|
+
aria-label="Loading service health"
|
|
42
|
+
class="home-surface-screen__health-skeleton"
|
|
43
|
+
type="text"
|
|
44
|
+
/>
|
|
45
|
+
<strong v-else>{{ health }}</strong>
|
|
40
46
|
</div>
|
|
41
47
|
<v-divider vertical class="d-none d-sm-block" />
|
|
42
48
|
<div class="home-surface-screen__status">
|
|
@@ -71,6 +77,10 @@ const health = computed(() => {
|
|
|
71
77
|
min-width: 9rem;
|
|
72
78
|
}
|
|
73
79
|
|
|
80
|
+
.home-surface-screen__health-skeleton {
|
|
81
|
+
max-width: 5rem;
|
|
82
|
+
}
|
|
83
|
+
|
|
74
84
|
@media (max-width: 640px) {
|
|
75
85
|
.home-surface-screen__actions :deep(.v-btn) {
|
|
76
86
|
min-height: 48px;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expect, test } from "@playwright/test";
|
|
2
2
|
import { DEFAULT_VIEWPORTS, runAdaptiveShellSmokeCase } from "@jskit-ai/shell-web/test/adaptiveShellSmoke";
|
|
3
3
|
|
|
4
|
-
test.describe("
|
|
4
|
+
test.describe("adaptive shell smoke", () => {
|
|
5
5
|
for (const viewport of DEFAULT_VIEWPORTS) {
|
|
6
6
|
test(`${viewport.name} layout has reachable navigation and no horizontal overflow`, async ({ page }) => {
|
|
7
7
|
await runAdaptiveShellSmokeCase({ page, expect, viewport });
|