@synopackageland/ui 0.25.15 → 0.25.16

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.
@@ -1,8 +1,40 @@
1
- /** Whether this page runs in the phone app and may go back to its App list. */
2
- export declare function canCloseToShell(): boolean;
3
1
  /**
4
- * Asks the phone app to go back to its App list. Call it from a tap: the app
2
+ * The Package Land launcher (the "shell") as seen from an App page in it. Its
3
+ * Home request, `{ v: 1, type: 'close' }`, takes the user back to the
4
+ * launcher's home. Two shells offer it:
5
+ *
6
+ * - The phone app injects `window.SynoPkgNative` (SynoPkgNative v1) into a
7
+ * registered App's main frame only; its optional `features` lists the
8
+ * requests it understands beyond the v1 baseline, `close` among them. The
9
+ * request goes through the bridge's `post`.
10
+ * - The browser launcher opens each App in a same-origin frame named
11
+ * `synopkg-shell:1:<features>` (comma-separated, e.g. `synopkg-shell:1:close`).
12
+ * The request is posted to the parent window at this page's own origin.
13
+ *
14
+ * In a plain browser tab, a DSM window or any other frame there is no shell
15
+ * and nothing here offers anything. The shell honors a request only right
16
+ * after a tap, so call it from a click.
17
+ */
18
+ type CloseMessage = {
19
+ v: 1;
20
+ type: 'close';
21
+ };
22
+ type ShellBridge = {
23
+ protocol: number;
24
+ features?: readonly unknown[];
25
+ post(message: CloseMessage): void;
26
+ };
27
+ type ShellWindow = Pick<Window, 'name' | 'parent' | 'top' | 'location'> & {
28
+ SynoPkgNative?: Partial<ShellBridge>;
29
+ };
30
+ /** The name the browser launcher gives an App's frame, and the features it lists. */
31
+ export declare const SHELL_FRAME_PREFIX = "synopkg-shell:1:";
32
+ /** Whether this page runs in the launcher (phone app or browser) and may go back to its home. */
33
+ export declare function canCloseToShell(view?: ShellWindow | undefined): boolean;
34
+ /**
35
+ * Asks the launcher to go back to its home. Call it from a tap: the launcher
5
36
  * ignores a request without a recent user gesture. Returns false when there is
6
- * no phone app to ask.
37
+ * no launcher to ask.
7
38
  */
8
- export declare function closeToShell(): boolean;
39
+ export declare function closeToShell(view?: ShellWindow | undefined): boolean;
40
+ export {};
@@ -3,7 +3,7 @@
3
3
  "version": "2.11.0",
4
4
  "delivery": "bundled-patched-esm",
5
5
  "patchManifestSha256": "9c5b9c9a162fa584b4695a683368a4484b3ac6e70177fd063b77aa618c051627",
6
- "bundleSha256": "abe34cf2578a7517d653b2d5efb3338ecce0562d845477aefc6158a18df763b1",
6
+ "bundleSha256": "0613c4649ba3a597c7c6d972e93541034089c6176d953a0a7d2426dc0fe6165a",
7
7
  "sourceHashes": {
8
8
  "shared/useBodyScrollLock.js": "287bfb604318c4202769e4b5191896eaf0e52a952e1de898967cbe09467fcfda",
9
9
  "DismissableLayer/DismissableLayer.js": "3c8d248f0a32e01f89ca1f6202b1bb691bf5d0e4012a92535e161c35e69cdc32",
@@ -141,16 +141,46 @@ state keys are copied through). The Android back button or the iOS edge swipe
141
141
  calls `close` for the top surface only; closing by code removes the entry.
142
142
  Pass `enabled: false` where the surface is a popover or inside a DSM window.
143
143
 
144
- Inside the Package Land phone app, a root page also gets Back to the App list.
145
- The app's bridge (`window.SynoPkgNative`, protocol 1) lists `close` in its
146
- `features`; AppLayout then leads the phone bar with the shared back arrow, and
147
- a tap posts `{ v: 1, type: 'close' }`, which the app honors only right after a
148
- tap. A browser, a sub-page (which has its own Back) and anything wider than a
149
- phone never show it. When the page hides the bar (`phone-bar-title="none"`
150
- without a menu), the first `PageToolbar` or `SectionTabs` row on the page holds
151
- the button at its start, so it costs no row; with no such row the bar is drawn
152
- for it. The arrow is `app-layout/back-arrow.json`, a byte copy of the phone
153
- app's drawing; `tests/ShellBack.test.ts` pins its SHA-256, as the phone app
144
+ Inside the Package Land launcher, every page leads with Home, sub-pages
145
+ included: Home goes back to the launcher's home, as the launcher's own bars do.
146
+ Stepping back is the system Back's job (Android's back button, the browser's
147
+ back or swipe). The page finds the launcher in one of two ways:
148
+
149
+ - **Phone app.** Its bridge (`window.SynoPkgNative`, protocol 1) lists `close`
150
+ in its `features`. A tap posts `{ v: 1, type: 'close' }` through the bridge.
151
+ - **Browser launcher.** It opens the App in a same-origin frame named
152
+ `synopkg-shell:1:close` (`SHELL_FRAME_PREFIX` followed by its features,
153
+ comma-separated). A tap posts the same message to the parent window, at the
154
+ page's own origin.
155
+
156
+ Either launcher honors the request only right after a tap. A plain browser
157
+ tab, a DSM window and anything wider than a phone never show Home; there a
158
+ sub-page keeps its Back arrow.
159
+
160
+ In the launcher, a sub-page has no Back button, so each one is a history entry
161
+ of the App (`useBackDismiss`):
162
+ - the layout's `back`, or a `PageHeader` with `back`, takes one entry while it
163
+ is shown;
164
+ - a `PushTransition` page already owns one.
165
+
166
+ The system Back pops that entry and runs the sub-page's back (`back`, or
167
+ `pop`). The launcher goes through an App's own entries before it leaves the
168
+ App: in the browser, the frame's entries come first in the tab's history; on
169
+ Android, the WebView's history comes first. A sub-page the App closes itself
170
+ takes its entry back off.
171
+
172
+ An App whose sub-pages are router addresses still works: the Back pops the
173
+ layout's entry, and the App's back handler then goes back through the
174
+ router.
175
+
176
+ AppLayout leads the phone bar with a 44px home icon; on a sub-page it comes
177
+ before the sub-page's title. When a root page hides the
178
+ bar (`phone-bar-title="none"` without a menu), the first `PageToolbar` or
179
+ `SectionTabs` row on the page holds the button at its start, so it costs no
180
+ row. With no such row the bar is drawn for it.
181
+
182
+ A sub-page's Back draws `app-layout/back-arrow.json`, a byte copy of the phone
183
+ app's drawing. `tests/ShellBack.test.ts` pins its SHA-256, as the phone app
154
184
  does, so change both copies together.
155
185
 
156
186
  `node scripts/check-keyboard.mjs [out-dir]` (after `pnpm build`) checks all of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/ui",
3
- "version": "0.25.15",
3
+ "version": "0.25.16",
4
4
  "description": "Shared Vue 3 UI component library with a DSM 7 inspired application theme",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -60,6 +60,67 @@
60
60
  "./themes/dsm7-embedded-reset.css": "./dist/themes/dsm7-embedded-reset.css",
61
61
  "./themes/dsm7-embedded-theme.css": "./dist/themes/dsm7-embedded-theme.css"
62
62
  },
