@synopackageland/ui 0.23.2 → 0.23.4

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.
@@ -499,6 +499,10 @@ the page, `--ui-chrome-height` tall (44px, plus a 1px rule):
499
499
  - **The drawer's head:** the App's icon and name, then the close button. The
500
500
  name takes the row up to the close button and is cut with "…" only when it
501
501
  is longer than that.
502
+ - **The drawer's focus:** opened with Enter or Space, focus lands on the
503
+ close button with its ring; opened by a tap or click, on the drawer panel,
504
+ which draws no ring. Tab still moves through the drawer only, and closing it
505
+ gives focus back to what opened it.
502
506
  - **Actions:** first the page's own actions, then `headerActions`
503
507
  (DropdownMenu entries). A pick emits `headerAction` with the key.
504
508
  - **One "…".** The bar never shows two overflow buttons. While the page's own
@@ -608,12 +612,16 @@ change: the same slot moves.
608
612
  row is never under the FAB; there is no room while no FAB is drawn.
609
613
  - A fill page (its content scrolls itself: `PageContent height="fill"`, or an
610
614
  App shell that keeps the PageContent from scrolling; PageContent marks it
611
- `data-ui-page-fills`) keeps that room only while the FAB is in view. While
612
- the FAB is hidden on scroll or by the keyboard, the content's own scroller
613
- takes the room down to the bars' edge, together with the room the hidden
614
- bars give back, so no blank band is left under it. A page that scrolls as a
615
- whole keeps the room at its end, so its length never changes under the
616
- finger.
615
+ `data-ui-page-fills`) puts that room at the end of its own scroller instead.
616
+ PageContent marks the vertical scroller in its body that reaches its bottom
617
+ `data-ui-page-scroller` (its own bottom padding is kept in
618
+ `--ui-page-scroller-pad`) and the page `data-ui-page-scroller-room`; the
619
+ scroller then runs down to the tab bar or the bottom accessory, its rows
620
+ pass under the FAB, which covers only its own circle, and the last row can
621
+ be scrolled above it. No blank band is left under the list, with the FAB
622
+ in view or hidden. A fill page whose scroller is not found keeps the room
623
+ under its content. A page that scrolls as a whole keeps the room at its
624
+ end, so its length never changes under the finger.
617
625
  - A toast sits 8px above the FAB while the FAB is shown, and back at its own
618
626
  place while the FAB is hidden on scroll or by the keyboard, and steps aside
619
627
  (fades out) while the speed dial is open; it moves with the bars (`--ui-motion-bars`, at once with reduced motion). A page without a FAB,
@@ -682,8 +690,39 @@ no offset of its own.
682
690
  of its scroller (the covered padding, a sticky `PageHeader` that keeps a row
683
691
  of its own, and the phone's tabs strip). Every element in the page body gets
684
692
  it as `scroll-margin-top`, so `scrollIntoView`, a `#hash` link and focus
685
- land below the stuck rows. A row an App makes sticky under them uses
686
- `top: var(--ui-sticky-top-offset)` instead of a hardcoded 44 or 96px.
693
+ land below the stuck rows.
694
+
695
+ **An App's own sticky row: `data-ui-sticky`.** A row the App keeps at the
696
+ top of its page (a sticky audio player on a detail page, a filter row) is
697
+ marked `data-ui-sticky`, anywhere in the PageContent's body. PageContent
698
+ measures it (ResizeObserver, again when rows mount, unmount or change size)
699
+ and, while it sticks, adds its height to `--ui-sticky-top-offset`, so
700
+ `scrollToStart`, `scrollIntoViewWithinScroller`, a `#hash` link and focus
701
+ land below it too. The UI also sticks it: `position: sticky`, `top` right
702
+ under what sticks above it (`--ui-sticky-row-top`: the covered padding, a
703
+ sticky `PageHeader`, the phone's tabs strip and earlier rows; several rows
704
+ stack in document order), `z-index: 2` and the page header's background.
705
+ An App sets no `top` of its own and measures nothing.
706
+
707
+ ```vue
708
+ <PageContent>
709
+ <PageHeader :title="meeting.title" back @back="goBack" />
710
+ <div class="player" data-ui-sticky><AudioPlayer :src="meeting.audio" /></div>
711
+ <p v-for="line in transcript" :id="line.id" :key="line.id">{{ line.text }}</p>
712
+ </PageContent>
713
+ <!-- scrollToStart(document.getElementById(line.id)) lands the line under the player -->
714
+ ```
715
+
716
+ - A row is counted while its computed `position` is `sticky`: an App that
717
+ lets it scroll at some widths (`position: static` in a media query) drops
718
+ it from the offset there. A row in a nested PageContent counts for that
719
+ page only.
720
+ - The offset is the page's, not per element: content above a sticky row in
721
+ the middle of a page also stops that much lower (never under it).
722
+ - The rule has one attribute's specificity, so an App's own class wins for
723
+ `position`, `background` or `z-index`.
724
+ - Before 0.23.4 an App measured its row and added it to the token by hand;
725
+ remove that code when it marks the row instead.
687
726
 
688
727
  **The end of a page: `--ui-page-end-space`.** The room after a page's last
689
728
  row, 24px. While the bars are hidden on a fill page (`data-ui-page-fills`)
@@ -700,6 +739,20 @@ the default, or `start`), honours `scroll-margin-top` / `-bottom` (so the
700
739
  sticky offset above applies) and moves at once under reduced motion.
