@synopackageland/ui 0.25.10 → 0.25.12
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/CHANGELOG.md +24 -0
- package/dist/components/app/app-layout/BackArrowIcon.vue.d.ts +8 -0
- package/dist/components/app/app-layout/MovableActions.d.ts +35 -0
- package/dist/components/app/app-layout/ShellBackButton.vue.d.ts +3 -0
- package/dist/components/app/app-layout/back-arrow.json.d.ts +9 -0
- package/dist/components/app/app-layout/shellBack.d.ts +23 -0
- package/dist/components/app/page-header/PageHeader.vue.d.ts +1 -3
- package/dist/components/app/page-toolbar/PageToolbar.vue.d.ts +3 -3
- package/dist/components/app/section-tabs/SectionTabs.vue.d.ts +4 -4
- package/dist/grid.js +9 -0
- package/dist/i18n/text.d.ts +1 -0
- package/dist/index.js +10484 -10323
- package/dist/json-preview/preview.js +7820 -7665
- package/dist/lib/nativeShell.d.ts +8 -0
- package/dist/reka-runtime.json +1 -1
- package/dist/theme.css +1 -1
- package/dist/themes/dsm7-embedded-theme.css +1 -1
- package/dist/themes/dsm7-embedded.css +1 -1
- package/dist/themes/dsm7.css +1 -1
- package/docs/adaptive-layout.md +12 -0
- package/docs/button-policy.md +1 -1
- package/docs/layout-rules.md +1 -1
- package/docs/mobile-native.md +24 -1
- package/package.json +97 -1
package/docs/adaptive-layout.md
CHANGED
|
@@ -141,6 +141,18 @@ 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
|
|
154
|
+
does, so change both copies together.
|
|
155
|
+
|
|
144
156
|
`node scripts/check-keyboard.mjs [out-dir]` (after `pnpm build`) checks all of
|
|
145
157
|
this in Chromium at 390 and 768 with touch, with Android emulated by a
|
|
146
158
|
viewport resize and iOS by a stand-in visual viewport. A real-device pass on
|
package/docs/button-policy.md
CHANGED
|
@@ -24,7 +24,7 @@ are in [dsm-native-metrics.md](dsm-native-metrics.md).
|
|
|
24
24
|
| Form or window footer | `FormActions`, `AppActionBar`, `Footbar`, `Panel` `#fbar` | capsule | Reset `secondary`, then Apply `primary` |
|
|
25
25
|
| Notification | `Notification` `confirm` / `cancel` | capsule | Cancel `secondary`, then the action `primary` |
|
|
26
26
|
| Toolbar | `AppToolbar`, a row above a list | tool | `secondary`; `SplitButton` for Create and its variants |
|
|
27
|
-
| Page header | `PageHeader` `#actions` | tool |
|
|
27
|
+
| Page header | `PageHeader` `#actions`, the SDK `AppShell`'s `#actions` | tool | `secondary`, only the page's own actions (Add); no refresh |
|
|
28
28
|
| Tab row | `SectionTabs` `#actions` | tool | `secondary`, for the shown section (Export, Check again) |
|
|
29
29
|
| Section or card | `SettingsSection` / `Card` body, `#actions`, `#footer` | tool | `secondary`; a Save / Cancel row there goes in `FormActions` |
|
|
30
30
|
| Beside a field | `InputGroup` | tool | `secondary` (Open, Copy, Test) |
|
package/docs/layout-rules.md
CHANGED
|
@@ -19,7 +19,7 @@ These rules keep pages built from `@synopackageland/ui` consistent. The componen
|
|
|
19
19
|
- Buttons that belong together sit in one row with an 8px gap: `FormActions` in a form, the `#footer` slot in a section or card.
|
|
20
20
|
- Only the bar that closes a dialog or form draws capsule `action` buttons, without a `kind`: `FormActions`, `Footbar`, `AppActionBar`, a `Notification`'s actions, and the footers of `Dialog`, `Wizard`, `Sheet` and `Panel` (`#fbar`), with the main action last. `kind="tool"` opts one button out. A `SettingsSection` or `Card` footer, header actions and content stay `tool` buttons; put a section's Save / Cancel in `FormActions`.
|
|
21
21
|
- A settings tab's Reset / Apply go in `SettingsPage`'s `#footer`: it stays at the bottom over a divider while only the sections scroll. Do not write your own sticky footer.
|
|
22
|
-
-
|
|
22
|
+
- A page's header actions (the SDK `AppShell`'s `#actions`, or `PageHeader` `#actions` where a page draws one) hold only the page's own actions, such as Add. There is no page-wide refresh: a page reads its data again on `ctx.reopen` and whenever it is shown, and a failed read puts Retry next to its error. The SDK `AppShell` draws no bar above the page while its `#actions` is empty.
|
|
23
23
|
- A disabled primary button keeps readable text. Put the reason next to it, such as "Enter the password to confirm."
|
|
24
24
|
- Danger actions sit apart from the rest: the explanation comes first, then the button, or a confirm dialog.
|
|
25
25
|
- Return the promise from a `Button` or `IconButton` click handler (`@click="save"` with an `async save`): the button shows a spinner, keeps its width and ignores further clicks until the promise settles. Use the `loading` prop only for work the button did not start.
|
package/docs/mobile-native.md
CHANGED
|
@@ -42,7 +42,7 @@ the commit footer behave as before.
|
|
|
42
42
|
| `--ui-radius-md` / `-lg` (and the 0.23.9 roles on them) | 4 / 6 | 12 / 14: md rounds the control, container and popover roles (fields, tool buttons, inset blocks, menus), lg the panel and nav roles |
|
|
43
43
|
| `--ui-radius-dialog` / `-window` / `-sheet` | 8 / 8 / 12 | 24 |
|
|
44
44
|
| Primary, danger and secondary buttons | capsule (action) or 4px (tool) | capsule; a primary's fill is accent step 10 (`#0075db`, 4.6:1 with white) |
|
|
45
|
-
| Segmented control | accent pill on a framed track, equal columns | a pill in the primary button's fill (accent step 10, `#0075db`, with the accent's contrast colour, white: 4.6:1, light and dark) on a frameless mist track; 6px sides; up to
|
|
45
|
+
| Segmented control | accent pill on a framed track, equal columns | a pill in the primary button's fill (accent step 10, `#0075db`, with the accent's contrast colour, white: 4.6:1, light and dark) on a frameless mist track; 6px sides; up to four segments stay equal columns but one whose label is wider than its share grows to it, so a label is not cut; labels too wide together scroll the track sideways (`check:phone-layout` checks it) |
|
|
46
46
|
| Phone bar | white with a hairline | the page's colour, no hairline, 17px bold title, round pressed tint |
|
|
47
47
|
| Tab bar | full-width white row with a top rule | a floating white pill inset 16px, 8px above the bottom (`--ui-tab-bar-float`); the current tab's icon is white on a round pad in the primary's fill (accent step 10); a tab with a label and no icon takes accent step 10 on its label over the mist pad |
|
|
48
48
|
| `--ui-text-muted` | 40% grey (2:1) | 80% (4.8:1 on the mist; dark 62%) |
|
|
@@ -68,6 +68,18 @@ Numeric preset rows are at least 44px tall on touch. The rich text toolbar
|
|
|
68
68
|
counts its 44px touch buttons when deciding which tools fit; the rest move
|
|
69
69
|
into the existing More menu.
|
|
70
70
|
|
|
71
|
+
On a touch phone (`pointer: coarse`) the UI draws no `::-webkit-scrollbar`:
|
|
72
|
+
Chromium, Android included, turns any styled webkit bar into a classic one
|
|
73
|
+
that takes its width from the scroller, which left the right margin 10px
|
|
74
|
+
short of the left. Scrollers keep the browser's overlay bar, and a Select or
|
|
75
|
+
Combobox list a thin one. A natural-height page chain (`flex: 0 0 auto`)
|
|
76
|
+
keeps the full width of a flex row such as `ListDetail` (`inline-size:
|
|
77
|
+
stretch`), so a list is never shrunk to its content. A `SearchField`
|
|
78
|
+
(`data-ui-search-field`), alone or in a wrapper holding only it, grows to its
|
|
79
|
+
row and drops a fixed basis or `max-width`. A DataGrid group row's
|
|
80
|
+
`#group-title` wraps instead of running over the row's links. A page's
|
|
81
|
+
toolbar and header actions wrap within the page.
|
|
82
|
+
|
|
71
83
|
`pnpm check:mobile` checks the gallery at both phone and tablet sizes. It is
|
|
72
84
|
a blocking step of `gates:full`; the basic gate selection stays the same.
|
|
73
85
|
Any remaining audit exceptions are bounded in
|
|
@@ -396,6 +408,12 @@ context menu for now; it becomes a phone sheet once pickers move to sheets.
|
|
|
396
408
|
The keyboard depends on each field's type, so these are component defaults,
|
|
397
409
|
not tokens.
|
|
398
410
|
|
|
411
|
+
A press on a text field (an `input` that takes text, a `textarea`, editable
|
|
412
|
+
content) is left to the browser's own focus. Android hides the soft keyboard
|
|
413
|
+
it just raised when script focuses the field during the press, so the app
|
|
414
|
+
root's focus handling focuses only buttons, links and other controls on
|
|
415
|
+
pointerdown.
|
|
416
|
+
|
|
399
417
|
### Keyboard hints by type
|
|
400
418
|
|
|
401
419
|
`Input` sets these from its `type`, and `SearchField` from `search`. An
|
|
@@ -752,6 +770,11 @@ change: the same slot moves.
|
|
|
752
770
|
name too long for the screen ends in an ellipsis inside the pill.
|
|
753
771
|
- Rare or destructive items belong in `headerActions` ("…" in the bar), not
|
|
754
772
|
in the page actions.
|
|
773
|
+
- Only actions float. While the actions hold anything else (a status badge, a
|
|
774
|
+
count, a date, a field), also content that arrives later through an App's
|
|
775
|
+
own teleport, they stay in the page's own row, which wraps, and no FAB is
|
|
776
|
+
drawn, so nothing floats over the page's rows. Put a page's status in the
|
|
777
|
+
page's meta (the SDK `PageInfo`), not in its actions.
|
|
755
778
|
- `phone-actions` on `AppLayout`, and on a `PageHeader`, `AppToolbar` or
|
|
756
779
|
`PushTransition` for one page: `fab` (default), `bar` (icons in the bar) or `inline` (the page's own header row).
|
|
757
780
|
- `PageFab` picks the FAB explicitly: `<PageFab><Button variant="primary">…</Button></PageFab>`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/ui",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.12",
|
|
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",
|