63
+ "scripts": {
64
+ "check:docs": "node --test scripts/check-doc-versions.test.mjs && node scripts/check-doc-versions.mjs",
65
+ "dev": "vite build --watch",
66
+ "build": "vite build && vite build --mode json && vite build --mode rich-text && vite build --mode grid && vite build --mode cli && vite build --mode preview && vite build --mode embedded && node scripts/postbuild.mjs",
67
+ "lint": "eslint .",
68
+ "typecheck": "vue-tsc --noEmit -p tsconfig.json",
69
+ "test": "vitest run",
70
+ "test:watch": "vitest",
71
+ "test:changed": "echo \"test:changed skips the tests the changes since ${SYNOPKGLAND_GATE_BASE:-origin/master} do not reach (vitest --changed); pnpm check runs them all\" && vitest run --changed ${SYNOPKGLAND_GATE_BASE:-origin/master}",
72
+ "story": "histoire dev",
73
+ "story:build": "histoire build",
74
+ "check:host": "node scripts/dsm-host-shots.mjs",
75
+ "check:switch": "node scripts/check-switch.mjs",
76
+ "check:tabs": "node scripts/check-tabs.mjs",
77
+ "check:mobile": "node scripts/check-mobile-overflow.mjs",
78
+ "check:ui-patch": "node scripts/check-ui-patch.mjs",
79
+ "check:narrow": "node scripts/check-narrow-controls.mjs",
80
+ "check:drawer-form": "node scripts/check-drawer-form.mjs",
81
+ "check:responsive": "node scripts/check-responsive.mjs",
82
+ "check:adaptive": "node scripts/check-adaptive.mjs",
83
+ "check:sidebar-focus": "node scripts/check-sidebar-focus.mjs",
84
+ "check:json-render": "node scripts/check-json-render.mjs",
85
+ "check:motion": "node scripts/check-motion.mjs",
86
+ "check:topology": "node scripts/check-topology.mjs",
87
+ "check:wizard": "node scripts/check-wizard.mjs",
88
+ "check:press": "node scripts/check-press.mjs",
89
+ "check:edges": "node scripts/check-edges.mjs",
90
+ "check:data-grid": "node scripts/check-data-grid.mjs",
91
+ "check:truncation": "node scripts/check-truncation.mjs",
92
+ "check:link": "node scripts/check-link.mjs",
93
+ "check:text-select": "node scripts/check-text-select.mjs",
94
+ "check:date-picker": "node scripts/check-date-picker.mjs",
95
+ "check:full-page": "node scripts/check-full-page.mjs",
96
+ "check:short-viewport": "node scripts/check-short-viewport.mjs",
97
+ "check:phone-layout": "node scripts/check-phone-layout.mjs",
98
+ "check:phone-bars": "node scripts/check-phone-bars.mjs",
99
+ "check:phone-fill": "node scripts/check-phone-fill.mjs",
100
+ "check:text-zoom": "node scripts/check-text-zoom.mjs",
101
+ "check:focus-restore": "node scripts/check-focus-restore.mjs",
102
+ "check:detail-surface": "node scripts/check-detail-surface.mjs",
103
+ "check:internal": "node --test scripts/check-internal-content.test.mjs scripts/check-npm-metadata.test.mjs && node scripts/check-internal-content.mjs --repo .",
104
+ "check:npm-metadata": "node scripts/check-npm-metadata.mjs",
105
+ "check:package": "node scripts/check-package-content.mjs",
106
+ "trace:restyle": "node scripts/trace-restyle.mjs",
107
+ "check:public-api-consumer": "node scripts/check-public-api-consumer.mjs",
108
+ "notices:update": "node scripts/third-party-notices.mjs --write",
109
+ "notices:check": "node scripts/third-party-notices.mjs --check",
110
+ "check": "bash scripts/docker-check.sh \"npm run gates\"",
111
+ "check:fast": "bash scripts/docker-check.sh \"npm run gates\"",
112
+ "check:local-browser": "node scripts/app-local-browser.mjs",
113
+ "check:infotip": "node scripts/check-infotip.mjs",
114
+ "release:stage": "node scripts/stage-release.mjs",
115
+ "check:polish": "bash scripts/docker-check.sh --build --out .polish-shots 'node scripts/check-polish.mjs'",
116
+ "check:acceptance": "node scripts/check-acceptance.mjs",
117
+ "check:palette": "node scripts/check-palette.mjs",
118
+ "gates": "node scripts/gates.mjs",
119
+ "gates:full": "node scripts/gates.mjs --full",
120
+ "check:layout": "node scripts/check-layout.mjs",
121
+ "release:smoke": "node scripts/release-smoke.mjs",
122
+ "check:browser-install": "playwright install chromium webkit"
123
+ },
63
124
  "peerDependencies": {
64
125
  "vue": "^3.5.0"
65
126
  },
@@ -79,9 +140,44 @@
79
140
  "@tiptap/vue-3": "3.32.1",
80
141
  "zod": "^4.6.5"
81
142
  },
143
+ "devDependencies": {
144
+ "@eslint/js": "10.0.1",
145
+ "@histoire/plugin-vue": "1.0.0-beta.1",
146
+ "@tailwindcss/vite": "4.3.3",
147
+ "@tanstack/vue-virtual": "3.13.39",
148
+ "@vitejs/plugin-vue": "6.0.9",
149
+ "@vue/test-utils": "2.5.1",
150
+ "@vueuse/core": "14.4.0",
151
+ "eslint": "10.11.0",
152
+ "eslint-plugin-vue": "10.11.1",
153
+ "flexsearch": "0.8.212",
154
+ "globals": "17.12.0",
155
+ "histoire": "1.0.0-beta.1",
156
+ "jsdom": "30.1.1",
157
+ "playwright": "1.58.2",
158
+ "reka-ui": "2.11.0",
159
+ "tailwindcss": "4.3.3",
160
+ "typescript": "5.9.3",
161
+ "typescript-eslint": "8.71.0",
162
+ "vite": "7.3.6",
163
+ "vite-plugin-dts": "5.1.1",
164
+ "vitest": "5.0.2",
165
+ "vscode-oniguruma": "2.0.1",
166
+ "vscode-textmate": "9.3.2",
167
+ "vue": "3.5.43",
168
+ "vue-eslint-parser": "10.4.1",
169
+ "vue-tsc": "3.3.11"
170
+ },
82
171
  "engines": {
83
172
  "node": ">=20"
84
173
  },
174
+ "packageManager": "pnpm@10.33.2",
175
+ "pnpm": {
176
+ "onlyBuiltDependencies": [
177
+ "esbuild",
178
+ "vue-demi"
179
+ ]
180
+ },
85
181
  "config": {
86
182
  "bundledRuntime": {
87
183
  "@tanstack/vue-virtual": "3.13.39",