@synopackageland/ui 0.25.17 → 0.25.18

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 CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.25.18 (2026-11-14)
6
+
7
+ ### InputSteppers
8
+
9
+ - **44px step buttons on touch.** On a coarse pointer the field is at least `--ui-hit-min` (44px) tall and each − and + button is `--ui-hit-min` wide. They were 32px wide on a 42px field. With `controlsType: 'up-down'` the two buttons sit side by side on touch, each 44px wide and the full field height, instead of two half-height buttons stacked in a 32px column. A mouse keeps the old sizes.
10
+
11
+ ### Consistency: one token scale
12
+
13
+ - **A small fixed scale** (docs/tokens.md): space 2/4/8/12/16/24/32, one horizontal inset `--ui-inset-x` for pages, sheets, dialogs, list rows and forms, three font weights (400/500/600), three radius steps (4/8/12) behind the role tokens, three shadow levels, two durations (150/250 ms) and one decelerating easing. Components read tokens instead of numbers. **Visible tweaks:** control radius 6→4 and dialog radius 10→12 in a DSM window, dialog and side sheet inset 20→16, field padding 12 at md, menu rows 32, card titles 600 instead of 700, section titles 16px, every transition 150 or 250 ms on one curve.
14
+ - **New tokens:** `--ui-space-half`, `--ui-inset-x`, `--ui-radius-1/2/3`, `--ui-radius-card` on desktop, `--ui-font-weight-regular/medium/strong`, `--ui-line-height-sm`, `--ui-duration-short/long`, `--ui-ease-standard`, `--ui-motion-spin`, `--ui-shadow-card-hover/bar/selected`, `--ui-bottom-bar-padding`, `--ui-page-max-width`, `--ui-sheet-width-sm/md`, `--ui-sheet-height-lg`.
15
+ - **`pnpm check:tokens`** (in `pnpm gates`): fails on a px length, an off-scale spacing step, a literal colour, a written duration or a fourth font weight in `src/`; the exceptions that stay are listed with reasons in `scripts/token-exceptions.json`.
16
+
17
+ ### Smoothness
18
+
19
+ - **Grid:** a scroll frame draws straight onto the screen canvas and skips the offscreen copy; the first still frame refills it. Desktop with 4× CPU throttling: frames over 33 ms 19→3, paint per frame p50 14.4→9.0 ms. The cell padding is `--ui-space-2`.
20
+ - **Grid:** opening a record with the row's expand control keeps the cell and row selection.
21
+ - **CardGrid:** from 24 cards, cards out of view skip rendering (`content-visibility`), holding the first card's height. 104 cards with SVG pictures on an Android phone: 51.8→54.7 fps. Studio's ordering page with 32 cards: 52.5 fps without it, 54.4 with it, 48.9 on 0.25.17. A shorter grid no longer measures its first card on mount.
22
+ - **Sheets and dialogs open without forced layout:** opening one no longer forces a style and layout pass of the whole page before its first frame. Four sources are fixed: the bottom sheet's snap points read the root font size and viewport height only when a snap point needs them, Presence checks for an enter animation once the frame is drawn, an app-local root reads the background's scroll offsets after that frame, and an empty toast stack does not measure itself when it mounts. On Studio's record sheet on an Android phone, forced style and layout before the first frame went from 230 to 0 ms, and from tap to first frame from 476 to 284 ms (median of 3 alternating rounds).
23
+ - **Phone App bar:** a title or brand with no button before it starts at `--ui-inset-x` (16px on a phone), in line with the page content, instead of 12px.
24
+ - **Touch targets:** the AppSidebar group toggle and FacetPanel group toggle grow their tap box to 44px on touch.
25
+ - **Tokens:** docs/tokens.md lists the tokens Studio asked for that were not added (`--ui-space-1-5`, `--ui-font-size-2xs`, `--ui-font-size-md`, `--ui-aside-width`, `--ui-avatar-*`, `--ui-icon-size-*`, `--ui-portal-header-height`), each with the existing token to use, and defines `--ui-app-web-canvas` as an App-set hook.
26
+
5
27
  ## 0.25.17 (2026-11-14)
