@kurot/ui 3.4.0 → 3.6.0

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
@@ -4,9 +4,110 @@ All notable changes to `@kurot/ui` are documented here.
4
4
 
5
5
  ---
6
6
 
7
+ ## [3.6.0] — 2026-10-11
8
+
9
+ Prepared for publication; not yet published. Requires published Core ^2.5.2.
10
+ See [Label outline layout](docs/label-text-layout.md#outline-safe-layout-in-360).
11
+
12
+ ### Fixed
13
+
14
+ - Dynamic Label outlines now reserve a symmetric internal safety inset in normal
15
+ layout and fitting. Automatic dimensions include this inset and any glyph
16
+ block taller than nominal rows; wrapping, painting and shrink checks share the
17
+ same content bounds. Scroller viewports retain complete edge outlines without
18
+ per-Scroller configuration or relaxed clips.
19
+ - Preserve authored alignment, state overrides, minimum overflow, blank rows,
20
+ automatic axes and stable top-aligned typewriter origins after clearing.
21
+ Empty/unoutlined Labels and EditableText retain native sizing/viewport rules.
22
+ RichLabel, BitmapLabel and Core nominal measurement are unchanged.
23
+
24
+ ### Compatibility and adoption
25
+
26
+ Outlined Label dimensions and wrapping may change, including when fitting is
27
+ disabled. Recheck tightly sized captions and keep explicit top alignment for
28
+ progressively typed dialogue. Empty/unoutlined Labels, EditableText, RichLabel
29
+ and BitmapLabel retain their layout contracts. No public property or KUI/resource
30
+ format migration is added.
31
+
32
+ The Core peer and development range increase from ^2.4.0 to ^2.5.2 for public
33
+ glyph metrics and unified block alignment. Development installs registry 2.5.3;
34
+ the 2.5.2 minimum is tested separately. Core itself needs no new release.
35
+ ui-runtime 0.10.0 already accepts UI 3.6.0 through ^3.4.0; its host must also
36
+ satisfy the new UI Core peer. CLI and ui-document need no changes or releases.
37
+
38
+ After publication, applications adopt UI 3.6.0 and rebuild explicitly. Editor's
39
+ exact UI 3.5.0 pin must change; compatible example/template ranges can update
40
+ their installations and locks without changing their ranges. Existing application
41
+ and SDK development locks are unchanged by this release preparation.
42
+
43
+ ### Verification
44
+
45
+ The clean prepublish build and all 371 unit tests pass with installed registry Core
46
+ 2.5.3 and an isolated 2.5.2 minimum. All 18 minified browser tests pass, including
47
+ exact outline clips on Canvas/WebGL 1/2 at physical 1x/2x. An isolated packed-UI
48
+ consumer also passes all six backend/density checks for clipping, Japanese tails
49
+ and typewriter layout with Core 2.5.2; its strict TypeScript check passes.
50
+ The 3.6.0 tarball contains all 344 matching compiled/declaration/map files and
51
+ public documentation, excluding tests, node_modules and internal drafts;
52
+ frozen registry installation and `git diff --check` pass. The MilfMaster trial
53
+ harness verifies the actual compiled Drama skin and completed render frames
54
+ without replacing its registry dependencies.
55
+
56
+ ## [3.5.0] — 2026-10-10
57
+
58
+ Published; verified on npm on 2026-10-10. Requires Core ^2.4.0, unchanged
59
+ from 3.4.0. See [Label fitting](docs/label-text-layout.md).
60
+
61
+ ### Added
62
+
63
+ - Extend ordinary Label `textFit="shrink"` to complete multiline layouts,
64
+ including wrapping, hard breaks, blank/trailing rows and line spacing.
65
+ Recalculate wrapping at each candidate size while retaining the authored
66
+ `multiline`, text and base size. No row limit or new authored property is added.
67
+
68
+ ### Fixed
69
+
70
+ - Retain the original Label alignment frame and nominal automatic dimensions
71
+ while reserving outline allowance in fit checks and the shared wrapping width.
72
+ Toggling fitting does not move unchanged text or its icon-and-caption row.
73
+ - Refresh automatic dimensions after authored width/height changes and refit
74
+ fixed-size Labels after font readiness invalidation.
75
+ - Preserve unconstrained automatic axes, avoid repeatedly deducting outline
76
+ space under maximum widths, and report minimum or zero-content-width overflow
77
+ without confusing nonempty text with empty content.
78
+
79
+ ### Compatibility and adoption
80
+
81
+ Existing multiline Labels with `textFit="shrink"` begin fitting instead of
82
+ ignoring that policy. Omitted/true multiline continues to wrap; false remains
83
+ single-line. Minimums, password/first-line semantics and EditableText restrictions
84
+ are retained. `renderedSize` and `textFitOverflow` remain read-only results.
85
+ Core APIs, peer minima, KUI format and resource contracts are unchanged.
86
+
87
+ ui-runtime 0.10.0's UI ^3.4.0 peer already accepts 3.5.0. CLI and ui-document
88
+ already preserve the fitting fields; neither needs a new release. Applications
89
+ adopt the UI installation/lock and rebuild explicitly. Editor 0.28.2 uses exact
90
+ registry UI 3.5.0 with a matching Bun lock and ordinary App build; its temporary
91
+ UI source binding is removed. The selected Tentax and MilfMaster templates
92
+ adopt ^3.5.0 with matching pnpm locks and rebuilt outputs. Other applications
93
+ and SDK development locks are unchanged.
94
+
95
+ ### Verification
96
+
97
+ The clean prepublish build, all 359 unit tests and 12 minified browser tests
98
+ pass against installed registry Core 2.4.0. Browser coverage includes centered
99
+ flips, independent RichLabel/BitmapLabel, multiline shrink on Canvas/WebGL 1/2
100
+ at 1x/2x and pixel-identical fitting toggles for all alignment combinations.
101
+ Local npm packing verifies version 3.5.0, unchanged Core ^2.4.0, compiled fitting
102
+ and alignment modules, declarations and public documentation, excluding tests,
103
+ node_modules and internal drafts. Registry latest, package download and integrity
104
+ are verified; the published Label/fitting modules match the tested build.
105
+ `git diff --check` passes.
106
+
7
107
  ## [3.4.0] — 2026-10-09
8
108
 
9
- Prepared in source; not published.
109
+ Published; verified on npm on 2026-10-09. Requires published Core ^2.4.0.
110
+ Applications adopt the new UI and Core installation/lock explicitly and rebuild.
10
111
 
11
112
  ### Added
12
113
 
@@ -26,6 +127,9 @@ Editor type checks, 66 focused unit tests and one Electron Inspector/save/undo/r
26
127
 
27
128
  ## [3.3.1] — 2026-10-09
28
129
 
130
+ Not published separately. Preserved in commit 60e6404; its layout correction is
131
+ included in published UI 3.4.0.
132
+
29
133
  ### Fixed
30
134
 
31
135
  - Honor parent-space layout allocations for flipped, scaled, rotated and skewed
package/README.md CHANGED
@@ -1,15 +1,37 @@
1
1
  # @kurot/ui
2
2
 
3
- Source prepares **3.4.0**, not published. Its development installation and lock
4
- now resolve published Core 2.4.0 without local overrides. See
5
- [centered flips](../../docs/centered-flips.md) for APIs and remaining release order.
3
+ **3.6.0 is prepared for publication; it is not yet published.** Dynamic Label
4
+ outlines now fit inside their layout bounds, including Scroller viewports,
5
+ automatic dimensions, wrapping and text fitting. The release requires Core
6
+ ^2.5.2 and develops against registry Core 2.5.3 without local overrides.
7
+ The latest verified published UI release is 3.5.0 (2026-10-10).
8
+ See [Label layout](docs/label-text-layout.md) for behavior and adoption.
6
9
 
7
10
  UI component framework for [@kurot/core](https://github.com/kurot-engine/kurot/tree/main/packages/core). Migrated from Egret EUI, rewritten in modern TypeScript with clean class inheritance — no namespace hacks, no prototype manipulation.
8
11
 
9
- > **Package version: 3.4.0 (unpublished).** Requires `@kurot/core@^2.4.0`. Targets ES2022 + evergreen browsers, same as core.
12
+ > **Package version: 3.6.0 (prepared, unpublished).** Requires `@kurot/core@^2.5.2`. Targets ES2022 + evergreen browsers, same as core.
13
+
14
+ Outlined Label sizes and line breaks can change, including without `textFit`;
15
+ Scroller viewports need no extra configuration. Keep explicit top alignment for
16
+ progressively typed dialogue. No new KUI field, Core release or unrelated SDK
17
+ bump is required. After publication, applications must adopt UI 3.6.0 and rebuild
18
+ to receive the correction.
10
19
 
11
20
  For the full list of changes in this release, see [CHANGELOG.md](./CHANGELOG.md).
12
21
 
22
+ ## Text alignment inherited from Core
23
+
24
+ Label, RichLabel and EditableText inherit TextField's default alignment;
25
+ BitmapLabel inherits BitmapText's. With published Core 2.5.3 they default to middle.
26
+ Published Core 2.5.2 and earlier default to top. Explicit top/bottom and skin-state
27
+ overrides stay effective; multiline only controls line generation. Set top
28
+ explicitly when text should start at the top of a taller box.
29
+ UI 3.4.0's existing peer range accepts Core 2.5.3 without a UI release or a higher
30
+ minimum for that default change alone. Applications adopt the Core installation/lock
31
+ and rebuild. UI 3.6.0's separate outline correction requires Core ^2.5.2;
32
+ the development installation is registry Core 2.5.3.
33
+ See [text layout](docs/label-text-layout.md#vertical-alignment-and-skin-defaults).
34
+
13
35
  ## Centered flips in 3.4.0
14
36
 
15
37
  All UI display components inherit independent boolean `flipX` and `flipY`,
@@ -27,9 +49,8 @@ image.percentHeight = 100;
27
49
  Core 2.4.0 supplies the effective transform for rendering and input. The authored
28
50
  `matrix` stays independent of the flags. Layout remains deferred; validate first
29
51
  when reading coordinates or rendering manually. KUI authoring requires document
30
- 0.13.0 and CLI 3.5.0; materialized previews require runtime 0.10.0. These versions
31
- remain prepared but unpublished; Core 2.4.0 is published. No existing skin is
32
- converted automatically.
52
+ 0.13.0 and CLI 3.5.0; materialized previews require runtime 0.10.0. Core 2.4.0,
53
+ UI 3.4.0, document 0.13.0, CLI 3.5.0 and runtime 0.10.0 are published. No existing skin is converted automatically.
33
54
 
34
55
  ## RichLabel in 3.3.0
35
56
 
@@ -52,13 +73,18 @@ See [RichLabel](docs/rich-label.md) for defaults, measurement and font readiness
52
73
  BitmapLabel now also honors maxWidth during automatic measurement. Both text
53
74
  components remeasure automatic height when an authored width changes.
54
75
 
55
- UI 3.3.1 builds and tests against published Core 2.3.1 without local overrides.
56
- These native APIs do
57
- not add KUI tags or an Editor rich-text authoring interface by themselves.
76
+ The unpublished UI 3.3.1 snapshot built and tested against registry Core 2.3.1.
77
+ Published UI 3.5.0 was tested against Core 2.4.0; UI 3.6.0 builds and tests against
78
+ registry Core 2.5.3 and separately verifies its 2.5.2 minimum. Native KUI support
79
+ for RichLabel and BitmapLabel is available with ui-document >= 0.12.0, CLI >= 3.4.0
80
+ and ui-runtime >= 0.9.0. The current document 0.13.1, CLI 3.6.0 and runtime 0.10.0
81
+ retain that support; authoring applications adopt these packages separately.
58
82
 
59
- ## Label text fitting in 3.1.0
83
+ ## Label text fitting in 3.5.0
60
84
 
61
- Single-line Labels can shrink their drawing size to fit the available region:
85
+ Labels can shrink their drawing size to fit the available region. UI 3.5.0
86
+ supports both single-line and multiline fitting; UI 3.1.0–3.4.0 fit only
87
+ single-line Labels:
62
88
 
63
89
  ```ts
64
90
  import { Label } from '@kurot/ui';
@@ -74,8 +100,30 @@ amount.minFontSize = 16;
74
100
  `size` stays authored; `renderedSize` and `textFitOverflow` are read-only results
75
101
  after layout validation. Shorter text or larger bounds restore the base size.
76
102
  Put a Button's fitting policy on its `labelDisplay` skin part, so icon spacing
77
- and state overrides are respected. EditableText rejects shrinking; multiline
78
- Labels retain their base size.
103
+ and state overrides are respected. EditableText rejects shrinking.
104
+
105
+ For a multiline caption, keep `multiline = true` (the default), set width and
106
+ height on the Label, and enable `textFit = 'shrink'`. Complete wrapped content,
107
+ hard breaks and line spacing participate in fitting. If several rows fit at the
108
+ base size, the base size is retained. Automatic axes are unconstrained, so
109
+ width-only multiline captions normally wrap and grow taller without shrinking.
110
+ UI 3.6.0 reserves a symmetric outline inset in every nonempty dynamic
111
+ Label with a positive finite stroke, including normal layout. Automatic dimensions
112
+ contain the outline; fixed and maximum bounds wrap/fit inside it. Toggling fitting at unchanged drawing size
113
+ retains geometry and painting. Published 3.5.0 kept automatic dimensions nominal.
114
+ See [outline layout](docs/label-text-layout.md#outline-safe-layout-in-360).
115
+
116
+ ```ts
117
+ const caption = new Label('Доказуемая честность');
118
+ caption.width = 120;
119
+ caption.height = 44;
120
+ caption.size = 30;
121
+ caption.wordWrap = true;
122
+ caption.lineSpacing = 2;
123
+ caption.stroke = 1;
124
+ caption.textFit = 'shrink';
125
+ caption.minFontSize = 14;
126
+ ```
79
127
 
80
128
  Label defaults to multiline, while explicit `multiline = false` displays one
81
129
  unwrapped first line. Remove an old false flag or set it to true for text
@@ -84,28 +132,46 @@ measurement; after late loading, call `label.invalidateSize()` to refresh
84
132
  metrics even if the family name is unchanged.
85
133
 
86
134
  See the [text layout and fitting contract](docs/label-text-layout.md). Fitting
87
- metadata was introduced in ui-document 0.9.0 and remains supported in 0.11.0.
88
- Native text KUI projects use published CLI 3.4.0 with ui-document `^0.12.0`;
89
- published ui-runtime 0.9.0 uses the same kernel range. Programmatic UI depends
135
+ metadata was introduced in document 0.9.0 and remains supported in 0.13.0.
136
+ Current CLI 3.6.0 and runtime 0.10.0 use document `^0.13.0`.
137
+ Runtime 0.10.0 also requires UI `^3.4.0` and Core `^2.4.0`. Programmatic UI depends
90
138
  only on Core.
91
139
 
92
140
  ## Installation
93
141
 
94
142
  ```bash
95
- pnpm add @kurot/ui@^3.4.0 @kurot/core@^2.4.0
143
+ pnpm add @kurot/ui@^3.6.0 @kurot/core@^2.5.2
96
144
  ```
97
145
 
98
146
  `@kurot/ui` declares `@kurot/core` as a peer dependency. Install both packages explicitly so the application controls the resolved core version.
99
147
 
100
- UI 3.3 requires Core 2.3.0 or later within Core 2.x for independent rich-text
101
- measurement as well as BitmapText rendering and font resources. Core installs its published bitmap-font dependency automatically.
102
- Refresh older Core/UI lockfiles and old sheet manifests with
103
- string-valued `subkeys` in Kurot Editor before launching the application.
148
+ Run this command after UI 3.6.0 is published. Its Core ^2.5.2 minimum supplies
149
+ the public glyph metrics and unified alignment used by outline-safe Label layout,
150
+ in addition to centered flips and the native text APIs from earlier releases.
151
+ Core installs its published bitmap-font dependency automatically. Update Core
152
+ installations older than 2.5.2 when adopting UI 3.6.0.
153
+ For legacy projects, refresh sheet manifests with string-valued `subkeys` in
154
+ Kurot Editor before launching the application on Core 2.x.
104
155
  See the [resource migration guide](../ui-document/docs/resource-nine-slice.md).
105
156
 
157
+ Adopting 3.6.0 requires a UI installation/lock update and rebuild, plus an accepted
158
+ Core installation. Review outlined captions for the larger automatic dimensions
159
+ or earlier wraps. ui-runtime 0.10.0 accepts it through ^3.4.0; its development lock
160
+ may adopt it separately and its host must satisfy UI's Core peer. CLI/ui-document
161
+ need no release or XML migration. Editor currently pins registry UI 3.5.0 and
162
+ requires an explicit dependency update after publication. The selected Tentax
163
+ and MilfMaster templates' ^3.5.0 ranges and the game example's ^3.1.0 range accept
164
+ 3.6.0; their installations/locks and rebuilds are separate adoption steps.
165
+ This release preparation does not upgrade applications or other SDK locks.
166
+
106
167
  ## Project style colors
107
168
 
108
- CLI 3.3.0 resolves Label presets and named colors from the optional
169
+ Default artwork and XML skins belong to CLI game templates and the application,
170
+ not the UI runtime package. The CLI 3.6.0 [rounded KUI skin kit](../cli/docs/default-ui-skins.md)
171
+ replaces the template's EUI atlas without changing the component APIs or requiring
172
+ a UI package release. The kit needs published Core ^2.5.0; CLI 3.6.0 is also published. Existing applications keep their own theme resources.
173
+
174
+ CLI 3.5.0 resolves Label presets and named colors from the optional
109
175
  `resource/config/style.json` into native UI properties, including state overrides:
110
176
 
111
177
  ```xml
@@ -117,8 +183,8 @@ The Label belongs to a Skin declaring the `disabled` state. Native Skin state
117
183
  handling applies the compiled numeric color and restores the base color on
118
184
  leaving that state. The same reference syntax works for base color properties.
119
185
  UI does not read style.json or evaluate XML references itself; programmatic
120
- components assign numeric colors. This release does not introduce complete
121
- typography presets or automatic live theme switching. See the
186
+ components assign numeric colors. Label presets are expanded by CLI/document
187
+ consumers before rendering; UI itself provides no automatic live theme switching. See the
122
188
  [project style contract](../ui-document/docs/project-styles.md).
123
189
 
124
190
  ## Quick Start
@@ -192,8 +258,8 @@ transformed rectangle, including negative scale on either axis. A flipped Image
192
258
  with 100% width/height fills its parent allocation, rather than reverting to the
193
259
  texture dimensions. This behavior is shared by Group and Component subclasses.
194
260
  Local minima/maxima still apply; infeasible transformed aspect ratios fit within
195
- the allocation when the local minimum dimensions permit it. The 3.3.1 layout repair adds no new flip property
196
- is introduced by this correction.
261
+ the allocation when the local minimum dimensions permit it. Published UI 3.4.0
262
+ includes this repair alongside the independent centered-flip properties.
197
263
 
198
264
  ### Skin system
199
265
 
@@ -539,6 +605,7 @@ resource cache or caller retains ownership. Superseded async requests cannot
539
605
  replace a newer assignment. Successful named loads dispatch Event.COMPLETE;
540
606
  failed or incorrectly typed resources dispatch IOErrorEvent.IO_ERROR.
541
607
 
542
- The component supports native code and programmatic skins. Installed KUI
543
- compilers, the ui-document catalog, Editor and ui-runtime materializers do not
544
- yet adopt the BitmapLabel tag. Published UI 3.1.0 does not include the component.
608
+ The component supports native code and programmatic skins. Native KUI authoring
609
+ requires ui-document >= 0.12.0 and CLI >= 3.4.0; materialized previews require
610
+ ui-runtime >= 0.9.0. Editor adopts those contracts explicitly. Published UI 3.1.0
611
+ does not include BitmapLabel.
@@ -2,7 +2,7 @@ import { Component } from './Component.js';
2
2
  import { TextField } from '@kurot/core';
3
3
  import type { IDisplayText } from '../core/IDisplayText.js';
4
4
  /**
5
- * Optional single-line font fitting policy.
5
+ * Optional font fitting policy, independent of line generation.
6
6
  */
7
7
  export type TextFitMode = 'none' | 'shrink';
8
8
  /**
@@ -21,6 +21,10 @@ export declare class Label extends Component implements IDisplayText {
21
21
  private _textFitOverflow;
22
22
  private _fitKey?;
23
23
  constructor(text?: string);
24
+ get width(): number;
25
+ set width(value: number);
26
+ get height(): number;
27
+ set height(value: number);
24
28
  get text(): string;
25
29
  set text(value: string);
26
30
  get fontFamily(): string;
@@ -28,8 +32,8 @@ export declare class Label extends Component implements IDisplayText {
28
32
  get size(): number;
29
33
  set size(value: number);
30
34
  /**
31
- * Shrink applies only to noneditable, single-line text with finite bounds.
32
- * Multiline text retains the authored size; editable text rejects shrink.
35
+ * Shrink fits the laid-out text within finite bounds, retaining multiline.
36
+ * Editable text rejects shrink; automatic axes do not constrain fitting.
33
37
  */
34
38
  get textFit(): TextFitMode;
35
39
  set textFit(value: TextFitMode);
@@ -85,5 +89,6 @@ export declare class Label extends Component implements IDisplayText {
85
89
  setLayoutBoundsSize(layoutWidth: number, layoutHeight: number): void;
86
90
  updateDisplayList(unscaledWidth: number, unscaledHeight: number): void;
87
91
  private _applyTextFit;
92
+ private _getTextContentWidth;
88
93
  }
89
94
  //# sourceMappingURL=Label.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Label.d.ts","sourceRoot":"","sources":["../../../src/kurot/components/Label.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Label.d.ts","sourceRoot":"","sources":["../../../src/kurot/components/Label.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { Component } from './Component.js';
2
2
  import { TextField, TextFieldType } from '@kurot/core';
3
3
  import { fitLabelText } from '../text/fit-label-text.js';
4
+ import { getLabelOutlinePadding, getLabelTextHeight } from '../text/label-text-bounds.js';
4
5
  import { PropertyEvent } from '../events/PropertyEvent.js';
5
6
  /**
6
7
  * Label component for displaying text.
@@ -28,6 +29,24 @@ export class Label extends Component {
28
29
  this.text = text;
29
30
  }
30
31
  // ── Getters / Setters ─────────────────────────────────────────────────
32
+ get width() {
33
+ return super.width;
34
+ }
35
+ set width(value) {
36
+ if (Object.is(this.$explicitWidth, value))
37
+ return;
38
+ super.width = value;
39
+ this.invalidateSize();
40
+ }
41
+ get height() {
42
+ return super.height;
43
+ }
44
+ set height(value) {
45
+ if (Object.is(this.$explicitHeight, value))
46
+ return;
47
+ super.height = value;
48
+ this.invalidateSize();
49
+ }
31
50
  get text() {
32
51
  return this._textField.text;
33
52
  }
@@ -62,8 +81,8 @@ export class Label extends Component {
62
81
  }
63
82
  }
64
83
  /**
65
- * Shrink applies only to noneditable, single-line text with finite bounds.
66
- * Multiline text retains the authored size; editable text rejects shrink.
84
+ * Shrink fits the laid-out text within finite bounds, retaining multiline.
85
+ * Editable text rejects shrink; automatic axes do not constrain fitting.
67
86
  */
68
87
  get textFit() {
69
88
  return this._textFit;
@@ -232,6 +251,9 @@ export class Label extends Component {
232
251
  this._fitKey = undefined;
233
252
  this._textField?.invalidateTextMetrics();
234
253
  super.invalidateSize();
254
+ if (this.textFit === 'shrink') {
255
+ this.invalidateDisplayList();
256
+ }
235
257
  }
236
258
  createChildren() {
237
259
  super.createChildren();
@@ -256,8 +278,9 @@ export class Label extends Component {
256
278
  : NaN;
257
279
  this._applyTextFit(availableWidth, availableHeight);
258
280
  try {
259
- tf.width = availableWidth;
260
- this.setMeasuredSize(tf.textWidth, tf.textHeight);
281
+ tf.width = this._getTextContentWidth(availableWidth);
282
+ const outline = getLabelOutlinePadding(tf) * 2;
283
+ this.setMeasuredSize(tf.textWidth + outline, getLabelTextHeight(tf) + outline);
261
284
  }
262
285
  finally {
263
286
  tf.width = oldWidth;
@@ -296,13 +319,18 @@ export class Label extends Component {
296
319
  if (previousSize !== this.renderedSize && (isNaN(this.$explicitWidth) || isNaN(this.$explicitHeight))) {
297
320
  this.invalidateSize();
298
321
  }
299
- this._textField.width = unscaledWidth;
300
- this._textField.height = unscaledHeight;
322
+ // Measure, wrap, fit and paint reserve the same space exactly once. Core
323
+ // alignment remains authored and operates inside this inset text region.
324
+ const padding = getLabelOutlinePadding(this._textField);
325
+ this._textField.x = padding;
326
+ this._textField.y = padding;
327
+ this._textField.width = Math.max(0, unscaledWidth - padding * 2);
328
+ this._textField.height = Math.max(0, unscaledHeight - padding * 2);
301
329
  }
302
330
  // ── Private methods ────────────────────────────────────────────────────
303
331
  _applyTextFit(width, height) {
304
332
  const tf = this._textField;
305
- if (this.textFit !== 'shrink' || this.multiline || tf.type === TextFieldType.INPUT) {
333
+ if (this.textFit !== 'shrink' || tf.type === TextFieldType.INPUT) {
306
334
  tf.size = this._baseSize;
307
335
  this._textFitOverflow = false;
308
336
  this._fitKey = undefined;
@@ -310,7 +338,9 @@ export class Label extends Component {
310
338
  }
311
339
  const text = tf.displayAsPassword
312
340
  ? '*'.repeat(this.text.length)
313
- : this.text.split(/\r\n|[\n\r\v\f\u0085\u2028\u2029]/, 1)[0];
341
+ : this.multiline
342
+ ? this.text
343
+ : this.text.split(/\r\n|[\n\r\v\f\u0085\u2028\u2029]/, 1)[0];
314
344
  const key = JSON.stringify([
315
345
  text,
316
346
  tf.fontFamily,
@@ -319,6 +349,9 @@ export class Label extends Component {
319
349
  tf.bold,
320
350
  tf.italic,
321
351
  tf.stroke,
352
+ tf.multiline,
353
+ tf.wordWrap,
354
+ tf.lineSpacing,
322
355
  width,
323
356
  height,
324
357
  ]);
@@ -332,6 +365,9 @@ export class Label extends Component {
332
365
  bold: tf.bold,
333
366
  italic: tf.italic,
334
367
  stroke: tf.stroke,
368
+ multiline: tf.multiline,
369
+ wordWrap: tf.wordWrap,
370
+ lineSpacing: tf.lineSpacing,
335
371
  width,
336
372
  height,
337
373
  });
@@ -339,5 +375,9 @@ export class Label extends Component {
339
375
  this._textFitOverflow = fitted.overflow;
340
376
  this._fitKey = key;
341
377
  }
378
+ _getTextContentWidth(width) {
379
+ const outline = getLabelOutlinePadding(this._textField) * 2;
380
+ return Number.isFinite(width) ? Math.max(0, width - outline) : NaN;
381
+ }
342
382
  }
343
383
  //# sourceMappingURL=Label.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Label.js","sourceRoot":"","sources":["../../../src/kurot/components/Label.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Label.js","sourceRoot":"","sources":["../../../src/kurot/components/Label.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,9 @@ interface LabelTextMetrics {
6
6
  bold: boolean;
7
7
  italic: boolean;
8
8
  stroke: number;
9
+ multiline: boolean;
10
+ wordWrap: boolean;
11
+ lineSpacing: number;
9
12
  width: number;
10
13
  height: number;
11
14
  }
@@ -14,7 +17,7 @@ interface LabelTextFit {
14
17
  overflow: boolean;
15
18
  }
16
19
  /**
17
- * Fits one plain-text line within externally constrained logical bounds.
20
+ * Fits plain text using the same line generation as the rendered TextField.
18
21
  * A finite zero bound is meaningful; NaN represents an unconstrained axis.
19
22
  * Never changes authored size or text, and always measures from the base size.
20
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"fit-label-text.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/fit-label-text.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,UAAU,YAAY;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CA8BpE"}
1
+ {"version":3,"file":"fit-label-text.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/fit-label-text.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,UAAU,YAAY;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CA6CpE"}
@@ -1,17 +1,34 @@
1
- import { measureText } from '@kurot/core';
1
+ import { TextField } from '@kurot/core';
2
+ import { getLabelOutlinePadding, getLabelTextHeight } from './label-text-bounds.js';
2
3
  /**
3
- * Fits one plain-text line within externally constrained logical bounds.
4
+ * Fits plain text using the same line generation as the rendered TextField.
4
5
  * A finite zero bound is meaningful; NaN represents an unconstrained axis.
5
6
  * Never changes authored size or text, and always measures from the base size.
6
7
  */
7
8
  export function fitLabelText(metrics) {
9
+ if (!metrics.text)
10
+ return { size: metrics.size, overflow: false };
11
+ const field = new TextField();
12
+ field.text = metrics.text;
13
+ field.fontFamily = metrics.fontFamily;
14
+ field.bold = metrics.bold;
15
+ field.italic = metrics.italic;
16
+ field.multiline = metrics.multiline;
17
+ field.wordWrap = metrics.wordWrap;
18
+ field.lineSpacing = metrics.lineSpacing;
19
+ field.stroke = metrics.stroke;
20
+ const outline = getLabelOutlinePadding(field) * 2;
21
+ const width = Number.isFinite(metrics.width) ? Math.max(0, metrics.width - outline) : NaN;
8
22
  const fits = (size) => {
9
- const width = measureText(metrics.text, metrics.fontFamily, size, metrics.bold, metrics.italic);
10
- const outline = metrics.stroke * 2;
11
- return ((!Number.isFinite(metrics.width) || width + outline <= metrics.width) &&
12
- (!Number.isFinite(metrics.height) || size + outline <= metrics.height));
23
+ // Core intentionally measures zero-width content as empty, not as overflow.
24
+ if (width === 0)
25
+ return false;
26
+ field.size = size;
27
+ field.width = width;
28
+ return ((!Number.isFinite(metrics.width) || field.textWidth + outline <= metrics.width) &&
29
+ (!Number.isFinite(metrics.height) || getLabelTextHeight(field) + outline <= metrics.height));
13
30
  };
14
- if (!metrics.text || fits(metrics.size)) {
31
+ if (fits(metrics.size)) {
15
32
  return { size: metrics.size, overflow: false };
16
33
  }
17
34
  const minimum = Math.min(metrics.minimum, metrics.size);
@@ -31,6 +48,7 @@ export function fitLabelText(metrics) {
31
48
  upper = candidate;
32
49
  }
33
50
  }
34
- return { size: Math.max(minimum, Math.floor(lower * 10) / 10), overflow: false };
51
+ const size = Math.max(minimum, Math.floor(lower * 10) / 10);
52
+ return { size: fits(size) ? size : minimum, overflow: false };
35
53
  }
36
54
  //# sourceMappingURL=fit-label-text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fit-label-text.js","sourceRoot":"","sources":["../../../src/kurot/text/fit-label-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmB1C;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAyB;IACrD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAW,EAAE;QACtC,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAChG,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACnC,OAAO,CACN,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;YACrE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CACtE,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,IAAI,KAAK,GAAG,OAAO,CAAC;IACpB,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IACzB,wEAAwE;IACxE,mEAAmE;IACnE,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,IAAI,KAAK,GAAG,KAAK,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;QACtE,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACrB,KAAK,GAAG,SAAS,CAAC;QACnB,CAAC;aAAM,CAAC;YACP,KAAK,GAAG,SAAS,CAAC;QACnB,CAAC;IACF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAClF,CAAC"}
1
+ {"version":3,"file":"fit-label-text.js","sourceRoot":"","sources":["../../../src/kurot/text/fit-label-text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { TextField } from '@kurot/core';
2
+ /**
3
+ * Dynamic outlines need layout space inside external clips. Keep this allowance
4
+ * independent of glyphs so a typewriter prefix cannot move its drawing origin.
5
+ * Input retains its native editing viewport and empty Labels add no inset.
6
+ */
7
+ export declare function getLabelOutlinePadding(field: TextField): number;
8
+ /**
9
+ * Preserve nominal rows, including blanks, while containing the complete glyph
10
+ * block of an outlined Label. Core measurement itself remains nominal.
11
+ */
12
+ export declare function getLabelTextHeight(field: TextField): number;
13
+ //# sourceMappingURL=label-text-bounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label-text-bounds.d.ts","sourceRoot":"","sources":["../../../src/kurot/text/label-text-bounds.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,aAAa,CAAC;AAI3D;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAQ/D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAmB3D"}
@@ -0,0 +1,42 @@
1
+ import { TextFieldType } from '@kurot/core';
2
+ const heightCache = new WeakMap();
3
+ /**
4
+ * Dynamic outlines need layout space inside external clips. Keep this allowance
5
+ * independent of glyphs so a typewriter prefix cannot move its drawing origin.
6
+ * Input retains its native editing viewport and empty Labels add no inset.
7
+ */
8
+ export function getLabelOutlinePadding(field) {
9
+ if (field.type === TextFieldType.INPUT || !field.text || !Number.isFinite(field.stroke) || field.stroke <= 0) {
10
+ return 0;
11
+ }
12
+ if (!field.multiline && !field.displayAsPassword && /^[\n\r\v\f\u0085\u2028\u2029]/u.test(field.text)) {
13
+ return 0;
14
+ }
15
+ return Math.ceil(field.stroke * 2) + 2;
16
+ }
17
+ /**
18
+ * Preserve nominal rows, including blanks, while containing the complete glyph
19
+ * block of an outlined Label. Core measurement itself remains nominal.
20
+ */
21
+ export function getLabelTextHeight(field) {
22
+ const nominalHeight = field.textHeight;
23
+ if (getLabelOutlinePadding(field) === 0)
24
+ return nominalHeight;
25
+ const lines = field.getLinesArr();
26
+ const cached = heightCache.get(lines);
27
+ if (cached !== undefined)
28
+ return cached;
29
+ let top = Infinity;
30
+ let bottom = -Infinity;
31
+ let lineTop = 0;
32
+ for (const line of lines) {
33
+ const hasInk = line.inkAscent + line.inkDescent > 0;
34
+ top = Math.min(top, lineTop + (hasInk ? line.baseline - line.inkAscent : 0));
35
+ bottom = Math.max(bottom, lineTop + (hasInk ? line.baseline + line.inkDescent : line.height));
36
+ lineTop += line.height + field.lineSpacing;
37
+ }
38
+ const height = Math.max(nominalHeight, lines.length === 0 ? 0 : bottom - top);
39
+ heightCache.set(lines, height);
40
+ return height;
41
+ }
42
+ //# sourceMappingURL=label-text-bounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label-text-bounds.js","sourceRoot":"","sources":["../../../src/kurot/text/label-text-bounds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,WAAW,GAAG,IAAI,OAAO,EAA0B,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAgB;IACtD,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC9G,OAAO,CAAC,CAAC;IACV,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvG,OAAO,CAAC,CAAC;IACV,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IAClD,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC;IACvC,IAAI,sBAAsB,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IAExC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,IAAI,MAAM,GAAG,CAAC,QAAQ,CAAC;IACvB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpD,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9F,OAAO,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;IAC5C,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAC9E,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -1,19 +1,31 @@
1
1
  # @kurot/ui — AI context map
2
2
 
3
- Source prepares UI 3.4.0 and installs published Core 2.4.0 with a matching
4
- registry lockfile, without local overrides. The released baseline below is
5
- historical. Read
3
+ UI 3.6.0 is prepared for publication, not yet published. It adds outline-safe
4
+ Label layout to normal measurement, wrapping and fitting; outlined automatic
5
+ dimensions and line breaks can change. Its Core peer is ^2.5.2 for public line
6
+ ink metrics and unified block alignment. Development installs registry Core
7
+ 2.5.3 with a matching lock, without local overrides; the 2.5.2 minimum is tested
8
+ separately. Published UI 3.5.0 (verified on 2026-10-10) introduced multiline
9
+ Label fitting and stable alignment when fitting is toggled, with Core ^2.4.0. Read
6
10
  [centered flips](../../../docs/centered-flips.md) before changing transforms,
7
11
  reflection frames, authored flags or dependency adoption.
8
12
 
13
+ Label/RichLabel/EditableText inherit TextField's vertical alignment;
14
+ BitmapLabel inherits BitmapText's. Published Core 2.5.3 defaults both to middle;
15
+ published Core 2.5.2 and earlier default to top. Explicit values remain effective
16
+ and multiline only controls line generation. UI has no default override and needs
17
+ no new release for this default change alone. The separate UI 3.6.0 outline
18
+ correction requires Core ^2.5.2.
19
+ Published document 0.13.1 supplies matching authoring defaults.
20
+
9
21
  Read this before exploring `src/`. It is a compressed map so an agent
10
22
  unfamiliar with Kurot does not need to re-derive the architecture from scratch
11
23
  each session. Treat the package source and its `src/index.ts` barrel as the
12
24
  authority for current behavior and exports; this file provides the compressed
13
25
  map, runtime contracts and task→file lookup.
14
26
 
15
- Package identity: `@kurot/ui@3.4.0`, EUI-compatible UI framework on top of
16
- `@kurot/core`. Peer-depends on `@kurot/core@^2.4.0`. Rewritten with standard class
27
+ Package identity: `@kurot/ui@3.6.0` (prepared, unpublished), EUI-compatible UI framework on top of
28
+ `@kurot/core`. Its peer is `@kurot/core@^2.5.2`; published 3.5.0 uses ^2.4.0. Rewritten with standard class
17
29
  inheritance and delegation — no namespace mixins, no prototype copying.
18
30
  Version 3.3.1 is preserved in commit 60e6404 and fixes transformed parent
19
31
  allocations. It has not been published; UI 3.4.0 includes the same correction. Version 3.3.0 adds RichLabel and tests against published Core 2.3.1 through its
@@ -211,29 +223,49 @@ before patching core's transform code.
211
223
  | Understand validation/render scheduling order | `core/Validator.ts`, core `player/SystemTicker.ts` |
212
224
  | Measure UI validation/rendering performance | `examples/benchmark/` for the visual runner, scenarios, Playwright automation, and local JSON/Markdown reports |
213
225
 
214
- ## Label text layout contract in 3.1.0
226
+ ## Label text layout contract in 3.6.0
215
227
 
216
228
  Label defaults to multiline; explicit false draws only the first hard-separated
217
229
  line without wrapping. EditableText defaults to single-line and rejects
218
230
  shrinking. `wordWrap` chooses Unicode versus character boundaries only while
219
231
  multiline is enabled.
220
232
 
221
- `TextFitMode` is exported with Label. `textFit` is `none` by default or `shrink`
222
- for single-line Labels. `minFontSize` defaults to 12 and must be finite and >= 1.
233
+ `TextFitMode` is exported with Label. `textFit` is `none` by default or `shrink`.
234
+ UI 3.5.0 fits both line modes using complete Core measurement at each candidate
235
+ size; UI 3.1.0–3.4.0 fit only single-line Labels.
236
+ `multiline` stays authored and automatic axes stay unconstrained. Outline
237
+ allowance affected fit checks and shared wrapping width, not the original alignment
238
+ frame or nominal automatic dimensions in 3.5.0. UI 3.6.0
239
+ uses `text/label-text-bounds.ts` to reserve symmetric stroke/AA insets
240
+ and contain complete ink in automatic dimensions. Measurement, wrapping, fitting
241
+ and painting share this area. Empty/input fields add no inset. `minFontSize` defaults to
242
+ 12 and must be finite and >= 1.
223
243
  `size` stays authored; `renderedSize` and `textFitOverflow` are read-only results
224
244
  after validation. Fitting uses fixed axes, parent layout constraints or explicit
225
- maximums, reserves outline thickness and caches unchanged metrics. Measured
245
+ maximums, reserves outline thickness and caches unchanged metrics, including
246
+ multiline/wordWrap/lineSpacing. Measured
226
247
  automatic bounds are not fed back as fit constraints.
227
248
 
228
249
  `label.invalidateSize()` also invalidates Core line metrics. Call it after
229
250
  late font loading, even if the family name did not change. This requires
230
- Core >= 2.1.0 for that API; UI 3.3.0's package requirement is Core ^2.3.0.
251
+ Core >= 2.1.0 for that API; published UI 3.5.0 requires Core ^2.4.0 for centered
252
+ flips, while the UI 3.6.0 outline correction needs ^2.5.2.
253
+
254
+ Width/height setters refresh automatic text dimensions. Font readiness also
255
+ invalidates fitting in fixed-size boxes. Fitting toggles preserve unchanged text
256
+ positions, all nine alignments and outline-safe automatic dimensions.
231
257
  There is no global font-readiness listener.
232
258
 
259
+ Existing multiline `shrink` policies begin fitting upon adoption; no XML format
260
+ or authored-property migration is required. Runtime 0.10.0 accepts UI 3.6.0
261
+ through its existing ^3.4.0 peer; its host must also satisfy UI's Core ^2.5.2 peer.
262
+ CLI/document APIs are unchanged. After publication, consumers update their own
263
+ UI installations/locks and rebuild; no other SDK bump is needed.
264
+
233
265
  See [Label text layout](label-text-layout.md) for fit bounds, state restoration,
234
266
  font readiness and shared-schema boundaries. Native UI still depends only on
235
- Core; KUI authoring uses ui-document 0.11.x, published CLI 3.3.0 and
236
- published ui-runtime 0.8.2. Label presets expand in consumer-owned
267
+ Core; current KUI authoring uses document 0.13.1, CLI 3.6.0 and runtime 0.10.0.
268
+ Label presets expand in consumer-owned
237
269
  copies before native rendering; UI does not read style.json or consume textStyle.
238
270
 
239
271
  ## Bitmap labels in 3.2.0
@@ -257,4 +289,5 @@ wordWrap, lineSpacing, textAlign and verticalAlign remain component-level.
257
289
  Task → `components/RichLabel.ts`, `test/RichLabel.test.ts`,
258
290
  `test/browser/text-labels.spec.ts`. Run `pnpm test:text-labels` after building
259
291
  Core and UI. BitmapLabel automatic measurement now uses maxWidth too. The KUI
260
- catalog, CLI and Editor must adopt these native components in a later phase.
292
+ catalog is available in published ui-document 0.12.0+, CLI 3.4.0+ and
293
+ ui-runtime 0.9.0+. Editor adoption remains an explicit application update.
@@ -1,6 +1,6 @@
1
1
  # @kurot/ui architecture
2
2
 
3
- > Package version: 3.4.0 (unpublished), with peerDependency `@kurot/core: ^2.4.0`.
3
+ > Package version: 3.5.0 (published), with peerDependency `@kurot/core: ^2.4.0`.
4
4
  > Development installs published Core 2.4.0 with a matching registry lockfile.
5
5
  > No local Core override is needed for builds or centered-flip checks.
6
6
  > See [CHANGELOG.md](../CHANGELOG.md) for release-by-release changes.
@@ -11,6 +11,9 @@ width nor an explicit width is present, so wrapped height matches rendering.
11
11
  Changing an authored width also invalidates automatic height after layout.
12
12
  UI 3.3.0 builds and tests against published Core 2.3.1 without local overrides.
13
13
 
14
+ Current UI 3.5.0 retains BitmapLabel and requires Core ^2.4.0 for centered flips.
15
+ Its development installation and lock use published Core 2.4.0.
16
+
14
17
  ```ts
15
18
  import { BitmapLabel } from '@kurot/ui';
16
19
 
@@ -41,7 +44,15 @@ DisplayObject tint. Alignments position glyphs without scaling them. Set scaleX
41
44
  and scaleY for decorative number sizing. Default multiline=true; explicit false
42
45
  keeps the first hard-separated line unwrapped.
43
46
 
44
- Published ui-document 0.12.0, CLI 3.4.0 and ui-runtime 0.9.0 support BitmapLabel
47
+ Vertical alignment inherits BitmapText's default: middle with published Core 2.5.3,
48
+ top with published 2.5.2 and earlier. Explicit top/bottom remain effective in either
49
+ line mode. Bitmap-font metrics and glyph offsets are unchanged. UI 3.4.0 accepts
50
+ the patch without another UI release; applications update their Core installation/
51
+ lock and rebuild. Published document 0.13.1 supplies the matching
52
+ catalog default.
53
+
54
+ Authoring support was introduced in document 0.12.0, CLI 3.4.0 and runtime 0.9.0.
55
+ Current document 0.13.1, CLI 3.6.0 and runtime 0.10.0 retain BitmapLabel
45
56
  authoring, KUI compilation and materialization. Earlier compilers do not accept
46
57
  this built-in XML tag; update applications explicitly when adopting it. Editor
47
58
  controls are owned by the separate application.
@@ -1,15 +1,49 @@
1
1
  # Label text layout and fitting
2
2
 
3
- Introduced in UI 3.1.0 with Core >= 2.1.0, this contract is unchanged in UI 3.2.0,
4
- which requires Core ^2.2.0. The public
3
+ Introduced in UI 3.1.0 with Core >= 2.1.0, fitting is single-line in UI 3.1.0–3.4.0.
4
+ UI 3.5.0 extends it to multiline Labels using Core's existing independent
5
+ measurement API. Version 3.5.0 is published, verified on npm on 2026-10-10, with
6
+ Core ^2.4.0. UI 3.6.0 is prepared, not yet published; it adds outline-safe layout
7
+ and requires Core ^2.5.2. The public
5
8
  `TextFitMode` type is `none | shrink`. Native UI depends only on Core. KUI
6
9
  authoring introduced fitting metadata in ui-document 0.9.0 and retains it in
7
- 0.11.0. Published CLI 3.3.0 and ui-runtime 0.8.2 use ui-document `^0.11.0`.
8
- Runtime 0.8.0's `^0.9.0` and runtime 0.8.1's `^0.10.0` peer ranges exclude
9
- the current kernel. Label presets are expanded into native properties before
10
+ 0.13.1. Current CLI 3.6.0 and runtime 0.10.0 use document `^0.13.0`; runtime
11
+ also requires UI `^3.4.0` and Core `^2.4.0`. Older 0.x kernel ranges do not
12
+ automatically accept 0.13.0. Label presets expand into native properties before
10
13
  rendering; their precedence does not change fitting behavior. See the
11
14
  [project style contract](../../ui-document/docs/project-styles.md).
12
15
 
16
+ ## Outline-safe layout in 3.6.0
17
+
18
+ Nonempty dynamic Labels with a positive finite `stroke` reserve
19
+ `ceil(2 * stroke) + 2` logical pixels on each side. This conservative allowance
20
+ contains the stroke and antialiasing inside the Label's external layout box.
21
+ The TextField is inset by that fixed amount; it does not change with a typewriter
22
+ prefix or fitting candidate. Scroller clips remain exact, with no new setting.
23
+
24
+ Automatic width includes both insets. Automatic height contains nominal rows
25
+ (including blank rows and line spacing), the complete glyph block if taller,
26
+ and both insets. Fixed/parent/max dimensions remain the outer box; line generation
27
+ and fitting use its inner area. Minimum-size overflow still reports failure
28
+ and permits clipping; a box too small for its inset does not become automatic.
29
+ Fitting toggles at unchanged drawing size retain identical geometry and pixels.
30
+ Unoutlined or empty Labels add no inset; empty-row measurements stay native.
31
+ EditableText, RichLabel and BitmapLabel do not adopt this layout change.
32
+
33
+ Keep explicit `verticalAlign="top"` for progressively typed dialogue. The origin
34
+ stays fixed after clearing/retyping; middle alignment intentionally follows its
35
+ changing glyph block and is not appropriate for that effect. Font readiness still
36
+ uses `invalidateSize()`. Outline/state changes invalidate the normal UI layout.
37
+
38
+ UI 3.6.0 is prepared for publication. Outlined Labels can measure larger
39
+ and wrap earlier than 3.5.0 even without `textFit`. No authored
40
+ properties or XML/resource formats change. Its manifest requires Core
41
+ ^2.5.2 for public line ink metrics and unified vertical block alignment; development
42
+ installs published 2.5.3. Core itself needs no new release. After publication,
43
+ consumers must adopt UI 3.6.0, use an accepted Core installation and rebuild; compatible
44
+ CLI/document/runtime contracts need no new SDK release. Existing application
45
+ installations remain on their registry versions until explicitly updated.
46
+
13
47
  ## Lines and bounds
14
48
 
15
49
  - `Label.multiline` defaults to `true`. Text wraps at a finite available width;
@@ -33,6 +67,31 @@ Explicit `multiline="false"` in older skins now means a real single line.
33
67
  Remove it or set it to `true` for text intended to wrap. No files are migrated
34
68
  automatically; omitted Label flags continue to allow wrapping.
35
69
 
70
+ ## Vertical alignment and skin defaults
71
+
72
+ Label, RichLabel and EditableText inherit TextField's default; BitmapLabel
73
+ inherits BitmapText's. With published Core 2.5.3 they default to
74
+ `verticalAlign="middle"`. Published Core 2.5.2 and earlier default to top. Button
75
+ skins in the native KUI kit already set middle explicitly. Button does not
76
+ overwrite an authored top/bottom or a skin state. Use explicit top for content
77
+ intended to start at the top of a taller box. `verticalCenter` positions the
78
+ Label box in its parent; it does not align text inside the Label.
79
+
80
+ Published document 0.13.1 reports the new middle default without writing omitted
81
+ properties into XML. Adopting editors need matching Core/catalog installations;
82
+ UI 3.4.0 itself requires no release or higher peer minimum. Existing applications
83
+ retain their installed behavior until they update their locks and rebuild.
84
+
85
+ Published Core 2.5.2 makes dynamic top/middle/bottom use the same
86
+ complete glyph-block boundaries in single-line and multiline modes. Blank rows
87
+ retain their height. `multiline` controls only line generation. Input uses stable
88
+ editing-row boundaries in all three modes; its caret and selection remain stable.
89
+ Core measurements stay nominal; UI 3.6.0 reserves outline-safe
90
+ layout space separately. Older Core installations retain their
91
+ recorded text behavior; adopt the Core installation/lock and rebuild.
92
+ UI 3.4.0's peer accepts 2.5.2; this correction needs no UI release.
93
+ See [Core text layout](../../core/docs/text-layout.md#unified-vertical-alignment-core-252).
94
+
36
95
  ## Shrink to fit
37
96
 
38
97
  ```xml
@@ -41,24 +100,48 @@ automatically; omitted Label flags continue to allow wrapping.
41
100
  ```
42
101
 
43
102
  `textFit` accepts `none` (default) and `shrink`. Shrinking applies to ordinary
44
- single-line Labels. Multiline Labels retain their authored size; EditableText
45
- rejects `shrink`, including through the shared authoring schema. Put the policy
103
+ Labels in either line mode. `multiline` always chooses line generation; fitting
104
+ never changes it based on height or the selected size. EditableText rejects
105
+ `shrink`, including through the shared authoring schema. Put the policy
46
106
  on a Button's `labelDisplay` skin part rather than on the Button itself.
47
107
 
108
+ ```xml
109
+ <Label text="Доказуемая честность" width="120" height="44" size="20"
110
+ wordWrap="true" lineSpacing="2" textFit="shrink" minFontSize="14" />
111
+ ```
112
+
113
+ This uses the default multiline mode. At each candidate size, Core lays out
114
+ the complete displayed text under the effective content width. Measurement
115
+ includes hard breaks, blank/trailing rows and line spacing, independently of
116
+ height clipping. If the base size fits across several rows it is retained.
117
+ Otherwise fitting searches smaller sizes, recalculating the row breaks each time.
118
+ No maximum row count is implied by a fixed height, and no `maxLines` is added.
119
+
120
+ | Available bounds | Multiline shrink behavior |
121
+ | ----------------------------------- | ------------------------------------------------------------------------------------------- |
122
+ | Both automatic | Retain base size; soft wrapping has no width constraint. |
123
+ | Width constrained, height automatic | Wrap and measure automatic height; shrink only if a protected sequence still exceeds width. |
124
+ | Width automatic, height constrained | Measure hard-separated rows without soft wrapping, then fit their complete height. |
125
+ | Both constrained | Wrap and shrink as needed to fit complete width and height. |
126
+
48
127
  - `size` is always the authored/base size. `renderedSize` is the derived drawing
49
128
  size after layout validation. State overrides capture and restore `size`.
50
129
  - Fit starts from that base size on every metric change. Shorter text or a
51
130
  larger region restores the base size; text never grows beyond it.
52
131
  - `minFontSize` defaults to 12 logical pixels, must be finite and at least 1,
53
132
  and acts as a lower bound. A minimum above `size` never enlarges the text.
54
- - Measurement uses the displayed text, font family, bold and italic settings,
55
- and reserves twice the outline thickness on each constrained axis. The
56
- ordinary Core clipping and outline rendering rules remain in effect.
133
+ - Measurement uses displayed text, font family, bold/italic settings and the
134
+ outline-safe layout bounds described above. Search, automatic measurement and
135
+ drawing reserve the same inset once. Both alignments operate inside that area;
136
+ symmetric insets preserve the horizontal center. Automatic measurements are
137
+ never recycled as fitting constraints. The published 3.5.0 baseline reserved
138
+ only twice the stroke in fit checks and kept automatic dimensions nominal.
57
139
  - Available bounds come from fixed dimensions, parent layout constraints or
58
140
  explicit maximum dimensions. Icon spacing belongs to the skin's Label
59
141
  region. Automatic measured dimensions are not fed back as fit constraints.
60
142
  - A finite zero-sized region is constrained. An automatic axis is unconstrained.
61
- - Search performs at most 16 metric comparisons after the endpoint checks.
143
+ - Search performs at most 16 metric comparisons after the endpoint checks,
144
+ followed by verification of the rounded result.
62
145
  Intermediate results are rounded down to tenths of a logical pixel while
63
146
  retaining the minimum. Base sizes and minimums may be fractional.
64
147
  - If text still cannot fit at the minimum, `textFitOverflow` is true after
@@ -72,6 +155,21 @@ These two read-only results are runtime observations, not authored KUI fields.
72
155
  CLI emits the policy and base size; ui-runtime uses the same native Label. Neither
73
156
  writes the derived size into XML, styles, semantic documents or history.
74
157
 
158
+ Existing multiline Labels with an authored `shrink` policy begin fitting when
159
+ they adopt UI 3.5.0; the published 3.4.0 runtime ignored that
160
+ combination. Single-line hard-separator/password semantics remain effective.
161
+ Finite zero content width reports overflow for nonempty displayed text; it is
162
+ not mistaken for empty content by Core's zero-width measurement. Empty displayed
163
+ content retains its base size without overflow.
164
+
165
+ The 3.5.0 multiline extension required no Core or KUI-format change. The separate
166
+ 3.6.0 outline correction raises UI's Core minimum to ^2.5.2. CLI/runtime already
167
+ pass the fields through; runtime 0.10.0's ^3.4.0 peer accepts UI 3.6.0, provided
168
+ its host also satisfies UI's Core peer. Applications adopt the UI installation/lock
169
+ and rebuild explicitly after publication. Editor currently pins registry UI 3.5.0;
170
+ Tentax and MilfMaster accept 3.6.0 through ^3.5.0 but retain their existing locks.
171
+ Preview and compiled games use the native Label behavior once their host adopts it.
172
+
75
173
  Load fonts before constructing or measuring text where possible. If a font
76
174
  becomes ready later, call `label.invalidateSize()` before the next validation;
77
175
  this clears both fitting and Core line metrics even when the family name stays
@@ -97,3 +195,19 @@ single-line fitting, Unicode wrapping without leading separator spaces, outline
97
195
  allowance, minimum overflow, native Button state restoration and invalidation
98
196
  after a font finishes loading. Fitted sizes are platform-dependent; these checks
99
197
  assert the layout contract rather than a universal numeric result.
198
+
199
+ Multiline tests cover complete-height fitting, blank/trailing rows, line spacing,
200
+ Unicode and grapheme boundaries, password text, minimum/zero-width overflow,
201
+ outline allowance, automatic axes, font readiness and parent resize recovery.
202
+ Minified browser tests validate native Russian/Chinese layouts in Canvas,
203
+ WebGL 1 and WebGL 2 at 1x/2x, using independent Canvas width measurements.
204
+ Pixel comparisons verify unchanged painting across fitting toggles for all nine
205
+ horizontal/vertical alignments and automatic dimensions; icon-and-caption row
206
+ tests retain parent geometry.
207
+
208
+ UI 3.6.0 adds exact clipped/unclipped pixel comparisons in real
209
+ Scroller viewports, across all nine alignments, italic text, thick outlines,
210
+ automatic/fixed/maximum/fitted bounds, and Japanese scroll tails. Minified Canvas,
211
+ WebGL 1 and WebGL 2 tests use physical 1x/2x targets. Unit tests additionally
212
+ cover glyphs taller than nominal rows, state outline restoration, late fonts,
213
+ empty text, EditableText isolation and repeated top-aligned typewriter prefixes.
@@ -3,6 +3,9 @@
3
3
  Native API introduced in UI 3.3.0, requiring Core ^2.3.0. Core 2.3.1 is
4
4
  published and installed from npm for this release's build and verification.
5
5
 
6
+ Current UI 3.5.0 retains RichLabel and requires Core ^2.4.0 for centered flips.
7
+ Its development installation and lock use published Core 2.4.0.
8
+
6
9
  ```ts
7
10
  import { RichLabel } from '@kurot/ui';
8
11
 
@@ -43,9 +46,15 @@ available, together with these text-layout properties:
43
46
  | wordWrap | true | Unicode line-break opportunities; false wraps between graphemes. |
44
47
  | lineSpacing | 0 | Finite, nonnegative distance between lines. |
45
48
  | textAlign | left | left, center or right. |
46
- | verticalAlign | top | top, middle or bottom. |
49
+ | verticalAlign | Host Core | top, middle or bottom. |
47
50
  | textWidth / textHeight | Read-only | Complete content metrics under the current width, before height clipping. |
48
51
 
52
+ Vertical alignment inherits TextField's default: middle with published Core 2.5.3,
53
+ top with published 2.5.2 and earlier. Explicit values remain effective in either
54
+ line mode. UI 3.4.0 accepts the Core patch without another UI release; adopt the
55
+ application installation/lock and rebuild. Published document
56
+ 0.13.1 supplies the matching catalog default.
57
+
49
58
  Measurement uses parent-assigned width first, then explicit width, then a
50
59
  configured maxWidth, otherwise unconstrained width. Automatic height includes
51
60
  every wrapped line and inter-line spacing. Each line uses the largest font size
@@ -67,7 +76,8 @@ call `label.invalidateSize()` to clear both component and native text metrics,
67
76
  then allow normal layout validation. RichLabel does not load font files or
68
77
  install global font-loading listeners.
69
78
 
70
- Published ui-document 0.12.0, CLI 3.4.0 and ui-runtime 0.9.0 provide RichLabel
79
+ Authoring support was introduced in document 0.12.0, CLI 3.4.0 and runtime 0.9.0.
80
+ Current document 0.13.1, CLI 3.6.0 and runtime 0.10.0 retain RichLabel
71
81
  authoring, KUI compilation and materialization. Earlier versions lack these
72
82
  built-in registrations. Editor controls are owned by the separate application;
73
83
  all consumers retain textFlow ownership and separation from Label presets.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurot/ui",
3
- "version": "3.4.0",
3
+ "version": "3.6.0",
4
4
  "description": "EUI-compatible UI component framework for the Kurot game engine — skin-based components, layouts, data binding, view states",
5
5
  "author": "Kelvin <kyia.x52@gmail.com>",
6
6
  "license": "MIT",
@@ -34,10 +34,10 @@
34
34
  "test:text-labels": "playwright test test/browser --workers=1"
35
35
  },
36
36
  "peerDependencies": {
37
- "@kurot/core": "^2.4.0"
37
+ "@kurot/core": "^2.5.2"
38
38
  },
39
39
  "devDependencies": {
40
- "@kurot/core": "^2.4.0",
40
+ "@kurot/core": "^2.5.2",
41
41
  "@playwright/test": "1.62.1",
42
42
  "@types/node": "^22.0.0",
43
43
  "esbuild": "^0.28.2",