Skip to content

fix(dl)!: errors following a full review of the component (#DS-5482) - #1995

Draft
artembelik wants to merge 2 commits into
mainfrom
fix/dl-attributes
Draft

fix(dl)!: errors following a full review of the component (#DS-5482)#1995
artembelik wants to merge 2 commits into
mainfrom
fix/dl-attributes

Conversation

@artembelik

Copy link
Copy Markdown
Contributor

What

The audit pass over the seven components that were already signal-based. Six of them needed no changeactions-panel, dynamic-translation, overflow-items, resizer, skeleton and content-panel are already compliant on signal inputs, booleanAttribute / numberAttribute, _IdGenerator, protected for template members, readonly on injections, and @docs-private. This PR is the one component where the audit found something.

Five inputs never got a coercion transform

readonly verticalBreakpoint = input(400, { transform: numberAttribute });
readonly minWidth = input<number | undefined>();          // no transform
readonly wide = input(false);                              // no transform
readonly resizable = input(false, { transform: booleanAttribute });
readonly vertical = input<boolean | null>(null);           // no transform

So <kbq-dl wide> and <kbq-dl vertical> did nothing — a valueless attribute passes the empty string, which is falsy — while <kbq-dl resizable> on the line above worked. That inconsistency inside one class is the whole finding.

vertical is tri-state, so booleanAttribute alone was wrong

null means "decide from verticalBreakpoint", and booleanAttribute(null) is false. It uses a transform that passes null through and coerces everything else, so the auto mode survives and <kbq-dl vertical> means true.

The numeric ones

minWidth, dtMinWidth and ddMinWidth report number | undefined — what an unbound description list always held. A static attribute used to reach the layout arithmetic as a string, which coerced in the <= comparison but not in Math.max.

Migration

dl-attribute-coercion runs from ng update @koobiq/components@20. Warn-only: whether markup relied on a valueless wide being ignored is a decision the call site owns.

It reads templates in both .html files and inline .ts templates, since <kbq-dl> is written in either.

Documented in docs/guides/migration.{en,ru}.md, section 18.

Testing

  • dl.component.spec.ts: 34 → 39 tests. The valueless wide and vertical attributes, null surviving as the vertical default, the coerced numeric attributes, and the unbound optional widths.
  • dl-attribute-coercion/index.spec.ts: 6 tests, including one that a bound [wide] is not reported.
  • Full packages/components (5166 tests) and packages/schematics (488 tests) suites pass.
  • check-api is in sync.

BREAKING CHANGE

🤖 Generated with Claude Code

`KbqDlComponent` was already fully signal-based, so there was nothing to migrate.
What the review found were the five inputs that never got a coercion transform,
sitting next to siblings that had one:

    readonly verticalBreakpoint = input(400, { transform: numberAttribute });
    readonly minWidth = input<number | undefined>();          // no transform
    readonly wide = input(false);                              // no transform

So `<kbq-dl wide>` and `<kbq-dl vertical>` did nothing — a valueless attribute
passes the empty string, which is falsy — while `<kbq-dl resizable>` right next
to it worked.

`vertical` is tri-state: `null` means "decide from `verticalBreakpoint`".
`booleanAttribute` would have folded that into `false`, so it uses a transform
that preserves null.

`minWidth`, `dtMinWidth` and `ddMinWidth` report `number | undefined`, which is
what an unbound description list always held.

BREAKING CHANGE: a valueless `wide` or `vertical` attribute on `<kbq-dl>` now
means true where it used to be ignored, and `minWidth`, `dtMinWidth` and
`ddMinWidth` are numeric inputs reporting `number | undefined`. Reported by the
`dl-attribute-coercion` schematic.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added bug Something isn't working breaking changes labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 29a0448):

https://koobiq-next--prs-1995-dy1hd4pv.web.app

(expires Mon, 07 Sep 2026 08:57:57 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

The breakpoint comparison only ever ran on resize, so changing `verticalBreakpoint`,
`minWidth` or `vertical` left the layout on the answer computed for the previous
values — including `vertical` going back to null, which handed the decision to a
stale `autoVertical`. Now re-evaluated from an effect on those three inputs.

The effect defers to the resize subscription for the first measurement. Wiring it
without that guard collapsed the list to vertical on init: the host has no box
before layout, so a zero width compares below every breakpoint — five existing
tests caught it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking changes bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant