uhuu-components 0.3.7 → 0.3.8
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/index.d.ts +7 -0
- package/package.json +5 -4
- package/uhuu-components.es.js +2711 -2696
- package/uhuu-components.es.js.map +1 -1
- package/uhuu-components.umd.cjs +19 -19
- package/uhuu-components.umd.cjs.map +1 -1
- package/CHANGELOG.md +0 -347
package/CHANGELOG.md
DELETED
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to the `uhuu-components` Storybook workspace are documented here.
|
|
4
|
-
|
|
5
|
-
### 2026-10-08 — Toolchain declarations (ECO-04)
|
|
6
|
-
|
|
7
|
-
- `package.json` declares the Node floor (>=24) and the package-manager pin (pnpm@10.30.3) the ecosystem
|
|
8
|
-
toolchain policy measures. Metadata only; the dependency resolution is unchanged.
|
|
9
|
-
|
|
10
|
-
## 0.3.3 (unreleased)
|
|
11
|
-
|
|
12
|
-
### Added
|
|
13
|
-
|
|
14
|
-
- The editor shell's chrome follows the host's light or dark appearance: the stage behind the
|
|
15
|
-
pages, page labels and their menus, the floating page toolbar and zoom menu, the add and reorder
|
|
16
|
-
sheets, notices and the stage's scrollbars. Pages, and the page thumbnails in the sheets, stay
|
|
17
|
-
paper. Inside the uhuu document editor the shell takes `?appearance=light|dark` from the template
|
|
18
|
-
URL before the first render, then `appearance` in the handshake answer (`shaked`, re-emitted by
|
|
19
|
-
the SDK as `loaded`), then `{ action: 'appearance', data: { appearance } }` when the user
|
|
20
|
-
switches; it reads the editor's messages itself, so templates that pin an older SDK follow too.
|
|
21
|
-
Light by default; never a cookie or the OS preference; the renderer is always light. No new
|
|
22
|
-
exports: `InteractiveModeProvider` takes `appearance` to force one, and `useInteractive()`
|
|
23
|
-
reports the resolved `appearance` for template-owned chrome. Dark values mirror `@uhuuio/theme`
|
|
24
|
-
(not a dependency). See `docs/editor-shell-appearance.md`.
|
|
25
|
-
|
|
26
|
-
### Changed
|
|
27
|
-
|
|
28
|
-
- Chrome surfaces draw with a shell token instead of `bg-white` (`bg-(--uhuu-shell-surface)`, and
|
|
29
|
-
`text-(--uhuu-shell-on-inverse)` on dark buttons); the light look is pixel-identical.
|
|
30
|
-
- Chrome roots without `data-uhuu-editor` (the "added" notice, `Section`'s default header, the
|
|
31
|
-
legacy `PageResizer` controls, the drag grid's debug box) now carry it.
|
|
32
|
-
|
|
33
|
-
## 0.3.2 (unreleased)
|
|
34
|
-
|
|
35
|
-
### Fixed
|
|
36
|
-
|
|
37
|
-
- The shell now follows the user's interface language inside the uhuu document editor. The editor
|
|
38
|
-
sends it once, in the handshake that the SDK re-emits as `loaded`, before the payload. Templates
|
|
39
|
-
that render nothing until the payload arrives (go-expose) mounted `InteractiveModeProvider` after
|
|
40
|
-
that event and fell back to `<html lang>`, the document's language. The package now subscribes
|
|
41
|
-
when it is imported, so the language is kept for any provider that mounts later.
|
|
42
|
-
- Per-language page and group labels now reach documents saved earlier. The page-editor state a
|
|
43
|
-
document stores keeps each item's label as saved, so restored documents showed the old English
|
|
44
|
-
string. On restore, a saved label that is one of the template label's values, or none, is replaced
|
|
45
|
-
by the current template label; a user's rename is kept. Found migrating go-expose.
|
|
46
|
-
|
|
47
|
-
## 0.3.1 (unreleased)
|
|
48
|
-
|
|
49
|
-
### Added
|
|
50
|
-
|
|
51
|
-
- The editor shell is translated: toolbar, page menus, add and reorder dialogs, zoom, image options
|
|
52
|
-
and notices ship in German, French, Italian and English, and follow the user's interface language
|
|
53
|
-
from the host handshake (`uhuuData.locale`, re-emitted by the SDK as `loaded`), then `?lang=`,
|
|
54
|
-
`<html lang>` and the browser. No new exports: `InteractiveModeProvider` takes `locale` and
|
|
55
|
-
`translations` (per-language overrides, or a whole catalog for another language, bundled or
|
|
56
|
-
fetched), `useInteractive()` reports the resolved `locale`, and `label` in `templateConfig` and
|
|
57
|
-
`pageOptions` (pages, groups, options, select and colour values) plus `reorderTitle` /
|
|
58
|
-
`reorderDescription` accept one string per language (`{ en: 'Cover', de: 'Titelseite' }`).
|
|
59
|
-
Plain string labels and developer tooling are unchanged. See `docs/editor-shell-translations.md`.
|
|
60
|
-
|
|
61
|
-
### Changed
|
|
62
|
-
|
|
63
|
-
- Generate the delivery README from owning Storybook package documentation and include the source CHANGELOG with every release. Public documentation describes current static/flow, editor, image and BrandKit APIs.
|
|
64
|
-
- Ship one UMD artifact, `uhuu-components.umd.cjs`, for CommonJS and browser-global use, with its matching source map. The duplicate `.umd.js` is removed from future releases; package-root ESM and CommonJS entries remain compatible. Direct `.umd.js` URLs must stay on their existing pinned release or migrate to `.umd.cjs`.
|
|
65
|
-
- Replace the public handoff repository’s unrelated application ignore rules with package-specific rules. The published 0.3.0 artifacts remain immutable.
|
|
66
|
-
|
|
67
|
-
## 0.3.0
|
|
68
|
-
|
|
69
|
-
### Changed
|
|
70
|
-
|
|
71
|
-
- `BrandKitProvider` applies a Brand Kit `brandkit.json.runtime` block (`version: 2`, brandkit.json
|
|
72
|
-
"2.0") as published, with the token chains skipped:
|
|
73
|
-
- shadcn/ui role variables, `--<role>` and `--color-<role>` (`--primary`, `--muted-foreground`,
|
|
74
|
-
`--chart-1` …), so Tailwind v4's `bg-primary` / `text-muted-foreground` resolve with no bridge;
|
|
75
|
-
- the `--color-kit-*` / `--font-kit-*` aliases with the meanings templates were written against
|
|
76
|
-
(`kit-muted` is grey text, `kit-secondary` the strong second brand colour);
|
|
77
|
-
- `--font-<role>`.
|
|
78
|
-
Entries are re-validated against an allowlist of names (a published document cannot set
|
|
79
|
-
`--radius` or `--spacing`) and the colour policy. Fonts come from `runtime.fontStylesheets` and
|
|
80
|
-
`runtime.fontFaces` (through the same `@font-face` builder), so only what the four font roles use
|
|
81
|
-
is loaded. Any other `runtime` (including the never-published `version: 1`) is ignored and the
|
|
82
|
-
chains apply. `defaults` still fill gaps; the kit wins.
|
|
83
|
-
- **Colour policy:** `oklch()` and `oklab()` with plain components pass as written (Brand Kit
|
|
84
|
-
publishes oklch; Chrome prints it since 111). Relative colour syntax and nested functions are
|
|
85
|
-
still skipped.
|
|
86
|
-
- Kits without `runtime` (template-bundled kits) also land Brand Kit's
|
|
87
|
-
`tokens.light.semantic` roles on `--<role>` / `--color-<role>`. Flat tokens never feed a role:
|
|
88
|
-
extracted kits use some of these words with other meanings (`muted` is grey text there).
|
|
89
|
-
- New `BrandKitJson.runtime` / `colorMode` types (`BrandKitRuntimeBlock`, `version: 2`).
|
|
90
|
-
- **The provider loads the kit.** `src` fetches a brandkit.json (`brandKitSourceUrl(payload)` reads
|
|
91
|
-
`brandKitUrl`, `kit-…` ids with `brandKitTeamId`, or `brandKit.storage.publicUrl`); the `brandKit`
|
|
92
|
-
prop renders until it arrives and when the fetch fails. `status` (and `data-uhuu-brand-kit-status`
|
|
93
|
-
on the scope element) is `idle`, `loading`, `ready` or `error`. `loadBrandKit` is exported.
|
|
94
|
-
- **Assets from the kit.** `useBrandKit()` adds `logo({ kind, background })` (Brand Kit's
|
|
95
|
-
`logoSystem` first, then `logos`, then template-bundled shapes), `collection(kind)` (the assigned
|
|
96
|
-
media collection's promoted version, items resolved), `mapStyle(mode)`, `env(keys)` and
|
|
97
|
-
`resolveUrl(path)`, all resolving relative paths against the kit's `baseUrl` or its source URL.
|
|
98
|
-
The same functions are exported (`brandKitLogo`, `brandKitCollection`, `brandKitMapStyle`,
|
|
99
|
-
`brandKitEnv`). Templates delete their copied `src/brandkit/brand-kit-client.js` and
|
|
100
|
-
`BrandKitContext.jsx`; the registry-style.json request they made is gone (`runtime` carries the
|
|
101
|
-
shadcn roles).
|
|
102
|
-
- The Brand Kit Switcher story renders through `BrandKitProvider` and includes Brand Kit's golden
|
|
103
|
-
kit (`test/fixtures/golden-brandkit.json`, copied from uhuu-brandkit, brandkit.json "2.0").
|
|
104
|
-
- The copy of `dist/` into the open-source handoff checkout is an explicit step,
|
|
105
|
-
`npm run release:handoff` (`scripts/handoffDist.js`, with `HANDOFF_DIR` / `--handoff-dir` and
|
|
106
|
-
`--dry-run`). `npm run build` writes only under `dist/` and no longer overwrites the public
|
|
107
|
-
package tree as a side effect. `scripts/release-components.sh` runs build → handoff → verify.
|
|
108
|
-
Covered by `test/handoff-dist.test.mjs`.
|
|
109
|
-
- Release pipeline (`.github/workflows/release-components.yml`): installs with pnpm
|
|
110
|
-
(`pnpm/action-setup` reading the new `packageManager` pin, `pnpm install --frozen-lockfile`,
|
|
111
|
-
pnpm store cache) instead of `npm ci` against the absent `package-lock.json`; runs the test suite
|
|
112
|
-
after the build; reads `HANDOFF_REPO_TOKEN` / `NPM_TOKEN` only in the opt-in jobs through `env:`
|
|
113
|
-
with fail-fast checks, publishes through `actions/setup-node`'s registry `.npmrc`, and keeps
|
|
114
|
-
`GITHUB_TOKEN` read-only. `pnpm test` now builds first (`pnpm test:unit` skips the build).
|
|
115
|
-
|
|
116
|
-
## 0.2.98
|
|
117
|
-
|
|
118
|
-
### Added
|
|
119
|
-
|
|
120
|
-
- `getDialogProps` is exported for binding a template's own element to a dialog, using the same
|
|
121
|
-
renderer guard and markers as `Editable` and `ImageBlock`.
|
|
122
|
-
- `imageUrl` provides shared thumbnail sizing, source encoding, SVG pass-through and empty-image
|
|
123
|
-
handling. See [image-url.md](docs/image-url.md).
|
|
124
|
-
- `BrandKitProvider` and `useBrandKit` share token mapping, font loading and CSS variable scoping.
|
|
125
|
-
Brand fallbacks stay in templates. Font assets honor face-level stylesheets, root-relative URLs
|
|
126
|
-
and declared Google Fonts styles. See [brand-kit-runtime.md](docs/brand-kit-runtime.md).
|
|
127
|
-
|
|
128
|
-
### Removed
|
|
129
|
-
|
|
130
|
-
- The unused internal `imgOptim` / `imgBlank` helpers (`src/uhuu/utility/helpers.js`). They were
|
|
131
|
-
never exported from the package root.
|
|
132
|
-
|
|
133
|
-
### Fixed
|
|
134
|
-
|
|
135
|
-
- Empty `text`, `textarea` and `markdown` bindings stay clickable in the interactive editor.
|
|
136
|
-
`Editable` and `Static.FlowDocument` mark empty text content; elements bound with `getDialogProps`
|
|
137
|
-
use `data-uhuu-type` and `:empty`. The one-line affordance is scoped to editor screen output.
|
|
138
|
-
Templates control whether empty fields preserve space or disappear in print.
|
|
139
|
-
- The library continues to leave Markdown rendering and typography to templates; wrap the
|
|
140
|
-
template's renderer in `Editable` and pass `null` for empty text. No Markdown runtime is bundled.
|
|
141
|
-
|
|
142
|
-
## 0.2.96
|
|
143
|
-
|
|
144
|
-
### Added
|
|
145
|
-
|
|
146
|
-
- **Cover spread geometry for perfect binding (`Static.planCoverSpread`, `Static.resolveSheetSize`).**
|
|
147
|
-
Pure, DOM-free planner in `src/uhuu/pagination-static/spread-core.js` that turns
|
|
148
|
-
`pageFormat.binding = { spine, glue }` plus the filtered cover pages into the printer's two
|
|
149
|
-
wide sheets — outer (back cover · spine · front cover) and inner (inside front · blank
|
|
150
|
-
spine + glue zones · inside back) — with panel, spine and glue boxes in mm. Verified in
|
|
151
|
-
`test/cover-spread-core.test.mjs` against the approved Lienhardt InDesign export
|
|
152
|
-
(429 × 303 mm with 3 mm bleed) and the hand-coded Prozentbuch A6 cover sheet. `BindingConfig`
|
|
153
|
-
is typed on `pageFormat` / `PrintConfig.pageFormat` (see `docs/printer-cover-spine-support.md`).
|
|
154
|
-
- **`Static.CoverSpread` — one physical cover sheet for the Static-only template path.**
|
|
155
|
-
`sheet="outer"` renders back cover · spine · front cover, `sheet="inner"` inside front · blank
|
|
156
|
-
spine + glue masks · inside back. Panels are ordinary `Static.Sheet`s clipped at the spine, so
|
|
157
|
-
ImageBlock/overlays keep their bleed contract and full-bleed artwork is cut cleanly at the spine;
|
|
158
|
-
glue zones and the inner spine are masked to `--uhuu-paper-color`. With `showBleed` the spine and
|
|
159
|
-
glue strips carry hatched, labelled screen-only guides. Without a binding the panels degrade to
|
|
160
|
-
two plain sheets. Story: `Pagination/Cover Spread` (Lienhardt A4, Prozentbuch A6, outer only,
|
|
161
|
-
saddle-stitch fallback, print preview). Rendered-DOM contract tested from the built package in
|
|
162
|
-
`test/cover-spread-render.test.mjs`.
|
|
163
|
-
- **`PageEditor` composes perfect-binding cover spreads.** With `pageFormat.binding = { type: 'perfect',
|
|
164
|
-
spine, glue }` and `pageFilter.mode === 'cover'`, the filtered cover pages are laid out on the
|
|
165
|
-
printer's sheets through `Static.CoverSpread`: outer (back cover · spine · front cover) and inner
|
|
166
|
-
(inside front · blank spine + glue masks · inside back). `binding` is ignored in `all`/`text`
|
|
167
|
-
modes, so it can live in the base page format or in `printConfigs.cover.pageFormat`; the dev
|
|
168
|
-
print switcher picks it up unchanged. `two_pages` preview is coerced to single-page while a
|
|
169
|
-
spread is active. Cover page components receive a `spread` prop (`{ sheet, side, spine, glue,
|
|
170
|
-
bleed }`), and `templateConfig.spine.component` paints the outer spine strip (`SpineComponentProps`).
|
|
171
|
-
Thumbnails, add/reorder dialogs and flow measurement always use a binding-less setup so the
|
|
172
|
-
`@page` size never flips. Unsupported cases (coverPageCount other than 1 or 2, saddle stitch)
|
|
173
|
-
fall back to plain cover pages with a one-time dev warning. Decision logic is pure
|
|
174
|
-
(`cover-spread-layout.js`, tested in `test/cover-spread-layout.test.mjs`); stories under
|
|
175
|
-
`EditorShell/Cover Spine`.
|
|
176
|
-
- **Sheet-level CSS vars drive `@page`.** `--uhuu-sheet-width/height` default to page + bleed and
|
|
177
|
-
become `2 × width + spine + 2 × bleed` while `setup.binding.spine > 0`, alongside
|
|
178
|
-
`--uhuu-spine-width`, `--uhuu-glue-width` and `--uhuu-paper-color`. `PageSizeUtils.resolveCssVars`
|
|
179
|
-
exposes the map; `config.page` now also carries `binding` and `sheet`.
|
|
180
|
-
|
|
181
|
-
### Changed
|
|
182
|
-
|
|
183
|
-
- **`PageSizeUtils.pageParams` returns the page config without a DOM.** Root CSS vars are only
|
|
184
|
-
written when `document` exists, but `ConfigContext` consumers (Sheet, CoverSpread, ImageBlock) now
|
|
185
|
-
see the same `page` during server rendering as in the browser; previously the context was empty on
|
|
186
|
-
the server.
|
|
187
|
-
|
|
188
|
-
### Fixed
|
|
189
|
-
|
|
190
|
-
- **Editable nodes no longer override template layout utilities.** The indicator's fallback
|
|
191
|
-
`position: relative` now lives in Tailwind's `components` layer, so a template's normal
|
|
192
|
-
`absolute` utility wins in the editor as it does in renderer mode. Existing inline, important,
|
|
193
|
-
and wrapper workarounds remain compatible but are no longer needed.
|
|
194
|
-
|
|
195
|
-
### Changed
|
|
196
|
-
|
|
197
|
-
- **`PageEditor` now opens fitted to the page.** `defaultZoomMode` defaults to `fit-page`
|
|
198
|
-
instead of `manual`, so a document loads with a whole sheet visible rather than at the
|
|
199
|
-
numeric `defaultZoom` (80%), which left large formats cropped on both axes until the author
|
|
200
|
-
opened the zoom menu. Fit keeps tracking layout and viewport changes until a manual zoom
|
|
201
|
-
(toolbar entry, ± buttons, Ctrl/Cmd-wheel or pinch) clears it. Pass
|
|
202
|
-
`defaultZoomMode="manual"` to restore the previous numeric-zoom start.
|
|
203
|
-
|
|
204
|
-
### Fixed
|
|
205
|
-
|
|
206
|
-
- **A starting fit mode no longer flashes the unfitted page.** Fit cannot resolve during the
|
|
207
|
-
first commit — `Section` publishes its natural size from an effect — so the editor painted
|
|
208
|
-
`defaultZoom` for a frame or two before snapping to the fitted zoom. The sheet stack now stays
|
|
209
|
-
`visibility: hidden` (still laid out, so the measurements fit needs keep arriving) until the
|
|
210
|
-
first fit lands, with a 1s reveal fallback so an unmeasurable document can never stay hidden.
|
|
211
|
-
|
|
212
|
-
- **Pointer-anchored zoom now holds the point it was given.** The focal correction measured the
|
|
213
|
-
whole page stack, but the stack's height is *affine* in zoom rather than proportional — every
|
|
214
|
-
section contributes a header and spacer that stay a fixed pixel size, so it measures
|
|
215
|
-
`naturalTotal * zoom + chromeTotal`. `zoomFocalScrollDelta` maps a point by the ratio of the
|
|
216
|
-
before/after rects, which only holds for a uniformly scaled box, so the anchor drifted by the
|
|
217
|
-
accumulated chrome: **~64px going 122% → 200%**, and worse the deeper the target sat in the
|
|
218
|
-
document. The correction now anchors on the individual sheet under the pointer
|
|
219
|
-
(`pickZoomFocalAnchor`), which *is* uniformly scaled, making the mapping exact. Note the
|
|
220
|
-
earlier "sub-pixel" verification of this path was circular — it re-derived the expected
|
|
221
|
-
position with the same formula under test — so the drift went unnoticed.
|
|
222
|
-
|
|
223
|
-
- **Fit to Page no longer behaves like Fit to Width, and Fit to Height no longer overshoots.**
|
|
224
|
-
The pan viewport's geometry lived only in `section-page-resizer.css`, and not every consumer
|
|
225
|
-
ends up with that stylesheet — Template Studio renders the editor in an iframe whose document
|
|
226
|
-
never receives it. Without those rules the pane degraded to a plain block reporting its whole
|
|
227
|
-
content height (measured: **4711px inside a 665px iframe**), so fit divided by a viewport
|
|
228
|
-
seven times too tall: Fit to Height computed **413%** (clamped to `maxZoom`) and Fit to Page,
|
|
229
|
-
being `min(width, height)`, always collapsed to the width value. The pane and its content box
|
|
230
|
-
now carry their load-bearing geometry as inline styles, and `resolveFitPaneHeight` clamps the
|
|
231
|
-
measured pane to the space actually visible in its own document, so a mis-sized pane can no
|
|
232
|
-
longer corrupt fit. Verified in the Studio iframe: pane height now tracks the iframe viewport
|
|
233
|
-
(665 → 851 on resize) and Fit to Width / Fit to Height resolve to distinct values
|
|
234
|
-
(84.1% / 47.4%) where they were previously 90.2% / 413%.
|
|
235
|
-
|
|
236
|
-
## 0.2.90
|
|
237
|
-
|
|
238
|
-
### Fixed
|
|
239
|
-
|
|
240
|
-
- **A zoomed-in page can be scrolled to on both sides.** `SectionPageResizer` had no scroll
|
|
241
|
-
container of its own, so it rode the document scroller while centering the page stack with
|
|
242
|
-
`items-center`. Horizontal overflow was therefore split evenly to the left and right, and
|
|
243
|
-
because `scrollLeft` cannot go negative the left half was permanently unreachable —
|
|
244
|
-
measured at 277px of a 554px overflow in a 716px viewport. The editor now renders its own
|
|
245
|
-
pan viewport, so every pixel of the sheet is reachable at any zoom, in single-page and
|
|
246
|
-
facing modes alike.
|
|
247
|
-
- **Pointer-anchored zoom no longer drifts once zoomed in.** The scroll correction clamped at
|
|
248
|
-
`scrollLeft: 0` whenever the anchor sat left of centre, silently losing the point under the
|
|
249
|
-
cursor. With a real scroller on both axes the anchor now holds to sub-pixel accuracy
|
|
250
|
-
wherever scroll range exists.
|
|
251
|
-
- **The toolbar zoom controls keep their place.** `+` / `−` and the `%` input previously did
|
|
252
|
-
no scroll correction at all and drifted the viewport; all zoom entry points now share one
|
|
253
|
-
path and anchor on the centre of the visible pane.
|
|
254
|
-
- **Fit to Width / Height / Page measure real space.** Fit used fixed `32px` / `120px` insets
|
|
255
|
-
against the window; it now uses the pane's own box, its rendered gutters, and the measured
|
|
256
|
-
section chrome.
|
|
257
|
-
|
|
258
|
-
### Changed
|
|
259
|
-
|
|
260
|
-
- **`SectionPageResizer` scrolls itself rather than the document.** Hosts that already provide
|
|
261
|
-
a scroller and want the previous behavior can pass `scrollMode="document"`. Note that the
|
|
262
|
-
editor no longer grows the page, so host-level page scrolling is replaced by pane scrolling.
|
|
263
|
-
|
|
264
|
-
## 0.2.87
|
|
265
|
-
|
|
266
|
-
### Fixed
|
|
267
|
-
|
|
268
|
-
- **The image options menu ("Edit image" / "Annotate") stays on the image in bleed and spread
|
|
269
|
-
mode.** It was rendered as a sibling of the absolutely positioned image container, so it
|
|
270
|
-
anchored to the page and landed in the page header — templates using `top`/`left`/`right`/
|
|
271
|
-
`bottom` insets (satellite and cadastral spreads) had to reposition it by hand. It is now
|
|
272
|
-
anchored to the image rect, clamped to the page the image renders on, so both halves of a
|
|
273
|
-
spread get the menu on their own visible corner. Bleed, spread and the anchor share one
|
|
274
|
-
width calculation (`image-anchor-geometry.ts`) so they cannot drift apart.
|
|
275
|
-
|
|
276
|
-
## 0.2.86
|
|
277
|
-
|
|
278
|
-
### Fixed
|
|
279
|
-
|
|
280
|
-
- **Wheel / pinch zoom keeps the pointer-anchored location.** After Ctrl/Cmd-wheel or trackpad
|
|
281
|
-
pinch, SectionPageResizer corrects document scroll so content under the pointer (e.g. a later
|
|
282
|
-
page) does not jump toward the first page as sheet heights grow.
|
|
283
|
-
|
|
284
|
-
## 0.2.85
|
|
285
|
-
|
|
286
|
-
### Added
|
|
287
|
-
|
|
288
|
-
- **PageEditor / SectionPageResizer support Ctrl/Cmd-wheel and trackpad-pinch zoom.** Plain wheel
|
|
289
|
-
still scrolls; modifier or pinch zooms proportionally (~0.3%/px, rAF-batched) and clears fit
|
|
290
|
-
mode the same way the toolbar ± controls do.
|
|
291
|
-
|
|
292
|
-
## 0.2.84
|
|
293
|
-
|
|
294
|
-
### Fixed
|
|
295
|
-
|
|
296
|
-
- **Single-page Fit to Page no longer sums every stacked sheet width.** Fit targets the first
|
|
297
|
-
sheet only (facing mode still fits the first pair). Multi-page documents no longer clamp to
|
|
298
|
-
`minZoom` (e.g. 25%) on load when `defaultZoomMode="fit-page"`.
|
|
299
|
-
|
|
300
|
-
### Added
|
|
301
|
-
|
|
302
|
-
- Added `Static.FlowColumns` and `Static.planFlowColumnChunks` for bounded, non-recursive
|
|
303
|
-
sequential/parallel Flow stories. Each column advances its measured cursor independently on
|
|
304
|
-
every output page, exhausted tracks preserve their geometry, and all leaf keep/break/header,
|
|
305
|
-
oversized-item, and no-progress behavior continues to come from the existing Flow planner.
|
|
306
|
-
- Added column-scoped render hooks for track width, distribution, stack alignment, and measured
|
|
307
|
-
child spacing so authoring previews and published output can consume one authoritative plan.
|
|
308
|
-
|
|
309
|
-
### Fixed
|
|
310
|
-
|
|
311
|
-
- Discarded short-page placement attempts no longer emit false unplaceable diagnostics when a
|
|
312
|
-
whole column group is successfully retried on a fresh page.
|
|
313
|
-
- Keep-with-next and avoid-break bundles now retry on a fresh physical page when the remaining
|
|
314
|
-
space would orphan their first leaf; composite header height determines whether that retry can
|
|
315
|
-
succeed.
|
|
316
|
-
- Repeated group headers retain continuation and `repeatHeader: false` state independently inside
|
|
317
|
-
each column, with header measurements scoped by column group, track, and group key.
|
|
318
|
-
- Column plans now reject duplicate/missing layout identities and leaf indexes before rendering,
|
|
319
|
-
terminate a page after controlled unplaceable output, and fail closed on any no-progress state.
|
|
320
|
-
- Measurement and output now share a geometry-invariant track contract: page-dependent column
|
|
321
|
-
styles and unmeasured vertical wrapper spacing are unsupported, while measured child margins
|
|
322
|
-
remain the canonical stack-gap mechanism.
|
|
323
|
-
|
|
324
|
-
- **PageEditor can now start in a layout-tracking fit mode.** `defaultZoomMode="fit-page"`
|
|
325
|
-
measures the current preview viewport and sheets directly, then keeps fit current through content
|
|
326
|
-
and viewport changes until the author chooses a manual zoom.
|
|
327
|
-
|
|
328
|
-
- **The package root is now a real dual ESM/CommonJS public API.** `import { Static } from
|
|
329
|
-
"uhuu-components"` resolves to the ESM bundle while CommonJS consumers resolve a `.cjs` copy of
|
|
330
|
-
the UMD bundle. Consumers no longer need a distribution-file deep import.
|
|
331
|
-
|
|
332
|
-
- Aligned `src/index.d.ts` with the actual minimal root runtime exports (`Static`, `EditorShell`,
|
|
333
|
-
`ImageBlock`, `Editable`) so TypeScript consumers are not offered imports that fail at runtime.
|
|
334
|
-
- Corrected the ImageBlock manifest to describe the existing root named import from
|
|
335
|
-
`uhuu-components`, not an unpublished `uhuu-components/ImageBlock` subpath.
|
|
336
|
-
- Made handoff checksum comparison explicit via `--compare-handoff` and kept CI npm publishing
|
|
337
|
-
downstream of a synced handoff repo checkout.
|
|
338
|
-
- Fixed the cross-repo Print Document Contract link in `docs/print-mode.md`.
|
|
339
|
-
|
|
340
|
-
### Added
|
|
341
|
-
|
|
342
|
-
- GitHub Actions release workflow (`.github/workflows/release-components.yml`): tag `v*` or
|
|
343
|
-
`workflow_dispatch` build, dist integrity checks, sha256 bundle output, version bump guard vs npm
|
|
344
|
-
`latest`, optional handoff sync (`HANDOFF_REPO_TOKEN`) and npm publish (`NPM_TOKEN`).
|
|
345
|
-
- Release verification script `scripts/verifyDistRelease.js`, manual fallback
|
|
346
|
-
`scripts/release-components.sh`, and `npm run release:verify`.
|
|
347
|
-
- Component manifest pilot for `ImageBlock` (`src/manifests/image-block.manifest.json`) with JSON Schema (`src/manifests/component-manifest.schema.json`), docs (`docs/component-manifests.md`), validation test (`test/manifests.test.mjs`), and Storybook manifest story (`stories/ImageBlockManifest.stories.tsx`).
|