701
740
  `scrollToStart(el)` is the `block: 'start'` case.
702
741
 
742
+ `nearestScroller` skips an element whose content is not taller than it
743
+ (`scrollHeight > clientHeight`), as it has nothing to scroll. jsdom lays
744
+ nothing out (both are 0), so a unit test of code that calls these helpers
745
+ gives its scroller geometry, or the helpers fall back to the document:
746
+
747
+ ```ts
748
+ const list = document.createElement('div')
749
+ list.style.overflowY = 'auto'
750
+ Object.defineProperty(list, 'clientHeight', { value: 400 })
751
+ Object.defineProperty(list, 'scrollHeight', { value: 1200 })
752
+ list.scrollBy = vi.fn()
753
+ vi.spyOn(list, 'getBoundingClientRect').mockReturnValue(new DOMRect(0, 0, 390, 400))
754
+ ```
755
+
703
756
  ```ts
704
757
  import { scrollToStart, scrollIntoViewWithinScroller } from '@synopackageland/ui'
705
758
  scrollToStart(sectionHeading)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/ui",
3
- "version": "0.23.2",
3
+ "version": "0.23.4",
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,63 @@
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:edges": "node scripts/check-edges.mjs",
89
+ "check:data-grid": "node scripts/check-data-grid.mjs",
90
+ "check:truncation": "node scripts/check-truncation.mjs",
91
+ "check:link": "node scripts/check-link.mjs",
92
+ "check:text-select": "node scripts/check-text-select.mjs",
93
+ "check:date-picker": "node scripts/check-date-picker.mjs",
94
+ "check:full-page": "node scripts/check-full-page.mjs",
95
+ "check:short-viewport": "node scripts/check-short-viewport.mjs",
96
+ "check:phone-layout": "node scripts/check-phone-layout.mjs",
97
+ "check:text-zoom": "node scripts/check-text-zoom.mjs",
98
+ "check:focus-restore": "node scripts/check-focus-restore.mjs",
99
+ "check:detail-surface": "node scripts/check-detail-surface.mjs",
100
+ "check:internal": "node --test scripts/check-internal-content.test.mjs scripts/check-npm-metadata.test.mjs && node scripts/check-internal-content.mjs --repo .",
101
+ "check:npm-metadata": "node scripts/check-npm-metadata.mjs",
102
+ "check:package": "node scripts/check-package-content.mjs",
103
+ "check:public-api-consumer": "node scripts/check-public-api-consumer.mjs",
104
+ "notices:update": "node scripts/third-party-notices.mjs --write",
105
+ "notices:check": "node scripts/third-party-notices.mjs --check",
106
+ "check": "bash scripts/docker-check.sh \"npm run gates\"",
107
+ "check:fast": "bash scripts/docker-check.sh \"npm run gates\"",
108
+ "check:local-browser": "node scripts/app-local-browser.mjs",
109
+ "check:infotip": "node scripts/check-infotip.mjs",
110
+ "release:stage": "node scripts/stage-release.mjs",
111
+ "check:polish": "bash scripts/docker-check.sh --build --out .polish-shots 'node scripts/check-polish.mjs'",
112
+ "check:acceptance": "node scripts/check-acceptance.mjs",
113
+ "check:palette": "node scripts/check-palette.mjs",
114
+ "gates": "node scripts/gates.mjs",
115
+ "gates:full": "node scripts/gates.mjs --full",
116
+ "check:layout": "node scripts/check-layout.mjs",
117
+ "release:smoke": "node scripts/release-smoke.mjs",
118
+ "check:browser-install": "playwright install chromium"
119
+ },
63
120
  "peerDependencies": {
64
121
  "vue": "^3.5.0"
65
122
  },
@@ -110,6 +167,13 @@
110
167
  "engines": {
111
168
  "node": ">=20"
112
169
  },
170
+ "packageManager": "pnpm@10.33.2",
171
+ "pnpm": {
172
+ "onlyBuiltDependencies": [
173
+ "esbuild",
174
+ "vue-demi"
175
+ ]
176
+ },
113
177
  "config": {
114
178
  "bundledRuntime": {
115
179
  "@tanstack/vue-virtual": "3.13.39",
@@ -117,62 +181,5 @@
117
181
  "reka-ui": "2.11.0"
118
182
  }
119
183
  },
120
- "homepage": "https://www.varvis.me/docs/",
121
- "scripts": {
122
- "check:docs": "node --test scripts/check-doc-versions.test.mjs && node scripts/check-doc-versions.mjs",
123
- "dev": "vite build --watch",
124
- "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",
125
- "lint": "eslint .",
126
- "typecheck": "vue-tsc --noEmit -p tsconfig.json",
127
- "test": "vitest run",
128
- "test:watch": "vitest",
129
- "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}",
130
- "story": "histoire dev",
131
- "story:build": "histoire build",
132
- "check:host": "node scripts/dsm-host-shots.mjs",
133
- "check:switch": "node scripts/check-switch.mjs",
134
- "check:tabs": "node scripts/check-tabs.mjs",
135
- "check:mobile": "node scripts/check-mobile-overflow.mjs",
136
- "check:ui-patch": "node scripts/check-ui-patch.mjs",
137
- "check:narrow": "node scripts/check-narrow-controls.mjs",
138
- "check:drawer-form": "node scripts/check-drawer-form.mjs",
139
- "check:responsive": "node scripts/check-responsive.mjs",
140
- "check:adaptive": "node scripts/check-adaptive.mjs",
141
- "check:sidebar-focus": "node scripts/check-sidebar-focus.mjs",
142
- "check:json-render": "node scripts/check-json-render.mjs",
143
- "check:motion": "node scripts/check-motion.mjs",
144
- "check:topology": "node scripts/check-topology.mjs",
145
- "check:wizard": "node scripts/check-wizard.mjs",
146
- "check:edges": "node scripts/check-edges.mjs",
147
- "check:data-grid": "node scripts/check-data-grid.mjs",
148
- "check:truncation": "node scripts/check-truncation.mjs",
149
- "check:link": "node scripts/check-link.mjs",
150
- "check:text-select": "node scripts/check-text-select.mjs",
151
- "check:date-picker": "node scripts/check-date-picker.mjs",
152
- "check:full-page": "node scripts/check-full-page.mjs",
153
- "check:short-viewport": "node scripts/check-short-viewport.mjs",
154
- "check:phone-layout": "node scripts/check-phone-layout.mjs",
155
- "check:text-zoom": "node scripts/check-text-zoom.mjs",
156
- "check:focus-restore": "node scripts/check-focus-restore.mjs",
157
- "check:detail-surface": "node scripts/check-detail-surface.mjs",
158
- "check:internal": "node --test scripts/check-internal-content.test.mjs scripts/check-npm-metadata.test.mjs && node scripts/check-internal-content.mjs --repo .",
159
- "check:npm-metadata": "node scripts/check-npm-metadata.mjs",
160
- "check:package": "node scripts/check-package-content.mjs",
161
- "check:public-api-consumer": "node scripts/check-public-api-consumer.mjs",
162
- "notices:update": "node scripts/third-party-notices.mjs --write",
163
- "notices:check": "node scripts/third-party-notices.mjs --check",
164
- "check": "bash scripts/docker-check.sh \"npm run gates\"",
165
- "check:fast": "bash scripts/docker-check.sh \"npm run gates\"",
166
- "check:local-browser": "node scripts/app-local-browser.mjs",
167
- "check:infotip": "node scripts/check-infotip.mjs",
168
- "release:stage": "node scripts/stage-release.mjs",
169
- "check:polish": "bash scripts/docker-check.sh --build --out .polish-shots 'node scripts/check-polish.mjs'",
170
- "check:acceptance": "node scripts/check-acceptance.mjs",
171
- "check:palette": "node scripts/check-palette.mjs",
172
- "gates": "node scripts/gates.mjs",
173
- "gates:full": "node scripts/gates.mjs --full",
174
- "check:layout": "node scripts/check-layout.mjs",
175
- "release:smoke": "node scripts/release-smoke.mjs",
176
- "check:browser-install": "playwright install chromium"
177
- }
178
- }
184
+ "homepage": "https://www.varvis.me/docs/"
185
+ }