feat(fp): WP-10 — CIBG button fidelity

Fix button atom's dead .btn-outline-primary → .btn-secondary; add 'ghost'
variant (.btn-ghost, CIBG-documented). RTE toolbar drops invented
.btn-outline-secondary/.btn-sm for .btn-ghost. file-input already used the
correct vendored .btn-upload pattern from the earlier CIBG UI fidelity
pass — no change needed there (documented as a deviation).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 22:34:28 +02:00
parent 8078c499cb
commit 69880efd38
5 changed files with 35 additions and 24 deletions

View File

@@ -1,8 +1,17 @@
# WP-10 — CIBG button fidelity # WP-10 — CIBG button fidelity
Status: todo Status: done (<pending commit>)
Phase: 2 — CIBG fidelity Phase: 2 — CIBG fidelity
> **Deviation:** file-input's label-button was already reworked to `.btn-primary
> .btn-upload` by the earlier out-of-order "CIBG UI fidelity pass" (WP-11/12) — the
> vendored upload vocabulary (`.btn-upload`) supersedes this WP's original
> `.btn-secondary` assumption, so no change was needed there. Icon affordances
> (chevron/pijl classes) are verified present in the vendored CSS, but no in-scope
> button (atom, file-input, RTE toolbar) currently has a next/previous affordance to
> attach one to — skipped as not applicable, not recorded as a gap (nothing hand-rolled
> to mark).
## Why ## Why
The vendored CIBG build ships `.btn-primary / .btn-secondary / .btn-danger / .btn-ghost / The vendored CIBG build ships `.btn-primary / .btn-secondary / .btn-danger / .btn-ghost /
@@ -46,9 +55,9 @@ and render as unstyled Bootstrap defaults instead of CIBG buttons.
## Acceptance criteria ## Acceptance criteria
- [ ] `grep -rn "btn-outline\|btn-sm" src/app` → empty. - [x] `grep -rn "btn-outline\|btn-sm" src/app` → empty.
- [ ] Button story shows all CIBG variants incl. ghost; visuals match the design system. - [x] Button story shows all CIBG variants incl. ghost; visuals match the design system.
- [ ] Axe still green (contrast can change with real button styles). - [x] Axe still green (contrast can change with real button styles).
## Verification ## Verification

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
import { Component, input } from '@angular/core'; import { Component, input } from '@angular/core';
type Variant = 'primary' | 'secondary' | 'subtle' | 'danger'; type Variant = 'primary' | 'secondary' | 'subtle' | 'danger' | 'ghost';
/** Atom: button. Thin wrapper over the CIBG/Bootstrap button CSS. */ /** Atom: button. Thin wrapper over the CIBG/Bootstrap button CSS. */
@Component({ @Component({
@@ -11,9 +11,10 @@ type Variant = 'primary' | 'secondary' | 'subtle' | 'danger';
[disabled]="disabled()" [disabled]="disabled()"
class="btn" class="btn"
[class.btn-primary]="variant() === 'primary'" [class.btn-primary]="variant() === 'primary'"
[class.btn-outline-primary]="variant() === 'secondary'" [class.btn-secondary]="variant() === 'secondary'"
[class.btn-link]="variant() === 'subtle'" [class.btn-link]="variant() === 'subtle'"
[class.btn-danger]="variant() === 'danger'" [class.btn-danger]="variant() === 'danger'"
[class.btn-ghost]="variant() === 'ghost'"
> >
<ng-content /> <ng-content />
</button> </button>

View File

@@ -16,4 +16,5 @@ export const Primary: Story = { args: { variant: 'primary' } };
export const Secondary: Story = { args: { variant: 'secondary' } }; export const Secondary: Story = { args: { variant: 'secondary' } };
export const Subtle: Story = { args: { variant: 'subtle' } }; export const Subtle: Story = { args: { variant: 'subtle' } };
export const Danger: Story = { args: { variant: 'danger' } }; export const Danger: Story = { args: { variant: 'danger' } };
export const Ghost: Story = { args: { variant: 'ghost' } };
export const Disabled: Story = { args: { variant: 'primary', disabled: true } }; export const Disabled: Story = { args: { variant: 'primary', disabled: true } };

View File

@@ -95,7 +95,7 @@ export interface PlaceholderOption {
<div class="rte-toolbar" role="toolbar" [attr.aria-label]="toolbarLabel()"> <div class="rte-toolbar" role="toolbar" [attr.aria-label]="toolbarLabel()">
<button <button
type="button" type="button"
class="btn btn-outline-secondary btn-sm" class="btn btn-ghost"
(mousedown)="$event.preventDefault()" (mousedown)="$event.preventDefault()"
(click)="format('bold')" (click)="format('bold')"
[attr.aria-label]="boldLabel()" [attr.aria-label]="boldLabel()"
@@ -104,7 +104,7 @@ export interface PlaceholderOption {
</button> </button>
<button <button
type="button" type="button"
class="btn btn-outline-secondary btn-sm" class="btn btn-ghost"
(mousedown)="$event.preventDefault()" (mousedown)="$event.preventDefault()"
(click)="format('italic')" (click)="format('italic')"
[attr.aria-label]="italicLabel()" [attr.aria-label]="italicLabel()"
@@ -113,7 +113,7 @@ export interface PlaceholderOption {
</button> </button>
<button <button
type="button" type="button"
class="btn btn-outline-secondary btn-sm" class="btn btn-ghost"
(mousedown)="$event.preventDefault()" (mousedown)="$event.preventDefault()"
(click)="format('underline')" (click)="format('underline')"
[attr.aria-label]="underlineLabel()" [attr.aria-label]="underlineLabel()"
@@ -123,7 +123,7 @@ export interface PlaceholderOption {
<span class="rte-sep" aria-hidden="true"></span> <span class="rte-sep" aria-hidden="true"></span>
<button <button
type="button" type="button"
class="btn btn-outline-secondary btn-sm" class="btn btn-ghost"
(mousedown)="$event.preventDefault()" (mousedown)="$event.preventDefault()"
(click)="list('bullet')" (click)="list('bullet')"
[attr.aria-label]="bulletListLabel()" [attr.aria-label]="bulletListLabel()"
@@ -132,7 +132,7 @@ export interface PlaceholderOption {
</button> </button>
<button <button
type="button" type="button"
class="btn btn-outline-secondary btn-sm" class="btn btn-ghost"
(mousedown)="$event.preventDefault()" (mousedown)="$event.preventDefault()"
(click)="list('number')" (click)="list('number')"
[attr.aria-label]="numberListLabel()" [attr.aria-label]="numberListLabel()"