@synopackageland/ui 0.23.4 → 0.23.6

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.
@@ -2,6 +2,25 @@
2
2
 
3
3
  How the UI SDK behaves on a phone (390×844) and a touch tablet (768×1024).
4
4
 
5
+ ## Phone behaviour contract
6
+
7
+ What every App gets on a touch phone, from the UI SDK, with no code of its
8
+ own. An App does not override these; a fix to one is made here, for every
9
+ App. Each line links to its details below.
10
+
11
+ | Behaviour | The rule |
12
+ | --- | --- |
13
+ | FAB and speed dial | The page's one action is a 56px circle (`border-radius: 50%`) with its icon and elevation; two or more open from a 56px circle with `+` as labelled pills. 56px is Material 3's FAB size (56dp; M3's default FAB shape is a rounded square, the UI draws a circle) and clears iOS's 44pt minimum tap target. See [Page actions on a FAB](#native-phone-shell). |
14
+ | One compact top bar | One 44px row: Back, the menu button or the App icon, the title, at most two icons and one "…". No brand row, no second header row. |
15
+ | No tab heading on tab pages | A page of the tab bar draws no title, icon or brand in the bar (`phone-bar-title="none"`) and no heading of its own: the tab bar says where the user is. A sub-page keeps Back and its title. |
16
+ | Title on a tab page is opt-in | Showing a title on a tab page is the App's explicit choice: `phone-bar-title="auto"` on `AppLayout`, and the SDK AppShell's own opt-in (`phoneTitle`). |
17
+ | Hide on scroll | By `transform` only; the scroller keeps its size, position and padding and nothing writes `scrollTop`, so a momentum fling keeps going. Slow scrolls use distance hysteresis, flicks decide at once. See [Hide on scroll](#native-phone-shell) and [Gesture velocity](#gesture-velocity). |
18
+ | No horizontal pan | The page never pans sideways: the phone layout's content area and page scroller clip `overflow-x`, a `PageHeader`'s last action keeps its tap box inside the header, and `check:phone-layout` asserts `scrollWidth == clientWidth` for the document and the page's scrollers at 320, 360, 390 and 430px and in landscape (825x360, 753x279), also when the scroller is an App's own element in a fill page. An inner horizontal scroller (a table, a tab strip) still scrolls. |
19
+ | Bottom accessory | `#accessory` docks above the tab bar, lifts the FAB and toasts, and slides into the tab bar's place with the bars. |
20
+ | Sticky offsets | `--ui-sticky-top-offset` counts the covered padding, a sticky `PageHeader`, the tabs strip and every `data-ui-sticky` row, so scrolling to an element lands below them. A row in an App's own nested scroller (a side pane, a record pane) sticks below the sticky `PageHeader` and tabs strip in that scroller and counts only there. |
21
+ | No end space under docked bars | The room under the last row is constant (`--ui-page-end-space`, plus `--ui-bars-room` under docked bars); a fill page's list runs under the FAB and bars to the screen's bottom with no blank band, also when that list is an App's own element nested in the page. |
22
+ | Gesture velocity | One estimator and one set of thresholds for every gesture decision the UI makes. See [Gesture velocity](#gesture-velocity). |
23
+
5
24
  ## Width containment and the release gate
6
25
 
7
26
  Typography tables scroll horizontally within their parent, including a flex
@@ -78,7 +97,7 @@ control and grid sizes; it does not change the 16px field rule.
78
97
  | `--ui-tab-bar-height` | – | – | **48** | the tab bar's row, above `--ui-safe-bottom` |
79
98
  | `--ui-section-tab-height` | 44 | 44 | **40** | the drawn height of a phone's tabs strip (its tap box stays 44) |
80
99
  | `--ui-sticky-top-offset` | 0 | 0 | measured | what sticks at the top of a PageContent (see below) |
81
- | `--ui-page-end-space` | 24 | 24 | 24, the safe area while the bars are hidden on a fill page | room after a page's last row |
100
+ | `--ui-page-end-space` | 24 | 24 | 24 (constant: hiding the bars never changes it) | room after a page's last row |
82
101
  | `--ui-radius-sheet` (new) | 12 | 12 | 12 | top corners of a bottom sheet |
83
102
  | `--ui-safe-top/right/bottom/left` (new) | `env(safe-area-inset-*, 0px)` | same | same | notch and home indicator; non-zero only once the viewport meta has `viewport-fit=cover` |
84
103
  | `--ui-pressed` (new) | 8% of the text colour | same | same | the pressed tint |
@@ -188,6 +207,31 @@ own) keeps scrolling. An App that puts small controls flush with the edge of
188
207
  its own scroller, outside a `PageContent`, clips that content sideways the
189
208
  same way.
190
209
 
210
+ When an App shell makes the `PageContent` itself its page scroller
211
+ (`overflow-y: auto` on it, like the SDK's `.app-page`), the browser turns its
212
+ sideways clip into `hidden`, which is a scroller again: a page-header ⋯ on its
213
+ right edge made it 13px wider than its view in a landscape phone window. So
214
+ the `PageContent` body clips too. The body reaches over the page's side
215
+ padding (`--ui-page-bleed`, the gutter of a page with a surface, 0 for
216
+ `surface="none"`) with a negative margin and the same padding inside, so its
217
+ content stays where it was, and it clips at the page's own edge: a box keeps
218
+ its 44px over the gutter and loses only what would lie outside the page. The
219
+ body's width and `max-width` allow for the bleed; an App that sizes the body
220
+ itself (`width: 100%`) is overridden by the body's inline width.
221
+
222
+ A fill page's scroller can be an element of the App's own, with the
223
+ `PageHeader` inside it (a record pane). No PageContent clip sits between the
224
+ header and that scroller's edge, so a "…" IconButton at the end of the
225
+ header reached 13px past it in a landscape phone window. A `PageHeader`'s
226
+ last action therefore sets `--ui-hit-end-room` to the header's own end
227
+ padding (`--ui-page-padding-x`, 0 inside a PageContent): its tap box stops
228
+ at the header's edge and grows towards its start side, still the full 44px,
229
+ wherever the header is. The scroller itself is not clipped: an App's
230
+ scroller that also scrolls a wide table sideways keeps doing so. For the
231
+ same reason no UI component's box reaches past its own edges: an
232
+ Accordion's pressed wash reaches 4px past each side by `box-shadow` (ink,
233
+ never scrollable overflow), not by a wider trigger.
234
+
191
235
  A control at the end edge of its own component is the component's job, not
192
236
  the page's: a dismissible Callout is often full width in an App's own
193
237
  scroller with no `PageContent` around it. Such a control sets
@@ -438,6 +482,46 @@ is the App's presentation (`mobile`), set by AppRoot or AppLayout. The
438
482
  `#actions` slot sits above the section list. A `SettingsPage` inside a pushed
439
483
  section keeps its sticky footer.
440
484
 
485
+ ## Gesture velocity
486
+
487
+ Scrolling and dragging stay the browser's own; the UI never animates a
488
+ scroll or replaces momentum. Where the UI itself decides what a gesture
489
+ means, it reads one estimator with one set of thresholds
490
+ (`src/interaction/velocity.ts`, exported from the package):
491
+
492
+ - `VelocityEstimator`: velocity along one axis (px/s) from a least-squares
493
+ line through the samples of the last 100ms (`VELOCITY_WINDOW_MS`), at most
494
+ 20 (`VELOCITY_MAX_SAMPLES`). A sample with the same timestamp replaces the
495
+ last, an out-of-order one is ignored, a reversal of more than 0.5px
496
+ (`VELOCITY_REVERSAL_PX`) starts a new fit from the turning point, a gap
497
+ longer than the window starts over, and a fit older than the window reads 0
498
+ (the finger stopped before lifting).
499
+ - `GESTURE_THRESHOLDS`:
500
+
501
+ | Name | Value | Used for |
502
+ | --- | --- | --- |
503
+ | `flick` | 1000 px/s | hide or show the phone bars at once; faster bar motion |
504
+ | `swipe` | 500 px/s | a short swipe commits (pop a pushed page, next image) |
505
+ | `swipeDistance` | 48px | a slow swipe commits (next image) |
506
+ | `hideDistance` | 48px | a slow scroll down hides the bars |
507
+ | `showDistance` | 24px | a slow scroll up shows the bars |
508
+ | `slop` | 6px | travel before a touch has a direction |
509
+
510
+ - `velocityDuration(velocity, baseMs)`: a motion set off by a flick takes 60%
511
+ of its base duration (never under 120ms); anything slower takes the base.
512
+ - `swipeCommits(travel, velocity, distance)`: a released swipe commits past
513
+ `distance`, or past `slop` at `swipe` speed or faster in its direction.
514
+
515
+ Reduced motion is the stylesheet's: every transition finishes at once, so a
516
+ decision still happens and nothing animates.
517
+
518
+ Where it is used: hide on scroll and the FAB (the page's `scrollTop`), the
519
+ pushed page's edge swipe back (`PushTransition`: past 35% of the width, or a
520
+ `swipe`), and the image lightbox's swipe to the next file. The BottomSheet's
521
+ drag and snap, the navigation drawer's swipe and a toast's swipe to dismiss
522
+ are decided by Reka UI, which the UI does not fork; they keep Reka's own
523
+ thresholds. SegmentControl and lists have no swipe gestures.
524
+
441
525
  ## RecordPanel and AsidePanel on the BottomSheet
442
526
 
443
527
  Both panels use `BottomSheet` on a phone, so they share its grabber, drag,
@@ -586,10 +670,10 @@ the page's actions (PageHeader `#actions`, a pushed page's
586
670
  at the bottom right, 16px from the edges and above the tab bar. No App
587
671
  change: the same slot moves.
588
672
 
589
- - One action: the FAB is that action (56px, its icon only, its label as the
590
- accessible name). A tap runs it. It is the area's one primary: a danger
673
+ - One action: the FAB is that action (a 56px circle, its icon only, its
674
+ label as the accessible name). A tap runs it. It is the area's one primary: a danger
591
675
  action stays red.
592
- - Two or more: the FAB (`+`, "Page actions") opens a speed dial: the actions
676
+ - Two or more: the FAB (a 56px circle with `+`, "Page actions") opens a speed dial: the actions
593
677
  as labelled 48px pills over a scrim, staggered in. Focus moves to the first
594
678
  and stays in the dial; Escape, Back, a press on the scrim or the FAB close
595
679
  it and focus returns to the FAB. A pick runs the action and closes the dial;
@@ -627,15 +711,38 @@ change: the same slot moves.
627
711
  (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,
628
712
  a DSM window and a desktop place toasts as before.
629
713
 
630
- **Hide on scroll.** On by default (`AppLayout` `hide-on-scroll`). Scrolling
631
- the page down 16px or more slides the bar, the tab bar, the FAB and a clean
632
- settings footer out (`data-ui-bars-hidden`, `all` when the page scrolls under
633
- the bar, `bottom` when the document scrolls); any scroll up of 4px, the top of
634
- the page and a scroll that stops at its end bring them back. Safe areas are
635
- kept, and they move in `--ui-motion-bars` (200ms; 0 with reduced motion). They
636
- never hide while the speed dial, the drawer, a sheet or a dialog is open or a
637
- text field has focus, and focus moving into a bar shows them. A page shorter
638
- than the bars' room never hides them.
714
+ **Hide on scroll.** On by default (`AppLayout` `hide-on-scroll`). The page
715
+ scrolls natively; the decision reads the shared velocity estimator (see
716
+ [Gesture velocity](#gesture-velocity)) and the distance travelled one way:
717
+
718
+ - a slow scroll down of `hideDistance` (48px) slides the bar, the tab bar,
719
+ the FAB and a clean settings footer out (`data-ui-bars-hidden`); a slow
720
+ scroll up of `showDistance` (24px) brings them back, so a slow or wobbly
721
+ drag never flickers them;
722
+ - a flick at `flick` (1000 px/s) or faster hides them, or shows them, at
723
+ once, and they move in 60% of `--ui-motion-bars` (never under 120ms;
724
+ `--ui-bars-motion` on the layout), else in `--ui-motion-bars` (200ms; at
725
+ once with reduced motion);
726
+ - the top of the page and a scroll that stops at its end bring them back.
727
+
728
+ The bars move by `transform` only. When the page scrolls in an area under
729
+ the bar (a fill layout, or an App shell whose `main` does not let the
730
+ document scroll) the layout marks itself `data-ui-bars-overlay`: the content
731
+ runs under the bar, the tab bar and the accessory from the start, and the
732
+ end of what scrolls has a constant spacer (`--ui-bars-room`: the bar, the
733
+ tab bar or the safe area, and the accessory) so the last row clears them.
734
+ Hiding then translates the bar, the content area and the tab bar
735
+ (`data-ui-bars-hidden="all"`). When the document scrolls, the bar scrolls
736
+ away with it, and only the tab bar, the accessory and the FAB slide
737
+ (`bottom`). Either way the scroller keeps its size, position and padding, no
738
+ `scrollTop` is written, and a momentum fling keeps going on iOS and Android.
739
+ While the content area is translated it is the containing block of a
740
+ `position: fixed` element inside it; the UI's own overlays (sheets, menus,
741
+ toasts) render in the floating layer outside it.
742
+
743
+ They never hide while the speed dial, the drawer, a sheet or a dialog is
744
+ open or a text field has focus, and focus moving into a bar shows them. A
745
+ page that scrolls less than the bars' room never hides them.
639
746
 
640
747
  - Opt out for the App: `<AppLayout :hide-on-scroll="false">`; for one page:
641
748
  `<PageContent :hide-on-scroll="false">`. Both keep the settings footer too.
@@ -719,16 +826,47 @@ An App sets no `top` of its own and measures nothing.
719
826
  page only.
720
827
  - The offset is the page's, not per element: content above a sticky row in
721
828
  the middle of a page also stops that much lower (never under it).
829
+ - A row inside a scroll container of the App's own in the body (a wide
830
+ layout's side pane with `overflow-y: auto`, or any ancestor whose overflow
831
+ is not `visible` or `clip`, which is where the browser sticks it) sticks in
832
+ that container, not in the page. It stacks only on that container's earlier
833
+ rows (`top` 0 for the first), never counts in the page's offset, and the
834
+ container gets its own `--ui-sticky-top-offset` (its top padding plus its
835
+ rows), so what scrolls in the pane stops below the pane's rows and not
836
+ below the page's header.
837
+ - A sticky `PageHeader` (and a sticky tabs strip) inside such a container
838
+ covers that container's top, not the page's: the container's rows stick
839
+ below it (`--ui-sticky-row-top` starts at the header's height), the
840
+ container's `--ui-sticky-top-offset` is its top padding plus the header,
841
+ the strip and its rows, and the container gets its own
842
+ `--ui-page-sticky-top` (its header's height) for a strip in it. Such a
843
+ header is left out of the page's `--ui-page-sticky-top` and offset. A
844
+ container with a sticky header and no rows gets the header as its offset.
845
+ - A nested scroller without rows still inherits the page's offset as its
846
+ content's scroll margin. Mark it `data-ui-sticky-scope` and what scrolls in
847
+ it takes no page offset. A fill page's own list scroller
848
+ (`data-ui-page-scroller`) never takes it: the header is above the list, not
849
+ over it.
722
850
  - The rule has one attribute's specificity, so an App's own class wins for
723
851
  `position`, `background` or `z-index`.
724
852
  - Before 0.23.4 an App measured its row and added it to the token by hand;
725
853
  remove that code when it marks the row instead.
726
854
 
727
855
  **The end of a page: `--ui-page-end-space`.** The room after a page's last
728
- row, 24px. While the bars are hidden on a fill page (`data-ui-page-fills`)
729
- it is only `--ui-safe-bottom`, so the content's scroller runs to the bottom
730
- of the screen. An App shell that pads its page end reads it:
731
- `padding-bottom: var(--ui-page-end-space, var(--ui-space-6, 24px))`.
856
+ row, 24px, constant: hiding the bars never changes it, so the content's
857
+ length never changes mid-scroll. Under docked bars (`data-ui-bars-overlay`)
858
+ the room for the bars is the separate `--ui-bars-room` spacer, and a fill
859
+ page whose own scroller has the FAB's room gets no end space below that
860
+ scroller, so no blank band sits under a list. An App shell that pads its
861
+ page end reads it:
862
+ `padding-bottom: var(--ui-page-end-space, var(--ui-space-6, 24px))`. Under
863
+ docked bars its value is a `calc()` expression, not a plain length: code
864
+ that needs it in pixels reads a resolved length (PageContent reads the
865
+ computed margin of a hidden probe whose `margin-top` is the variable), never
866
+ `parseFloat` of the property's text. PageContent subtracts it when it looks
867
+ for a fill page's scroller, so an App that puts the end space on a wrapper
868
+ around its own scroller (rather than on the scroller) still has that
869
+ scroller found.
732
870
 
733
871
  **Scroll helpers.** A phone page scrolls in a different element than a
734
872
  desktop or DSM window. `nearestScroller(el)` returns the element that
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/ui",
3
- "version": "0.23.4",
3
+ "version": "0.23.6",
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,63 +60,6 @@
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
- },
120
63
  "peerDependencies": {
121
64
  "vue": "^3.5.0"
122
65
  },
@@ -167,13 +110,6 @@
167
110
  "engines": {
168
111
  "node": ">=20"
169
112
  },
170
- "packageManager": "pnpm@10.33.2",
171
- "pnpm": {
172
- "onlyBuiltDependencies": [
173
- "esbuild",
174
- "vue-demi"
175
- ]
176
- },
177
113
  "config": {
178
114
  "bundledRuntime": {
179
115
  "@tanstack/vue-virtual": "3.13.39",
@@ -181,5 +117,62 @@
181
117
  "reka-ui": "2.11.0"
182
118
  }
183
119
  },
184
- "homepage": "https://www.varvis.me/docs/"
185
- }
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
+ }