6
28
 
7
29
  ### Grid
@@ -10,3 +10,12 @@ export declare function cardGridColumns({ width, count, minItemWidth, gap }: {
10
10
  minItemWidth: number;
11
11
  gap: number;
12
12
  }): number | undefined;
13
+ /**
14
+ * From this many cards the ones out of view skip style, layout and paint
15
+ * (content-visibility). On an Android phone 104 cards with SVG pictures
16
+ * scrolled at 51.8 fps without it and 54.7 with it (mean of 4 alternating
17
+ * runs, tests/cards/scroll-fixture.html); Studio's ordering page (32 cards
18
+ * with SVG pictures) at 52.5 without it and 54.4 with it (0.25.17: 48.9;
19
+ * median of 3 alternating rounds). A short grid gains nothing.
20
+ */
21
+ export declare const CARD_GRID_SKIP_FROM = 24;
@@ -1,4 +1,4 @@
1
- export declare const TOOLTIP_CONTENT_CLASS = "z-[1450] max-w-[min(18rem,var(--reka-popper-available-width,18rem))] rounded-[var(--ui-radius-inner)] bg-[var(--ui-tooltip-bg)] px-3 py-1.5 text-[length:var(--ui-font-size-sm)] leading-4 text-[var(--ui-tooltip-fg)] whitespace-pre-line shadow-[var(--ui-shadow-menu)] [overflow-wrap:anywhere] animate-[ui-fade-in_var(--ui-motion-fast)_var(--ui-motion-ease)]";
1
+ export declare const TOOLTIP_CONTENT_CLASS = "z-[1450] max-w-[min(18rem,var(--reka-popper-available-width,18rem))] rounded-[var(--ui-radius-inner)] bg-[var(--ui-tooltip-bg)] px-3 py-1 text-[length:var(--ui-font-size-sm)] leading-4 text-[var(--ui-tooltip-fg)] whitespace-pre-line shadow-[var(--ui-shadow-menu)] [overflow-wrap:anywhere] animate-[ui-fade-in_var(--ui-motion-fast)_var(--ui-motion-ease)]";
2
2
  /** Gap between a tooltip and its trigger. */
3
3
  export declare const TOOLTIP_OFFSET = 6;
4
4
  /** The first tooltip waits this long (interaction-spec §1.1). */
@@ -17,6 +17,7 @@ export declare const GRID_DEFAULT: {
17
17
  readonly columnFreezeHandlerHeight: 30;
18
18
  /** The minimum while resizing. */
19
19
  readonly columnMinWidth: 100;
20
+ /** The cells' side padding: `--ui-space-2` (tests/grid/tokens.test.ts keeps them equal). */
20
21
  readonly cellHorizontalPadding: 8;
21
22
  readonly cellVerticalPaddingXS: 3;
22
23
  readonly cellVerticalPaddingSM: 6;
@@ -130,6 +130,11 @@ export declare const computeShouldRerender: (current: IGridRenderProps, last?: I
130
130
  * Paints one frame. `mainCanvas` is the visible canvas; `cacheCanvas` is an
131
131
  * offscreen canvas that keeps cell content between frames. Pass the previous
132
132
  * frame's props as `lastProps` so unchanged content is not redrawn.
133
+ *
134
+ * A scroll frame redraws every cell anyway, so it draws the content straight
135
+ * onto the main canvas and skips the cache and its full-size copy (half the
136
+ * cost of a scroll frame on a 2× screen); the first still frame after it
137
+ * refills the cache, so a hover or a selection change copies it again.
133
138
  */
134
139
  export declare const drawGrid: (mainCanvas: HTMLCanvasElement, cacheCanvas: HTMLCanvasElement, props: IGridRenderProps, lastProps?: IGridRenderProps, pixelRatio?: number) => void;
135
140
  export {};