feat(dashboard): restyle Mijn aanvragen / Wat moet ik regelen as a CIBG keuzelijst
Both sections offer a set of choices the user picks between to proceed, matching
designsystem.cibg.nl/componenten/keuzelijst rather than the "aanvragen" row pattern
("Wat wilt u doen?" keeps that look — it's a static nav list, not a choice list).
- New shared/ui molecules: choice-list (heading + keuzelijst__list, wired via
aria-labelledby per CIBG's a11y guidance) and choice-link (one keuzelijst__link
choice; routerLink, imperative-clickable, or a plain non-interactive block).
- choice-link's non-interactive block needed a `--static` modifier: CIBG's
`.keuzelijst__link:after`/`:hover`/`:focus` key off the bare class (keuzelijst
assumes every item is a link), unlike `.applications li a::after` which is scoped
to the anchor — without it, a non-actionable aanvraag row inherited a chevron and
hover accent it shouldn't have.
- task-list.component.ts now composes choice-list/choice-link internally; public
API unchanged except a new required `listHeading` input (the heading moves inside
the list for the aria-labelledby link, so dashboard.page.ts stops rendering it
separately — same fix applied to "Mijn aanvragen").
- aanvraag-block.component.ts moves from application-link to choice-link, combining
its separate status/subtitle text into one instructions paragraph (keuzelijst has
no cta field — the row itself is the action). Only a resumable Concept renders as
a real choice; InBehandeling/Goedgekeurd/Afgewezen stay non-interactive, unchanged
from before.
Verified: lint/check:tokens/build green, 178 tests pass, build-storybook succeeds,
and manually driven end-to-end (dashboard renders both sections as keuzelijst cards,
confirmed via screenshot that non-actionable rows have no chevron after the fix).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Component, input } from '@angular/core';
|
||||
import { LinkComponent } from '@shared/ui/link/link.component';
|
||||
import { ChoiceListComponent } from '@shared/ui/choice-list/choice-list.component';
|
||||
import { ChoiceLinkComponent } from '@shared/ui/choice-link/choice-link.component';
|
||||
|
||||
/** Presentational task shape — what "Wat moet ik regelen" renders. Domain-free so
|
||||
shared/ stays independent of any context (a context's task type that has these
|
||||
@@ -12,40 +13,21 @@ export interface TaskItem {
|
||||
}
|
||||
|
||||
/** Molecule: the "Wat moet ik regelen" action list (NL Design System "Mijn
|
||||
omgeving" pattern). Each task is a titled row with a call to action. */
|
||||
omgeving" pattern), rendered as a CIBG Huisstijl "keuzelijst" — each task is a
|
||||
choice the user picks to resolve it. `actionLabel` has no keuzelijst equivalent
|
||||
(the whole row is the action; the chevron already implies "ga verder"). */
|
||||
@Component({
|
||||
selector: 'app-task-list',
|
||||
imports: [LinkComponent],
|
||||
styles: [`
|
||||
:host{display:block}
|
||||
.tasks{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--rhc-space-max-md)}
|
||||
.task{
|
||||
display:flex;flex-wrap:wrap;gap:var(--rhc-space-max-md) var(--rhc-space-max-xl);
|
||||
align-items:center;justify-content:space-between;
|
||||
background:var(--rhc-color-wit);
|
||||
border:var(--rhc-border-width-sm) solid var(--rhc-color-border-subtle);
|
||||
border-inline-start:var(--rhc-border-width-md) solid var(--rhc-color-lintblauw-700);
|
||||
border-radius:var(--rhc-border-radius-md);
|
||||
padding:var(--rhc-space-max-lg) var(--rhc-space-max-xl);
|
||||
}
|
||||
.title{margin:0 0 var(--rhc-space-max-xs);font-weight:var(--rhc-text-font-weight-semi-bold)}
|
||||
.desc{margin:0;color:var(--rhc-color-foreground-subtle);font-size:var(--rhc-text-font-size-sm)}
|
||||
.cta{flex:0 0 auto}
|
||||
`],
|
||||
imports: [ChoiceListComponent, ChoiceLinkComponent],
|
||||
template: `
|
||||
<ul class="tasks">
|
||||
<app-choice-list [heading]="listHeading()">
|
||||
@for (t of tasks(); track t.title) {
|
||||
<li class="task">
|
||||
<div>
|
||||
<p class="title">{{ t.title }}</p>
|
||||
<p class="desc">{{ t.description }}</p>
|
||||
</div>
|
||||
<span class="cta"><app-link [to]="t.to">{{ t.actionLabel }} →</app-link></span>
|
||||
</li>
|
||||
<app-choice-link [heading]="t.title" [instructions]="t.description" [to]="t.to" />
|
||||
}
|
||||
</ul>
|
||||
</app-choice-list>
|
||||
`,
|
||||
})
|
||||
export class TaskListComponent {
|
||||
listHeading = input.required<string>();
|
||||
tasks = input.required<readonly TaskItem[]>();
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@ const meta: Meta<TaskListComponent> = {
|
||||
title: 'Molecules/Task List',
|
||||
component: TaskListComponent,
|
||||
decorators: [applicationConfig({ providers: [provideRouter([])] })],
|
||||
render: (args) => ({ props: args, template: `<app-task-list [tasks]="tasks" />` }),
|
||||
render: (args) => ({ props: args, template: `<app-task-list [listHeading]="listHeading" [tasks]="tasks" />` }),
|
||||
};
|
||||
export default meta;
|
||||
type Story = StoryObj<TaskListComponent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
listHeading: 'Wat moet ik regelen',
|
||||
tasks: [
|
||||
{ title: 'Vraag uw herregistratie aan', description: 'Verleng uw registratie vóór 31 december 2026.', to: '/herregistratie', actionLabel: 'Herregistratie aanvragen' },
|
||||
{ title: 'Controleer uw adresgegevens', description: 'Uw adres is langer dan een jaar niet bevestigd.', to: '/registratie', actionLabel: 'Bekijk uw gegevens' },
|
||||
|
||||
Reference in New Issue
Block a user