@ndwnu/design-system 13.1.0 → 13.2.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/CLAUDE.md +1525 -0
- package/assets/images/flags/de.svg +1 -0
- package/assets/images/flags/en.svg +1 -0
- package/assets/images/flags/fr.svg +1 -0
- package/assets/images/flags/nl.svg +1 -0
- package/fesm2022/ndwnu-design-system.mjs +71 -18
- package/fesm2022/ndwnu-design-system.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/components/_datepicker.scss +13 -0
- package/types/ndwnu-design-system.d.ts +30 -7
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,1525 @@
|
|
|
1
|
+
# @ndwnu/design-system
|
|
2
|
+
|
|
3
|
+
> **Guidelines version**: Written for `@ndwnu/design-system@13.1.1` (2026-05-01). If your installed version is newer, check the [CHANGELOG](./CHANGELOG.md) for additions or breaking changes since this version.
|
|
4
|
+
|
|
5
|
+
Angular component library for NDW (Nationaal Dataportaal Wegverkeer) applications. Install via `npm install @ndwnu/design-system`.
|
|
6
|
+
|
|
7
|
+
## Rules
|
|
8
|
+
|
|
9
|
+
- **Always use NDW components** instead of native HTML or Material components when an NDW equivalent exists.
|
|
10
|
+
- **Always use NDW CSS custom properties** for colors (`--ndw-color-*`), spacing (`--ndw-spacing-*`), typography (`--ndw-font-*`), borders, and elevation. Never hardcode values.
|
|
11
|
+
- **Always use NDW utility CSS classes** for typography (`.ndw-heading-*`, `.ndw-paragraph-*`), grid layout (`.ndw-grid`, `.ndw-c-grid`), and directives (`[ndwButton]`, `[ndwInput]`, `[ndwLink]`, `[ndwLabel]`, `[ndwDivider]`).
|
|
12
|
+
- **Always use NDW SCSS mixins** for typography in component SCSS files (`@include ndw-heading-xl`, `@include ndw-paragraph-md`, etc.).
|
|
13
|
+
- **Import the global stylesheet** in your `angular.json` styles array to get all base styles, component styles, layout, and utilities.
|
|
14
|
+
- **Themes**: Default theme is NDW (orange primary). NWB theme is available via `data-theme="nwb"` on `<html>`.
|
|
15
|
+
- **Angular signals & OnPush**: All NDW components use `ChangeDetectionStrategy.OnPush`. Follow the same conventions in your own components: use `input()` / `input.required()` instead of `@Input()`, `output()` instead of `@Output()`, `model()` for two-way bindings, `signal()` / `computed()` for local state, `inject()` instead of constructor injection, and `viewChild()` / `contentChildren()` for queries. Never use `@Component({ changeDetection: ChangeDetectionStrategy.Default })` — always set `OnPush`. Avoid manual `ChangeDetectorRef.detectChanges()` / `markForCheck()` calls; signals handle reactivity automatically.
|
|
16
|
+
- **Never use inline styles**: Do not use `style="..."` in HTML templates. If you need sizing, spacing, or colors, first check if an NDW component attribute (e.g., `large` on `[ndwButton]` for 40px height), CSS custom property (`--ndw-spacing-*`), or utility class already covers it. If exact values don't exist but something close does (e.g., you want 42px but `large` gives 40px), prefer the design system value — consistency matters more than pixel-perfection. Only if nothing fits, create a CSS class in the component's SCSS file using NDW tokens.
|
|
17
|
+
- **Accessibility (a11y)**: Always ensure WCAG 2.1 AA compliance:
|
|
18
|
+
- **Color contrast**: Never rely on color alone to convey meaning. Ensure text meets minimum contrast ratios (4.5:1 for normal text, 3:1 for large text) against its background. When combining NDW color tokens, verify contrast — e.g., don't place `grey-400` text on `grey-100` backgrounds.
|
|
19
|
+
- **ARIA labels**: Many NDW components accept `ariaLabel` inputs (e.g., `ndw-badge`, `ndw-map-button`, `ndw-form-field`), but for custom or composed UI you must add ARIA attributes yourself. Always add `aria-label` or `aria-labelledby` to icon-only buttons, interactive elements without visible text, and landmark regions. Use `aria-live` regions for dynamic content updates (toasts, alerts, loaders). Add `aria-describedby` to link form fields to their error/help messages when not using `ndw-form-field`.
|
|
20
|
+
- **Semantic HTML**: Use the correct HTML elements (`<nav>`, `<main>`, `<section>`, `<aside>`, `<h1>`–`<h6>`) for structure. Don't use `<div>` or `<span>` for interactive elements — use `<button>` or `<a>`. Use the `sr-only` utility class to provide screen-reader-only text where visual context is obvious but programmatic context is missing.
|
|
21
|
+
- **Keyboard navigation**: Ensure all interactive elements are reachable and operable via keyboard. Use `tabindex` only when native tab order is insufficient. Never set `tabindex` > 0. Ensure custom dropdowns, modals, and popovers trap focus correctly and support Escape to close.
|
|
22
|
+
|
|
23
|
+
## Global Styles Setup
|
|
24
|
+
|
|
25
|
+
Component styles (e.g. `ndw-card`, `ndw-alert`) are encapsulated and work automatically after importing the component.
|
|
26
|
+
|
|
27
|
+
The global stylesheet provides CSS custom properties (colors, spacing, typography variables), utility classes (`.ndw-heading-*`, `.ndw-grid`), and directive styles (`[ndwButton]`, `[ndwInput]`, `[ndwLink]`, `[ndwLabel]`, `[ndwDivider]`). Add it to your `angular.json`:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
// angular.json > projects > your-app > architect > build > options > styles
|
|
31
|
+
"styles": [
|
|
32
|
+
"./node_modules/@ndwnu/design-system/styles/index.scss"
|
|
33
|
+
]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## CSS Custom Properties
|
|
39
|
+
|
|
40
|
+
### Spacing
|
|
41
|
+
|
|
42
|
+
| Variable | Value |
|
|
43
|
+
| ------------------- | -------------- |
|
|
44
|
+
| `--ndw-spacing-3xs` | 0.125rem (2px) |
|
|
45
|
+
| `--ndw-spacing-2xs` | 0.25rem (4px) |
|
|
46
|
+
| `--ndw-spacing-xs` | 0.5rem (8px) |
|
|
47
|
+
| `--ndw-spacing-sm` | 0.75rem (12px) |
|
|
48
|
+
| `--ndw-spacing-md` | 1rem (16px) |
|
|
49
|
+
| `--ndw-spacing-lg` | 1.5rem (24px) |
|
|
50
|
+
| `--ndw-spacing-xl` | 2rem (32px) |
|
|
51
|
+
| `--ndw-spacing-2xl` | 2.5rem (40px) |
|
|
52
|
+
| `--ndw-spacing-3xl` | 3rem (48px) |
|
|
53
|
+
| `--ndw-spacing-4xl` | 5rem (80px) |
|
|
54
|
+
| `--ndw-spacing-5xl` | 8rem (128px) |
|
|
55
|
+
|
|
56
|
+
### Colors
|
|
57
|
+
|
|
58
|
+
**Grey scale**: `--ndw-color-grey-50` through `--ndw-color-grey-700`, `--ndw-color-white`
|
|
59
|
+
|
|
60
|
+
**Primary** (NDW: orange, NWB: teal): `--ndw-color-primary-050` through `--ndw-color-primary-800`
|
|
61
|
+
|
|
62
|
+
- Shortcuts: `--ndw-color-primary`, `--ndw-color-primary-hover`, `--ndw-color-primary-active`
|
|
63
|
+
|
|
64
|
+
**Secondary** (NDW: blue, NWB: pink): `--ndw-color-secondary-050` through `--ndw-color-secondary-700`
|
|
65
|
+
|
|
66
|
+
- Shortcuts: `--ndw-color-secondary`, `--ndw-color-secondary-hover`, `--ndw-color-secondary-active`
|
|
67
|
+
|
|
68
|
+
**Tertiary**: `--ndw-color-tertiary-400`, `--ndw-color-tertiary-500`
|
|
69
|
+
|
|
70
|
+
**Links**: `--ndw-color-link-400`, `--ndw-color-link-500`
|
|
71
|
+
|
|
72
|
+
**Feedback**:
|
|
73
|
+
|
|
74
|
+
- Positive: `--ndw-color-positive-100` to `--ndw-color-positive-600`
|
|
75
|
+
- Warning: `--ndw-color-warning-100` to `--ndw-color-warning-600`
|
|
76
|
+
- Critical: `--ndw-color-critical-100` to `--ndw-color-critical-500`
|
|
77
|
+
- Info: `--ndw-color-info-100` to `--ndw-color-info-500`
|
|
78
|
+
- Alternative: `--ndw-color-alternative-100`, `--ndw-color-alternative-500`
|
|
79
|
+
|
|
80
|
+
**Data visualization**: `--ndw-color-data-{a..f}-{100,500}`
|
|
81
|
+
|
|
82
|
+
**Semantic**: `--ndw-color-background`, `--ndw-color-background-hover`, `--ndw-color-background-active`, `--ndw-color-background-disabled`, `--ndw-color-foreground`, `--ndw-color-text`
|
|
83
|
+
|
|
84
|
+
**Alpha**: `--ndw-alpha-black-007`, `--ndw-alpha-black-015`, `--ndw-alpha-black-040`, `--ndw-alpha-white-040`, `--ndw-alpha-primary-007`, `--ndw-alpha-primary-015`
|
|
85
|
+
|
|
86
|
+
### Borders & Radius
|
|
87
|
+
|
|
88
|
+
| Variable | Value |
|
|
89
|
+
| ------------------------ | -------- |
|
|
90
|
+
| `--ndw-border-size-sm` | 1px |
|
|
91
|
+
| `--ndw-border-size-md` | 2px |
|
|
92
|
+
| `--ndw-border-size-lg` | 3px |
|
|
93
|
+
| `--ndw-border-radius-xs` | 0.125rem |
|
|
94
|
+
| `--ndw-border-radius-sm` | 0.25rem |
|
|
95
|
+
| `--ndw-border-radius-md` | 0.5rem |
|
|
96
|
+
| `--ndw-border-radius-lg` | 1.5rem |
|
|
97
|
+
|
|
98
|
+
### Typography
|
|
99
|
+
|
|
100
|
+
| Variable | Value |
|
|
101
|
+
| --------------------------- | ------------------------- |
|
|
102
|
+
| `--ndw-font-family-body` | 'Nunito Sans', sans-serif |
|
|
103
|
+
| `--ndw-font-family-heading` | 'DM Sans', sans-serif |
|
|
104
|
+
| `--ndw-font-size-2xs` | 0.5625rem |
|
|
105
|
+
| `--ndw-font-size-xs` | 0.6875rem |
|
|
106
|
+
| `--ndw-font-size-sm` | 0.8125rem |
|
|
107
|
+
| `--ndw-font-size-md` | 1.125rem |
|
|
108
|
+
| `--ndw-font-size-lg` | 1.25rem |
|
|
109
|
+
| `--ndw-font-size-xl` | 1.5rem |
|
|
110
|
+
| `--ndw-font-weight-regular` | 400 |
|
|
111
|
+
| `--ndw-font-weight-bold` | 650 |
|
|
112
|
+
|
|
113
|
+
### Elevation
|
|
114
|
+
|
|
115
|
+
| Variable | Use case |
|
|
116
|
+
| -------------------------- | ----------------------- |
|
|
117
|
+
| `--ndw-elevation-content` | Cards, subtle elevation |
|
|
118
|
+
| `--ndw-elevation-dropdown` | Dropdowns |
|
|
119
|
+
| `--ndw-elevation-popover` | Popovers |
|
|
120
|
+
| `--ndw-elevation-toast` | Toast notifications |
|
|
121
|
+
| `--ndw-elevation-info` | Focus rings |
|
|
122
|
+
|
|
123
|
+
### Animation
|
|
124
|
+
|
|
125
|
+
| Variable | Value |
|
|
126
|
+
| --------------------------------- | ----- |
|
|
127
|
+
| `--ndw-animation-speed-very-fast` | 100ms |
|
|
128
|
+
| `--ndw-animation-speed-fast` | 200ms |
|
|
129
|
+
| `--ndw-animation-speed-default` | 300ms |
|
|
130
|
+
| `--ndw-animation-speed-slow` | 500ms |
|
|
131
|
+
|
|
132
|
+
### Screen Breakpoints (SCSS variables)
|
|
133
|
+
|
|
134
|
+
| Variable | Value |
|
|
135
|
+
| ----------------- | ------ |
|
|
136
|
+
| `$ndw-screen-2xs` | 480px |
|
|
137
|
+
| `$ndw-screen-xs` | 768px |
|
|
138
|
+
| `$ndw-screen-sm` | 1024px |
|
|
139
|
+
| `$ndw-screen-md` | 1440px |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Typography CSS Classes & SCSS Mixins
|
|
144
|
+
|
|
145
|
+
Classes for use in HTML, mixins for use in SCSS:
|
|
146
|
+
|
|
147
|
+
| Class | Mixin | Font | Size |
|
|
148
|
+
| ------------------------ | -------------------------------- | ------------------- | --------- |
|
|
149
|
+
| `.ndw-heading-xl` | `@include ndw-heading-xl` | DM Sans Bold | 2.5rem |
|
|
150
|
+
| `.ndw-heading-lg` | `@include ndw-heading-lg` | DM Sans Bold | 2rem |
|
|
151
|
+
| `.ndw-heading-md` | `@include ndw-heading-md` | DM Sans Bold | 1.5rem |
|
|
152
|
+
| `.ndw-heading-sm` | `@include ndw-heading-sm` | DM Sans Bold | 1.25rem |
|
|
153
|
+
| `.ndw-paragraph-bold-xl` | `@include ndw-paragraph-bold-xl` | Nunito Sans Bold | 1.125rem |
|
|
154
|
+
| `.ndw-paragraph-xl` | `@include ndw-paragraph-xl` | Nunito Sans Regular | 1.125rem |
|
|
155
|
+
| `.ndw-paragraph-bold-lg` | `@include ndw-paragraph-bold-lg` | Nunito Sans Bold | 1rem |
|
|
156
|
+
| `.ndw-paragraph-lg` | `@include ndw-paragraph-lg` | Nunito Sans Regular | 1rem |
|
|
157
|
+
| `.ndw-paragraph-bold-md` | `@include ndw-paragraph-bold-md` | Nunito Sans Bold | 0.8125rem |
|
|
158
|
+
| `.ndw-paragraph-md` | `@include ndw-paragraph-md` | Nunito Sans Regular | 0.8125rem |
|
|
159
|
+
| `.ndw-paragraph-bold-sm` | `@include ndw-paragraph-bold-sm` | Nunito Sans Bold | 0.6875rem |
|
|
160
|
+
| `.ndw-paragraph-sm` | `@include ndw-paragraph-sm` | Nunito Sans Regular | 0.6875rem |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Layout Utilities
|
|
165
|
+
|
|
166
|
+
### Grid (`.ndw-grid`)
|
|
167
|
+
|
|
168
|
+
Responsive CSS Grid with 12-column system. Columns per breakpoint: 2xs=2, xs=4, sm=6, md=12.
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<div class="ndw-grid">
|
|
172
|
+
<div class="column-6 column-sm-3">Half / quarter</div>
|
|
173
|
+
<div class="column-6 column-sm-9">Half / three-quarter</div>
|
|
174
|
+
</div>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Modifier: `.ndw-grid--no-padding` removes horizontal padding.
|
|
178
|
+
|
|
179
|
+
### Container Grid (`.ndw-c-grid`)
|
|
180
|
+
|
|
181
|
+
Container-query based 12-column flex grid.
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<div class="ndw-c-grid">
|
|
185
|
+
<div class="ndw-c-col ndw-c-col-6 ndw-c-col-sm-4">Content</div>
|
|
186
|
+
<div class="ndw-c-col ndw-c-col-6 ndw-c-col-sm-8">Content</div>
|
|
187
|
+
</div>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Ordering: `.ndw-c-order-{0-5}`, `.ndw-c-order-{breakpoint}-{0-5}`
|
|
191
|
+
|
|
192
|
+
### Screenreader Only
|
|
193
|
+
|
|
194
|
+
```html
|
|
195
|
+
<span class="sr-only">Hidden visually, available to screen readers</span>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Directive-based Styling
|
|
201
|
+
|
|
202
|
+
### Button `[ndwButton]`
|
|
203
|
+
|
|
204
|
+
Apply to `<button>` or `<a>` elements. Provides full button styling.
|
|
205
|
+
|
|
206
|
+
```html
|
|
207
|
+
<button ndwButton>Primary</button>
|
|
208
|
+
<button ndwButton secondary>Secondary (outlined)</button>
|
|
209
|
+
<button ndwButton tertiary>Tertiary (ghost)</button>
|
|
210
|
+
<button ndwButton secondary alternative>Alternative secondary</button>
|
|
211
|
+
<button ndwButton tertiary alternative>Alternative tertiary</button>
|
|
212
|
+
<button ndwButton extra-small>Extra small</button>
|
|
213
|
+
<button ndwButton large>Large</button>
|
|
214
|
+
<button ndwButton disabled>Disabled</button>
|
|
215
|
+
<button ndwButton filter>Filter button style</button>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Import**: `ButtonDirective` from `@ndwnu/design-system`
|
|
219
|
+
|
|
220
|
+
### Input `[ndwInput]`
|
|
221
|
+
|
|
222
|
+
Apply to `<input>`, `<select>`, or `<textarea>` elements. Supports `error`, `success`, `disabled`, `readonly` attributes.
|
|
223
|
+
|
|
224
|
+
```html
|
|
225
|
+
<input ndwInput type="text" placeholder="Enter text" />
|
|
226
|
+
<select ndwInput>
|
|
227
|
+
<option>Choose...</option>
|
|
228
|
+
</select>
|
|
229
|
+
<textarea ndwInput></textarea>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Wrap in `.input-container` for prefix/suffix support:
|
|
233
|
+
|
|
234
|
+
```html
|
|
235
|
+
<div class="input-container">
|
|
236
|
+
<ndw-input-icon><ndw-icon>search</ndw-icon></ndw-input-icon>
|
|
237
|
+
<input ndwInput type="search" />
|
|
238
|
+
</div>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Import**: `InputDirective` from `@ndwnu/design-system`
|
|
242
|
+
|
|
243
|
+
### Link `[ndwLink]`
|
|
244
|
+
|
|
245
|
+
```html
|
|
246
|
+
<a ndwLink href="/page">Link text <ndw-icon>arrow_forward</ndw-icon></a>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Label `[ndwLabel]`
|
|
250
|
+
|
|
251
|
+
```html
|
|
252
|
+
<label ndwLabel>Field label</label>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Divider `[ndwDivider]`
|
|
256
|
+
|
|
257
|
+
```html
|
|
258
|
+
<hr ndwDivider />
|
|
259
|
+
<hr ndwDivider noMargin />
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Components
|
|
265
|
+
|
|
266
|
+
### AccordionComponent
|
|
267
|
+
|
|
268
|
+
**Selector**: `ndw-accordion`
|
|
269
|
+
**Import**: `AccordionComponent`
|
|
270
|
+
|
|
271
|
+
| Input | Type | Default | Description |
|
|
272
|
+
| ---------------- | --------- | ------- | -------------------------------------------------- |
|
|
273
|
+
| `collapseOthers` | `boolean` | `false` | When true, expanding one collapsible closes others |
|
|
274
|
+
|
|
275
|
+
Contains `ndw-collapsible` children.
|
|
276
|
+
|
|
277
|
+
```html
|
|
278
|
+
<ndw-accordion [collapseOthers]="true">
|
|
279
|
+
<ndw-collapsible [index]="0" title="Section 1">Content 1</ndw-collapsible>
|
|
280
|
+
<ndw-collapsible [index]="1" title="Section 2">Content 2</ndw-collapsible>
|
|
281
|
+
</ndw-accordion>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
### AlertComponent
|
|
287
|
+
|
|
288
|
+
**Selector**: `ndw-alert`
|
|
289
|
+
**Import**: `AlertComponent`
|
|
290
|
+
|
|
291
|
+
| Input | Type | Default | Description |
|
|
292
|
+
| ------------ | -------------------------------------------------- | ------------- | ---------------------------- |
|
|
293
|
+
| `type` | `'critical' \| 'info' \| 'info-grey' \| 'warning'` | `'info-grey'` | Visual style |
|
|
294
|
+
| `actionable` | `boolean` | `false` | Shows close button and title |
|
|
295
|
+
| `title` | `string` | `undefined` | Title (only when actionable) |
|
|
296
|
+
| `ariaLive` | `'polite' \| 'assertive' \| 'off'` | `'off'` | Screen reader announcement |
|
|
297
|
+
|
|
298
|
+
| Output | Type | Description |
|
|
299
|
+
| ------- | ------ | --------------------------------- |
|
|
300
|
+
| `close` | `void` | Emitted when close button clicked |
|
|
301
|
+
|
|
302
|
+
```html
|
|
303
|
+
<ndw-alert type="warning" [actionable]="true" title="Warning" (close)="onClose()">
|
|
304
|
+
Alert message content
|
|
305
|
+
</ndw-alert>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### AvatarComponent
|
|
311
|
+
|
|
312
|
+
**Selector**: `ndw-avatar`
|
|
313
|
+
**Import**: `AvatarComponent`
|
|
314
|
+
|
|
315
|
+
| Input | Type | Default | Description |
|
|
316
|
+
| ---------- | ----------------------------------------------------------------------------- | ----------- | ------------------ |
|
|
317
|
+
| `status` | `'approved' \| 'declined' \| 'open' \| 'none'` | `'none'` | Status indicator |
|
|
318
|
+
| `initials` | `boolean` | `false` | Show initials mode |
|
|
319
|
+
| `color` | `'default' \| 'blue' \| 'purple' \| 'red' \| 'green' \| 'yellow' \| 'orange'` | `undefined` | Background color |
|
|
320
|
+
|
|
321
|
+
```html
|
|
322
|
+
<ndw-avatar status="approved" color="blue">AB</ndw-avatar>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
### BadgeComponent
|
|
328
|
+
|
|
329
|
+
**Selector**: `ndw-badge`
|
|
330
|
+
**Import**: `BadgeComponent`
|
|
331
|
+
|
|
332
|
+
| Input | Type | Default | Description |
|
|
333
|
+
| --------------------- | ---------------------- | ----------- | ------------------------------------------ |
|
|
334
|
+
| `value` | `number` | `undefined` | Numeric value |
|
|
335
|
+
| `ariaLabel` | `string` | `undefined` | Screen reader label |
|
|
336
|
+
| `displayLargeNumbers` | `boolean` | `false` | Show values above 99 (otherwise shows dot) |
|
|
337
|
+
| `size` | `'default' \| 'small'` | `'default'` | Badge size |
|
|
338
|
+
| `variant` | `'default' \| 'error'` | `'default'` | Error variant shows `!` |
|
|
339
|
+
|
|
340
|
+
```html
|
|
341
|
+
<ndw-badge [value]="5" ariaLabel="5 notifications"></ndw-badge>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
### BannerComponent
|
|
347
|
+
|
|
348
|
+
**Selector**: `ndw-banner`
|
|
349
|
+
**Import**: `BannerComponent`
|
|
350
|
+
|
|
351
|
+
| Input | Type | Default | Description |
|
|
352
|
+
| --------------- | ---------------------------------------------------------------- | --------------- | ----------------------------- |
|
|
353
|
+
| `title` | `string` | **required** | Banner title |
|
|
354
|
+
| `message` | `string` | **required** | Banner message |
|
|
355
|
+
| `type` | `'critical' \| 'info' \| 'info-grey' \| 'warning' \| 'positive'` | `'info'` | Visual style |
|
|
356
|
+
| `readMoreLabel` | `string` | `'lees verder'` | Read more text when truncated |
|
|
357
|
+
| `ariaLive` | `'polite' \| 'assertive' \| 'off'` | `'off'` | Screen reader announcement |
|
|
358
|
+
|
|
359
|
+
| Output | Type | Description |
|
|
360
|
+
| ------- | ------ | --------------------------------- |
|
|
361
|
+
| `close` | `void` | Emitted when close button clicked |
|
|
362
|
+
|
|
363
|
+
```html
|
|
364
|
+
<ndw-banner
|
|
365
|
+
title="Update"
|
|
366
|
+
message="System maintenance planned"
|
|
367
|
+
type="warning"
|
|
368
|
+
(close)="dismiss()"
|
|
369
|
+
></ndw-banner>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
### BreadcrumbComponent & BreadcrumbGroupComponent
|
|
375
|
+
|
|
376
|
+
**Selectors**: `ndw-breadcrumb`, `ndw-breadcrumb-group`
|
|
377
|
+
**Import**: `BreadcrumbComponent`, `BreadcrumbGroupComponent`
|
|
378
|
+
|
|
379
|
+
**BreadcrumbComponent**:
|
|
380
|
+
| Input | Type | Default | Description |
|
|
381
|
+
|---|---|---|---|
|
|
382
|
+
| `link` | `string \| null` | `null` | Route path (last breadcrumb typically has no link) |
|
|
383
|
+
|
|
384
|
+
Content projection for the breadcrumb label text.
|
|
385
|
+
|
|
386
|
+
```html
|
|
387
|
+
<ndw-breadcrumb-group>
|
|
388
|
+
<ndw-breadcrumb link="/">Home</ndw-breadcrumb>
|
|
389
|
+
<ndw-breadcrumb link="/projects">Projects</ndw-breadcrumb>
|
|
390
|
+
<ndw-breadcrumb>Current Page</ndw-breadcrumb>
|
|
391
|
+
</ndw-breadcrumb-group>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### RouterBreadcrumbsComponent
|
|
395
|
+
|
|
396
|
+
**Selector**: `ndw-router-breadcrumbs`
|
|
397
|
+
**Import**: `RouterBreadcrumbsComponent`
|
|
398
|
+
|
|
399
|
+
Auto-generates breadcrumbs from Angular router `data` properties.
|
|
400
|
+
|
|
401
|
+
| Input | Type | Default | Description |
|
|
402
|
+
| -------------- | -------- | -------------- | ------------------------------------------------ |
|
|
403
|
+
| `routeDataKey` | `string` | `'breadcrumb'` | The key in route data to use as breadcrumb title |
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
// In your route config:
|
|
407
|
+
{ path: 'projects', component: ProjectsComponent, data: { breadcrumb: 'Projects' } }
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
```html
|
|
411
|
+
<ndw-router-breadcrumbs></ndw-router-breadcrumbs>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
### CardComponent
|
|
417
|
+
|
|
418
|
+
**Selector**: `ndw-card`
|
|
419
|
+
**Import**: `CardComponent`, `CardHeaderComponent`, `CardContentComponent`, `CardFooterComponent`
|
|
420
|
+
|
|
421
|
+
| Input/Model | Type | Default | Description |
|
|
422
|
+
| --------------------- | --------- | ------- | --------------------------------- |
|
|
423
|
+
| `isCollapsed` (model) | `boolean` | `false` | Collapsed state (two-way binding) |
|
|
424
|
+
|
|
425
|
+
**CardHeaderComponent** (`ndw-card-header`):
|
|
426
|
+
| Input | Type | Default | Description |
|
|
427
|
+
|---|---|---|---|
|
|
428
|
+
| `isCollapsible` | `boolean` | `false` | Show expand/collapse toggle in header |
|
|
429
|
+
|
|
430
|
+
```html
|
|
431
|
+
<ndw-card>
|
|
432
|
+
<ndw-card-header [isCollapsible]="true">Card Title</ndw-card-header>
|
|
433
|
+
<ndw-card-content>Card body content</ndw-card-content>
|
|
434
|
+
<ndw-card-footer>Footer actions</ndw-card-footer>
|
|
435
|
+
</ndw-card>
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### CollapsibleComponent
|
|
441
|
+
|
|
442
|
+
**Selector**: `ndw-collapsible`
|
|
443
|
+
**Import**: `CollapsibleComponent`
|
|
444
|
+
|
|
445
|
+
| Input | Type | Default | Description |
|
|
446
|
+
| --------------------- | --------- | ------------ | --------------------- |
|
|
447
|
+
| `index` | `number` | **required** | Position index |
|
|
448
|
+
| `title` | `string` | **required** | Header title |
|
|
449
|
+
| `subtitle` | `string` | `undefined` | Subtitle text |
|
|
450
|
+
| `value` | `number` | `undefined` | Numeric value display |
|
|
451
|
+
| `checkable` | `boolean` | `false` | Show checkbox |
|
|
452
|
+
| `displayLargeNumbers` | `boolean` | `false` | Show large numbers |
|
|
453
|
+
|
|
454
|
+
| Model | Type | Default |
|
|
455
|
+
| ---------- | --------- | ------- |
|
|
456
|
+
| `expanded` | `boolean` | `false` |
|
|
457
|
+
|
|
458
|
+
Supports `<custom-header-content>` content projection slot for custom header content next to the title.
|
|
459
|
+
|
|
460
|
+
```html
|
|
461
|
+
<ndw-collapsible [index]="0" title="Section" [(expanded)]="isExpanded">
|
|
462
|
+
<custom-header-content><ndw-pill>New</ndw-pill></custom-header-content>
|
|
463
|
+
Expandable content
|
|
464
|
+
</ndw-collapsible>
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
### DashboardCardComponent
|
|
470
|
+
|
|
471
|
+
**Selector**: `ndw-dashboard-card`
|
|
472
|
+
**Import**: `DashboardCardComponent`
|
|
473
|
+
|
|
474
|
+
| Input | Type | Default | Description |
|
|
475
|
+
| ------------ | -------- | ------------ | ------------------------------------- |
|
|
476
|
+
| `title` | `string` | **required** | Card title |
|
|
477
|
+
| `imgSource` | `string` | **required** | Icon URL |
|
|
478
|
+
| `link` | `string` | **required** | URL to open on click |
|
|
479
|
+
| `linkTarget` | `string` | `'_blank'` | Link target (`_blank`, `_self`, etc.) |
|
|
480
|
+
|
|
481
|
+
```html
|
|
482
|
+
<ndw-dashboard-card
|
|
483
|
+
title="Traffic Data"
|
|
484
|
+
imgSource="/assets/icon.svg"
|
|
485
|
+
link="https://example.com"
|
|
486
|
+
></ndw-dashboard-card>
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
### DropdownComponent
|
|
492
|
+
|
|
493
|
+
**Selector**: `ndw-dropdown`
|
|
494
|
+
**Import**: `DropdownComponent`
|
|
495
|
+
|
|
496
|
+
| Input | Type | Default | Description |
|
|
497
|
+
| -------------- | --------- | ------------ | ------------------------- |
|
|
498
|
+
| `buttonText` | `string` | **required** | Button label |
|
|
499
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
500
|
+
| `chevron` | `boolean` | `true` | Show chevron icon |
|
|
501
|
+
| `prefixIcon` | `string` | `''` | Material icon before text |
|
|
502
|
+
| `selectAmount` | `number` | `0` | Selected count badge |
|
|
503
|
+
|
|
504
|
+
| Output | Type | Description |
|
|
505
|
+
| -------------- | --------- | --------------------------- |
|
|
506
|
+
| `tagClicked` | `void` | Tag clear button clicked |
|
|
507
|
+
| `isOpenChange` | `boolean` | Dropdown open state changed |
|
|
508
|
+
|
|
509
|
+
Content is projected into the dropdown popover.
|
|
510
|
+
|
|
511
|
+
```html
|
|
512
|
+
<ndw-dropdown buttonText="Filter" [selectAmount]="3" (tagClicked)="clearFilter()">
|
|
513
|
+
<div>Dropdown content here</div>
|
|
514
|
+
</ndw-dropdown>
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
### EditBarComponent
|
|
520
|
+
|
|
521
|
+
**Selector**: `ndw-edit-bar`
|
|
522
|
+
**Import**: `EditBarComponent`
|
|
523
|
+
|
|
524
|
+
| Input | Type | Default | Description |
|
|
525
|
+
| -------------------- | ----------------------------------------------- | ---------- | ---------------- |
|
|
526
|
+
| `grid` | `boolean` | `false` | Use grid layout |
|
|
527
|
+
| `position` | `'fixed' \| 'sticky' \| 'static' \| 'absolute'` | `'fixed'` | Position type |
|
|
528
|
+
| `positionFixedWidth` | `'full' \| 'layout'` | `'layout'` | Width when fixed |
|
|
529
|
+
|
|
530
|
+
```html
|
|
531
|
+
<ndw-edit-bar position="fixed">
|
|
532
|
+
<button ndwButton>Save</button>
|
|
533
|
+
<button ndwButton secondary>Cancel</button>
|
|
534
|
+
</ndw-edit-bar>
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
### FavoriteComponent
|
|
540
|
+
|
|
541
|
+
**Selector**: `ndw-favorite`
|
|
542
|
+
**Import**: `FavoriteComponent`
|
|
543
|
+
|
|
544
|
+
| Model | Type | Default |
|
|
545
|
+
| --------- | --------- | ------- |
|
|
546
|
+
| `checked` | `boolean` | `false` |
|
|
547
|
+
|
|
548
|
+
```html
|
|
549
|
+
<ndw-favorite [(checked)]="isFavorite"></ndw-favorite>
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
### FormFieldComponent
|
|
555
|
+
|
|
556
|
+
**Selector**: `ndw-form-field`
|
|
557
|
+
**Import**: `FormFieldComponent`
|
|
558
|
+
|
|
559
|
+
Wraps any form element (inputs, selects, textareas, checkboxes, radio groups, option groups, datepickers, month inputs) with a label, error, success, info messages, and tooltip. Automatically uses `<fieldset>`/`<legend>` for non-input elements (like checkbox groups) and `<label>`/`for` for regular inputs.
|
|
560
|
+
|
|
561
|
+
| Input | Type | Default | Description |
|
|
562
|
+
| ----------------- | --------- | ------------ | --------------------- |
|
|
563
|
+
| `label` | `string` | **required** | Field label |
|
|
564
|
+
| `hideLabel` | `boolean` | `false` | Visually hide label |
|
|
565
|
+
| `disabled` | `boolean` | `false` | Disable the field |
|
|
566
|
+
| `error` | `string` | `undefined` | Error message |
|
|
567
|
+
| `success` | `string` | `undefined` | Success message |
|
|
568
|
+
| `info` | `string` | `undefined` | Info/help message |
|
|
569
|
+
| `tooltip` | `string` | `''` | Tooltip text |
|
|
570
|
+
| `suffixAriaLabel` | `string` | `''` | Aria label for suffix |
|
|
571
|
+
|
|
572
|
+
| Output | Type | Description |
|
|
573
|
+
| -------------------- | ------ | --------------------------- |
|
|
574
|
+
| `clearButtonClicked` | `void` | Search clear button clicked |
|
|
575
|
+
|
|
576
|
+
```html
|
|
577
|
+
<!-- With input -->
|
|
578
|
+
<ndw-form-field label="Email" [error]="emailError" tooltip="Enter your work email">
|
|
579
|
+
<input ndwInput type="email" [formControl]="emailControl" />
|
|
580
|
+
</ndw-form-field>
|
|
581
|
+
|
|
582
|
+
<!-- With select -->
|
|
583
|
+
<ndw-form-field label="Country">
|
|
584
|
+
<select ndwInput [formControl]="countryControl">
|
|
585
|
+
<option disabled selected>Choose...</option>
|
|
586
|
+
<option value="nl">Netherlands</option>
|
|
587
|
+
</select>
|
|
588
|
+
</ndw-form-field>
|
|
589
|
+
|
|
590
|
+
<!-- With checkbox group (uses fieldset/legend automatically) -->
|
|
591
|
+
<ndw-form-field label="Options" [error]="optionsError">
|
|
592
|
+
<ndw-checkbox-group>
|
|
593
|
+
<ndw-checkbox>Option A</ndw-checkbox>
|
|
594
|
+
<ndw-checkbox>Option B</ndw-checkbox>
|
|
595
|
+
</ndw-checkbox-group>
|
|
596
|
+
</ndw-form-field>
|
|
597
|
+
|
|
598
|
+
<!-- With datepicker -->
|
|
599
|
+
<ndw-form-field label="Start date">
|
|
600
|
+
<ndw-datepicker [formControl]="dateControl"></ndw-datepicker>
|
|
601
|
+
</ndw-form-field>
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
### CheckboxComponent
|
|
607
|
+
|
|
608
|
+
**Selector**: `ndw-checkbox`
|
|
609
|
+
**Import**: `CheckboxComponent`
|
|
610
|
+
**CVA**: Yes (use with `formControl` or `ngModel`)
|
|
611
|
+
|
|
612
|
+
| Input/Model | Type | Default | Description |
|
|
613
|
+
| ------------------ | --------- | ------- | ----------------------- |
|
|
614
|
+
| `checked` (model) | `boolean` | `false` | Checked state |
|
|
615
|
+
| `disabled` (model) | `boolean` | `false` | Disabled state |
|
|
616
|
+
| `error` | `boolean` | `false` | Error state |
|
|
617
|
+
| `indeterminate` | `boolean` | `false` | Indeterminate state |
|
|
618
|
+
| `required` | `boolean` | `false` | Required |
|
|
619
|
+
| `switch` | `boolean` | `false` | Render as toggle switch |
|
|
620
|
+
| `success` | `boolean` | `false` | Success state |
|
|
621
|
+
|
|
622
|
+
Content projection for the label text.
|
|
623
|
+
|
|
624
|
+
```html
|
|
625
|
+
<ndw-checkbox [formControl]="myControl">Label text</ndw-checkbox>
|
|
626
|
+
<ndw-checkbox [switch]="true" [(ngModel)]="toggleValue">Toggle</ndw-checkbox>
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### CheckboxGroupComponent
|
|
630
|
+
|
|
631
|
+
**Selector**: `ndw-checkbox-group`
|
|
632
|
+
**Import**: `CheckboxGroupComponent`
|
|
633
|
+
|
|
634
|
+
Container for grouping checkboxes.
|
|
635
|
+
|
|
636
|
+
```html
|
|
637
|
+
<ndw-checkbox-group>
|
|
638
|
+
<ndw-checkbox>Option A</ndw-checkbox>
|
|
639
|
+
<ndw-checkbox>Option B</ndw-checkbox>
|
|
640
|
+
</ndw-checkbox-group>
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
---
|
|
644
|
+
|
|
645
|
+
### RadioButtonComponent & RadioGroupComponent
|
|
646
|
+
|
|
647
|
+
**Selectors**: `ndw-radio-button`, `ndw-radio-group`
|
|
648
|
+
**Import**: `RadioButtonComponent`, `RadioGroupComponent`
|
|
649
|
+
**CVA**: Yes
|
|
650
|
+
|
|
651
|
+
RadioButton inputs:
|
|
652
|
+
| Input/Model | Type | Default | Description |
|
|
653
|
+
|---|---|---|---|
|
|
654
|
+
| `checked` (model) | `boolean` | `false` | Checked state |
|
|
655
|
+
| `disabled` (model) | `boolean` | `false` | Disabled state |
|
|
656
|
+
| `value` (model) | `unknown` | `undefined` | Option value emitted on selection |
|
|
657
|
+
| `error` | `boolean` | `false` | Error state styling |
|
|
658
|
+
| `success` | `boolean` | `false` | Success state styling |
|
|
659
|
+
| `required` | `boolean` | `false` | Mark as required |
|
|
660
|
+
|
|
661
|
+
```html
|
|
662
|
+
<ndw-radio-group [formControl]="selection">
|
|
663
|
+
<ndw-radio-button [value]="'a'">Option A</ndw-radio-button>
|
|
664
|
+
<ndw-radio-button [value]="'b'">Option B</ndw-radio-button>
|
|
665
|
+
</ndw-radio-group>
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
### DatepickerComponent
|
|
671
|
+
|
|
672
|
+
**Selector**: `ndw-datepicker`
|
|
673
|
+
**Import**: `DatepickerComponent`
|
|
674
|
+
**CVA**: Yes
|
|
675
|
+
|
|
676
|
+
| Input | Type | Default | Description |
|
|
677
|
+
| ------------------------- | ----------------------------------- | ----------------------- | ------------------- |
|
|
678
|
+
| `mode` | `'single' \| 'multiple' \| 'month'` | `'single'` | Selection mode |
|
|
679
|
+
| `required` | `boolean` | `false` | Required field |
|
|
680
|
+
| `placeholder` | `string` | `'Selecteer een datum'` | Placeholder text |
|
|
681
|
+
| `openCalendarLabel` | `string` | `'Open kalender'` | Aria label |
|
|
682
|
+
| `minDate` | `Date \| null` | `null` | Minimum date |
|
|
683
|
+
| `maxDate` | `Date \| null` | `null` | Maximum date |
|
|
684
|
+
| `dateEnabledFilter` | `DateFilterFn<Date \| null>` | `() => true` | Custom date filter |
|
|
685
|
+
| `dateWithIndicatorFilter` | `DateFilterFn<Date \| null>` | `() => false` | Show indicator dots |
|
|
686
|
+
| `showWeekNumbers` | `boolean` | `false` | Show week numbers |
|
|
687
|
+
|
|
688
|
+
| Model | Type | Default | Description |
|
|
689
|
+
| ---------- | --------- | ------- | -------------- |
|
|
690
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
691
|
+
|
|
692
|
+
```html
|
|
693
|
+
<ndw-form-field label="Date">
|
|
694
|
+
<ndw-datepicker [formControl]="dateControl" [minDate]="minDate"></ndw-datepicker>
|
|
695
|
+
</ndw-form-field>
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
### MonthInputComponent
|
|
701
|
+
|
|
702
|
+
**Selector**: `ndw-month-input`
|
|
703
|
+
**Import**: `MonthInputComponent`
|
|
704
|
+
**CVA**: Yes
|
|
705
|
+
|
|
706
|
+
| Input | Type | Default | Description |
|
|
707
|
+
| ---------------------- | ---------- | ------------------------- | ---------------------------------- |
|
|
708
|
+
| `required` | `boolean` | `false` | Mark as required |
|
|
709
|
+
| `placeholder` | `string` | `'JJJJ-MM'` | Placeholder text |
|
|
710
|
+
| `showMonthPickerLabel` | `string` | `'Selecteer maand'` | Aria label for month picker button |
|
|
711
|
+
| `yearPlaceholder` | `string` | `'Jaar'` | Placeholder for year input |
|
|
712
|
+
| `minDate` | `Date` | `2020-01-01` | Earliest selectable month |
|
|
713
|
+
| `maxDate` | `Date` | `2099-12-31` | Latest selectable month |
|
|
714
|
+
| `monthLabels` | `string[]` | Dutch month abbreviations | Labels for month buttons |
|
|
715
|
+
| `addValidators` | `boolean` | `true` | Auto-add min/max validators |
|
|
716
|
+
| `readonly` | `boolean` | `false` | Readonly state |
|
|
717
|
+
|
|
718
|
+
```html
|
|
719
|
+
<ndw-form-field label="Month">
|
|
720
|
+
<ndw-month-input [formControl]="monthControl"></ndw-month-input>
|
|
721
|
+
</ndw-form-field>
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
### FileUploadComponent
|
|
727
|
+
|
|
728
|
+
**Selector**: `ndw-file-upload`
|
|
729
|
+
**Import**: `FileUploadComponent`
|
|
730
|
+
**CVA**: Yes
|
|
731
|
+
|
|
732
|
+
| Input | Type | Default | Description |
|
|
733
|
+
| ---------------------- | ------------------------ | -------------- | ------------------------ |
|
|
734
|
+
| `allowedFileTypeRegex` | `RegExp` | `undefined` | Allowed MIME types regex |
|
|
735
|
+
| `maxFileSizeInBytes` | `number` | `1000000` | Max file size (1MB) |
|
|
736
|
+
| `fileUploadText` | `FileUploadText` | Dutch defaults | Drag/drop text |
|
|
737
|
+
| `mimeTypeMap` | `Record<string, string>` | `{}` | Extra MIME type mappings |
|
|
738
|
+
| `readonly` | `boolean` | `false` | Readonly state |
|
|
739
|
+
| `uploadDate` | `string` | `''` | Display upload date |
|
|
740
|
+
|
|
741
|
+
| Model | Type | Description |
|
|
742
|
+
| ------------------- | -------------- | ----------------------- |
|
|
743
|
+
| `disabled` | `boolean` | Disabled state |
|
|
744
|
+
| `selectedFile` | `File \| null` | Currently selected file |
|
|
745
|
+
| `error` | `boolean` | General error state |
|
|
746
|
+
| `incorrectFileSize` | `boolean` | File exceeds max size |
|
|
747
|
+
| `incorrectFileType` | `boolean` | File type not allowed |
|
|
748
|
+
|
|
749
|
+
```html
|
|
750
|
+
<ndw-file-upload
|
|
751
|
+
[formControl]="fileControl"
|
|
752
|
+
[allowedFileTypeRegex]="pdfRegex"
|
|
753
|
+
[maxFileSizeInBytes]="5000000"
|
|
754
|
+
></ndw-file-upload>
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
### MarkdownEditorComponent
|
|
760
|
+
|
|
761
|
+
**Selector**: `ndw-markdown-editor`
|
|
762
|
+
**Import**: `MarkdownEditorComponent`
|
|
763
|
+
**CVA**: Yes
|
|
764
|
+
|
|
765
|
+
| Input | Type | Default | Description |
|
|
766
|
+
| ---------- | ---------- | ------------------------------------------------------------------------ | --------------- |
|
|
767
|
+
| `toolbar` | `string[]` | `['bold','header','italic','unordered-list','ordered-list','task-list']` | Toolbar buttons |
|
|
768
|
+
| `error` | `boolean` | `false` | Error state |
|
|
769
|
+
| `readonly` | `boolean` | `false` | Readonly |
|
|
770
|
+
| `success` | `boolean` | `false` | Success state |
|
|
771
|
+
| `required` | `boolean` | `false` | Required |
|
|
772
|
+
|
|
773
|
+
| Model | Type | Description |
|
|
774
|
+
| ---------- | --------- | ---------------- |
|
|
775
|
+
| `value` | `string` | Markdown content |
|
|
776
|
+
| `disabled` | `boolean` | Disabled state |
|
|
777
|
+
|
|
778
|
+
```html
|
|
779
|
+
<ndw-markdown-editor
|
|
780
|
+
[formControl]="mdControl"
|
|
781
|
+
[toolbar]="['bold','italic','unordered-list']"
|
|
782
|
+
></ndw-markdown-editor>
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
---
|
|
786
|
+
|
|
787
|
+
### OptionGroupComponent
|
|
788
|
+
|
|
789
|
+
**Selector**: `ndw-option-group`
|
|
790
|
+
**Import**: `OptionGroupComponent`
|
|
791
|
+
**CVA**: Yes
|
|
792
|
+
|
|
793
|
+
| Input | Type | Default | Description |
|
|
794
|
+
| -------------- | ------------------------ | ------------ | -------------- |
|
|
795
|
+
| `mode` | `'single' \| 'multiple'` | `'multiple'` | Selection mode |
|
|
796
|
+
| `error` | `boolean` | `false` | Error state |
|
|
797
|
+
| `success` | `boolean` | `false` | Success state |
|
|
798
|
+
| `readonly` | `boolean` | `false` | Readonly |
|
|
799
|
+
| `required` | `boolean` | `false` | Required |
|
|
800
|
+
| `fluid` | `boolean` | `false` | Fluid width |
|
|
801
|
+
| `fluidColumns` | `number \| null` | `null` | Grid columns |
|
|
802
|
+
|
|
803
|
+
| Model | Type | Description |
|
|
804
|
+
| --------------- | ----------- | -------------------------------- |
|
|
805
|
+
| `checkedValues` | `unknown[]` | Currently selected option values |
|
|
806
|
+
| `disabled` | `boolean` | Disabled state |
|
|
807
|
+
|
|
808
|
+
Uses `ndw-option` children:
|
|
809
|
+
|
|
810
|
+
**OptionComponent** (`ndw-option`):
|
|
811
|
+
| Input | Type | Default | Description |
|
|
812
|
+
|---|---|---|---|
|
|
813
|
+
| `value` | `unknown` | **required** | Option value |
|
|
814
|
+
| `label` | `string` | **required** | Display label |
|
|
815
|
+
| `description` | `string` | `undefined` | Secondary description text |
|
|
816
|
+
| `required` | `boolean` | `false` | Mark as required |
|
|
817
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
818
|
+
|
|
819
|
+
```html
|
|
820
|
+
<ndw-form-field label="Priority">
|
|
821
|
+
<ndw-option-group [formControl]="priorityControl" mode="single">
|
|
822
|
+
<ndw-option [value]="'low'" label="Low"></ndw-option>
|
|
823
|
+
<ndw-option [value]="'medium'" label="Medium"></ndw-option>
|
|
824
|
+
<ndw-option [value]="'high'" label="High" description="Urgent items only"></ndw-option>
|
|
825
|
+
</ndw-option-group>
|
|
826
|
+
</ndw-form-field>
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
---
|
|
830
|
+
|
|
831
|
+
### AutosuggestDirective
|
|
832
|
+
|
|
833
|
+
**Selector**: `input[ndwAutosuggest]`, `textarea[ndwAutosuggest]`
|
|
834
|
+
**Import**: `AutosuggestDirective`, `AutosuggestPanelComponent`, `AutosuggestOptionComponent`, `AutosuggestAddOptionComponent`
|
|
835
|
+
**CVA**: Yes
|
|
836
|
+
|
|
837
|
+
**AutosuggestPanelComponent** (`ndw-autosuggest`):
|
|
838
|
+
| Input | Type | Default | Description |
|
|
839
|
+
|---|---|---|---|
|
|
840
|
+
| `options` | `AutosuggestOption[]` | `[]` | List of options to search/filter |
|
|
841
|
+
| `customSearch` | `AutosuggestSearchFn \| null` | `null` | Custom search function `(searchTerm, option) => boolean` |
|
|
842
|
+
| `enableAddOption` | `boolean` | `false` | Allow adding new options |
|
|
843
|
+
| `maxResults` | `number` | `100` | Max results shown |
|
|
844
|
+
| `noResultText` | `string` | `'Geen resultaten gevonden...'` | No results text |
|
|
845
|
+
| `hiddenResultsText` | `string` | Dutch default | Text when results are truncated |
|
|
846
|
+
|
|
847
|
+
| Output | Type | Description |
|
|
848
|
+
| ---------------------- | --------------------------- | ------------------------------------------------- |
|
|
849
|
+
| `optionSelected` | `AutosuggestOption \| null` | Option selected by user |
|
|
850
|
+
| `addOption` | `string` | New option added (when `enableAddOption` is true) |
|
|
851
|
+
| `opened` | `void` | Panel opened |
|
|
852
|
+
| `closed` | `void` | Panel closed |
|
|
853
|
+
| `results` | `AutosuggestOption[]` | Filtered results |
|
|
854
|
+
| `numberOfResultsShown` | `number` | Number of hidden results |
|
|
855
|
+
|
|
856
|
+
**AutosuggestOptionComponent** (`ndw-autosuggest-option`):
|
|
857
|
+
| Input | Type | Default | Description |
|
|
858
|
+
|---|---|---|---|
|
|
859
|
+
| `value` | `AutosuggestOption` | **required** | Option data object |
|
|
860
|
+
| `label` | `string` | **required** | Display label (used for filtering and bold matching) |
|
|
861
|
+
| `searchTerm` | `string` | `''` | Current search term (for bold text matching) |
|
|
862
|
+
| `icon` | `string` | `undefined` | Material icon prefix |
|
|
863
|
+
| `image` | `Image` | `undefined` | Image to display alongside option |
|
|
864
|
+
|
|
865
|
+
**AutosuggestOption interface**: `{ label: string; value: string \| number \| boolean; icon?: string; image?: Image }`
|
|
866
|
+
|
|
867
|
+
```html
|
|
868
|
+
<ndw-form-field label="Search">
|
|
869
|
+
<input ndwInput [ndwAutosuggest]="panel" [formControl]="searchControl" />
|
|
870
|
+
</ndw-form-field>
|
|
871
|
+
<ndw-autosuggest #panel [options]="options" (optionSelected)="onSelect($event)">
|
|
872
|
+
@for (option of panel.slicedOptions(); track option.value) {
|
|
873
|
+
<ndw-autosuggest-option [value]="option" [label]="option.label" [searchTerm]="panel.searchTerm()">
|
|
874
|
+
</ndw-autosuggest-option>
|
|
875
|
+
}
|
|
876
|
+
</ndw-autosuggest>
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
---
|
|
880
|
+
|
|
881
|
+
### InputIconComponent
|
|
882
|
+
|
|
883
|
+
**Selector**: `ndw-input-icon`
|
|
884
|
+
**Import**: `InputIconComponent`
|
|
885
|
+
|
|
886
|
+
Used inside `.input-container` to add prefix/suffix icons to inputs.
|
|
887
|
+
|
|
888
|
+
```html
|
|
889
|
+
<div class="input-container">
|
|
890
|
+
<ndw-input-icon><ndw-icon>search</ndw-icon></ndw-input-icon>
|
|
891
|
+
<input ndwInput type="text" />
|
|
892
|
+
</div>
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
---
|
|
896
|
+
|
|
897
|
+
### IconComponent
|
|
898
|
+
|
|
899
|
+
**Selector**: `ndw-icon`
|
|
900
|
+
**Import**: `IconComponent`
|
|
901
|
+
|
|
902
|
+
Uses Material Symbols Rounded. Content is the icon name.
|
|
903
|
+
|
|
904
|
+
| Input | Type | Default | Description |
|
|
905
|
+
| -------- | -------------- | ------- | ------------------- |
|
|
906
|
+
| `filled` | `boolean` | `false` | Filled icon variant |
|
|
907
|
+
| `size` | `'sm' \| 'md'` | `'md'` | Icon size |
|
|
908
|
+
|
|
909
|
+
```html
|
|
910
|
+
<ndw-icon>home</ndw-icon> <ndw-icon [filled]="true" size="sm">favorite</ndw-icon>
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
---
|
|
914
|
+
|
|
915
|
+
### HoverableListItemComponent
|
|
916
|
+
|
|
917
|
+
**Selector**: `ndw-hoverable-list-item`
|
|
918
|
+
**Import**: `HoverableListItemComponent`
|
|
919
|
+
|
|
920
|
+
| Input | Type | Default | Description |
|
|
921
|
+
| ------------- | --------------------------- | ----------- | ----------------------------- |
|
|
922
|
+
| `title` | `string` | `undefined` | Item title |
|
|
923
|
+
| `subtitle` | `string` | `undefined` | Secondary text |
|
|
924
|
+
| `prefixIcon` | `string` | `undefined` | Material icon before title |
|
|
925
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
926
|
+
| `path` | `string[]` | `undefined` | Router link path |
|
|
927
|
+
| `queryParams` | `Params` | `undefined` | Router query params |
|
|
928
|
+
| `actions` | `HoverableListItemAction[]` | `undefined` | Action buttons shown on hover |
|
|
929
|
+
|
|
930
|
+
| Output | Type | Description |
|
|
931
|
+
| ---------------- | ------------------------- | ---------------------------------------- |
|
|
932
|
+
| `selected` | `void` | Emitted when item is clicked |
|
|
933
|
+
| `actionSelected` | `HoverableListItemAction` | Emitted when an action button is clicked |
|
|
934
|
+
|
|
935
|
+
---
|
|
936
|
+
|
|
937
|
+
### KeyValueListComponent
|
|
938
|
+
|
|
939
|
+
**Selector**: `ndw-key-value-list`
|
|
940
|
+
**Import**: `KeyValueListComponent`
|
|
941
|
+
|
|
942
|
+
| Input | Type | Default | Description |
|
|
943
|
+
| ----------------- | ---------------------- | ------------ | ---------------------------------------- |
|
|
944
|
+
| `data` | `KeyValueRow[]` | **required** | Array of `{key, value}` pairs to display |
|
|
945
|
+
| `hasZebraStripes` | `boolean` | `false` | Alternating row backgrounds |
|
|
946
|
+
| `fontSize` | `'sm' \| 'md' \| 'lg'` | `'sm'` | Text size |
|
|
947
|
+
| `fluid` | `boolean` | `false` | Full width layout |
|
|
948
|
+
|
|
949
|
+
```html
|
|
950
|
+
<ndw-key-value-list
|
|
951
|
+
[data]="[{key: 'Name', value: 'NDW'}, {key: 'Type', value: 'Organization'}]"
|
|
952
|
+
></ndw-key-value-list>
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
---
|
|
956
|
+
|
|
957
|
+
### LanguageSwitcherComponent
|
|
958
|
+
|
|
959
|
+
**Selector**: `ndw-language-switcher`
|
|
960
|
+
**Import**: `LanguageSwitcherComponent`
|
|
961
|
+
|
|
962
|
+
| Input | Type | Default | Description |
|
|
963
|
+
| ------------- | ----------------------------------------- | -------------- | -------------------------------- |
|
|
964
|
+
| `languages` | `Language[]` | `['NL', 'EN']` | Available language options |
|
|
965
|
+
| `displayMode` | `'flag-only' \| 'abbreviation' \| 'full'` | `'flag-only'` | How to render the language label |
|
|
966
|
+
|
|
967
|
+
| Model | Type | Default | Description |
|
|
968
|
+
| ---------- | ---------- | ------- | --------------------------- |
|
|
969
|
+
| `selected` | `Language` | `'NL'` | Currently selected language |
|
|
970
|
+
|
|
971
|
+
```html
|
|
972
|
+
<ndw-language-switcher
|
|
973
|
+
[(selected)]="currentLang"
|
|
974
|
+
displayMode="abbreviation"
|
|
975
|
+
></ndw-language-switcher>
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
---
|
|
979
|
+
|
|
980
|
+
### LayoutComponent
|
|
981
|
+
|
|
982
|
+
**Selector**: `ndw-layout`
|
|
983
|
+
**Import**: `LayoutComponent`
|
|
984
|
+
|
|
985
|
+
Main application layout with navigation sidebar.
|
|
986
|
+
|
|
987
|
+
| Input | Type | Default | Description |
|
|
988
|
+
| ----------------- | -------------------------------------- | ------------ | ----------------------- |
|
|
989
|
+
| `applicationName` | `string` | **required** | App name in sidebar |
|
|
990
|
+
| `topMenuItems` | `MenuItem[]` | **required** | Top navigation items |
|
|
991
|
+
| `bottomMenuItems` | `MenuItem[]` | `undefined` | Bottom navigation items |
|
|
992
|
+
| `environment` | `'Local' \| 'Staging' \| 'Acceptance'` | `undefined` | Environment badge |
|
|
993
|
+
| `isCollapsible` | `boolean` | `true` | Sidebar collapsible |
|
|
994
|
+
| `isExpanded` | `boolean` | `true` | Sidebar expanded |
|
|
995
|
+
| `menuFooterTexts` | `string[]` | `undefined` | Footer text lines |
|
|
996
|
+
| `version` | `string` | `undefined` | Version display |
|
|
997
|
+
|
|
998
|
+
**MenuItem interface**:
|
|
999
|
+
|
|
1000
|
+
```typescript
|
|
1001
|
+
interface MenuItem {
|
|
1002
|
+
label: string;
|
|
1003
|
+
icon: string; // Material icon name
|
|
1004
|
+
active?: boolean;
|
|
1005
|
+
path?: string[];
|
|
1006
|
+
queryParams?: Params;
|
|
1007
|
+
notifications?: number;
|
|
1008
|
+
callback?: () => void;
|
|
1009
|
+
children?: SubMenuItem[];
|
|
1010
|
+
}
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
```html
|
|
1014
|
+
<ndw-layout applicationName="My App" [topMenuItems]="menuItems" environment="Acceptance">
|
|
1015
|
+
<ndw-layout-banners>
|
|
1016
|
+
<ndw-banner title="Notice" message="System update"></ndw-banner>
|
|
1017
|
+
</ndw-layout-banners>
|
|
1018
|
+
<router-outlet></router-outlet>
|
|
1019
|
+
</ndw-layout>
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
---
|
|
1023
|
+
|
|
1024
|
+
### LayoutBannersComponent
|
|
1025
|
+
|
|
1026
|
+
**Selector**: `ndw-layout-banners`
|
|
1027
|
+
**Import**: `LayoutBannersComponent`
|
|
1028
|
+
|
|
1029
|
+
Container for banners inside `ndw-layout`. No inputs - content projection only.
|
|
1030
|
+
|
|
1031
|
+
---
|
|
1032
|
+
|
|
1033
|
+
### ListComponent
|
|
1034
|
+
|
|
1035
|
+
**Selector**: `ndw-list`
|
|
1036
|
+
**Import**: `ListComponent`
|
|
1037
|
+
|
|
1038
|
+
| Input | Type | Default | Description |
|
|
1039
|
+
| ---------- | --------- | ------- | -------------------------------- |
|
|
1040
|
+
| `elevated` | `boolean` | `false` | Add shadow elevation to the list |
|
|
1041
|
+
|
|
1042
|
+
### ListItemComponent
|
|
1043
|
+
|
|
1044
|
+
**Selector**: `ndw-list-item`
|
|
1045
|
+
**Import**: `ListItemComponent`
|
|
1046
|
+
|
|
1047
|
+
| Input | Type | Default | Description |
|
|
1048
|
+
| --------------------- | ----------------------- | ------------ | ---------------------------------------- |
|
|
1049
|
+
| `title` | `string` | `undefined` | Item title text |
|
|
1050
|
+
| `subtitle` | `string` | `undefined` | Secondary text below title |
|
|
1051
|
+
| `prefixIcon` | `string` | `undefined` | Material icon before title |
|
|
1052
|
+
| `buttonIcon` | `string` | `undefined` | Icon for the action button |
|
|
1053
|
+
| `buttonLabel` | `string` | `undefined` | Label for the action button |
|
|
1054
|
+
| `badgeValue` | `number` | `undefined` | Numeric badge value |
|
|
1055
|
+
| `pillLabel` | `string` | `undefined` | Pill label text |
|
|
1056
|
+
| `pillColor` | `PillColor` | `'green'` | Pill color variant |
|
|
1057
|
+
| `checkable` | `boolean` | `false` | Show checkbox/radio |
|
|
1058
|
+
| `checkType` | `'checkbox' \| 'radio'` | `'checkbox'` | Check input type |
|
|
1059
|
+
| `collapsible` | `boolean` | `false` | Enable expand/collapse of nested content |
|
|
1060
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
1061
|
+
| `indented` | `boolean` | `false` | Indent item (for nested lists) |
|
|
1062
|
+
| `showButton` | `boolean` | `false` | Show action button |
|
|
1063
|
+
| `displayLargeNumbers` | `boolean` | `false` | Show badge values > 99 |
|
|
1064
|
+
|
|
1065
|
+
| Model | Type | Default | Description |
|
|
1066
|
+
| ---------- | --------- | ------- | --------------------------------- |
|
|
1067
|
+
| `active` | `boolean` | `false` | Active/highlighted state |
|
|
1068
|
+
| `checked` | `boolean` | `false` | Checked state (when checkable) |
|
|
1069
|
+
| `expanded` | `boolean` | `false` | Expanded state (when collapsible) |
|
|
1070
|
+
|
|
1071
|
+
| Output | Type | Description |
|
|
1072
|
+
| --------------- | ------ | ------------------------------------- |
|
|
1073
|
+
| `buttonClicked` | `void` | Emitted when action button is clicked |
|
|
1074
|
+
|
|
1075
|
+
```html
|
|
1076
|
+
<ndw-list [elevated]="true">
|
|
1077
|
+
<ndw-list-item
|
|
1078
|
+
title="Item 1"
|
|
1079
|
+
subtitle="Description"
|
|
1080
|
+
prefixIcon="folder"
|
|
1081
|
+
[checkable]="true"
|
|
1082
|
+
[(checked)]="item1Checked"
|
|
1083
|
+
></ndw-list-item>
|
|
1084
|
+
<ndw-list-item title="Item 2" [collapsible]="true"> Nested content </ndw-list-item>
|
|
1085
|
+
</ndw-list>
|
|
1086
|
+
```
|
|
1087
|
+
|
|
1088
|
+
---
|
|
1089
|
+
|
|
1090
|
+
### LoaderComponent
|
|
1091
|
+
|
|
1092
|
+
**Selector**: `ndw-loader`
|
|
1093
|
+
**Import**: `LoaderComponent`
|
|
1094
|
+
|
|
1095
|
+
No inputs. Displays a spinning loader animation.
|
|
1096
|
+
|
|
1097
|
+
```html
|
|
1098
|
+
<ndw-loader></ndw-loader>
|
|
1099
|
+
```
|
|
1100
|
+
|
|
1101
|
+
---
|
|
1102
|
+
|
|
1103
|
+
### MapButtonComponent
|
|
1104
|
+
|
|
1105
|
+
**Selector**: `ndw-map-button`
|
|
1106
|
+
**Import**: `MapButtonComponent`
|
|
1107
|
+
|
|
1108
|
+
| Input | Type | Default | Description |
|
|
1109
|
+
| ----------- | --------------- | ----------- | -------------------- |
|
|
1110
|
+
| `icon` | `MapButtonIcon` | `undefined` | Button icon |
|
|
1111
|
+
| `active` | `boolean` | `false` | Active/pressed state |
|
|
1112
|
+
| `ariaLabel` | `string` | `undefined` | Custom aria label |
|
|
1113
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
1114
|
+
|
|
1115
|
+
| Output | Type | Description |
|
|
1116
|
+
| --------- | ------ | ------------------------------ |
|
|
1117
|
+
| `clicked` | `void` | Emitted when button is clicked |
|
|
1118
|
+
|
|
1119
|
+
**MapButtonIcon values**: `'direction'`, `'gps'`, `'high-res'`, `'layers'`, `'polygon'`, `'search'`, `'zoom-in'`, `'zoom-out'`, `'mail'`, `'add-traffic-sign'`, `'add-zone'`, `'download'`, `'hectometer'`, `'low-res'`, `'zoom-to-content'`
|
|
1120
|
+
|
|
1121
|
+
```html
|
|
1122
|
+
<ndw-map-button icon="zoom-in" (clicked)="zoomIn()"></ndw-map-button>
|
|
1123
|
+
<ndw-map-button icon="layers" [active]="showLayers" (clicked)="toggleLayers()"></ndw-map-button>
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
---
|
|
1127
|
+
|
|
1128
|
+
### MapDisplayComponent
|
|
1129
|
+
|
|
1130
|
+
**Selector**: `ndw-map-display`
|
|
1131
|
+
**Import**: `MapDisplayComponent`
|
|
1132
|
+
|
|
1133
|
+
| Input | Type | Default | Description |
|
|
1134
|
+
| ------------------- | ----------------------- | ----------------- | ------------------------------- |
|
|
1135
|
+
| `title` | `string` | `'Kaartweergave'` | Panel title |
|
|
1136
|
+
| `backgroundsTitle` | `string` | `'Achtergrond'` | Background section title |
|
|
1137
|
+
| `layersTitle` | `string` | `'Gegevens'` | Layers section title |
|
|
1138
|
+
| `enableClearLayers` | `boolean` | `true` | Show clear-all layers button |
|
|
1139
|
+
| `layerOptionType` | `'radio' \| 'checkbox'` | `'checkbox'` | Single or multi layer selection |
|
|
1140
|
+
| `backgroundOptions` | `MapBackgroundOption[]` | `[]` | Available map backgrounds |
|
|
1141
|
+
| `layerOptions` | `MapDisplayOption[]` | `[]` | Available data layers |
|
|
1142
|
+
|
|
1143
|
+
| Model | Type | Description |
|
|
1144
|
+
| ------ | --------- | ----------------------- |
|
|
1145
|
+
| `open` | `boolean` | Panel open/closed state |
|
|
1146
|
+
|
|
1147
|
+
| Output | Type | Description |
|
|
1148
|
+
| ------------------ | --------------------- | ----------------------------------------- |
|
|
1149
|
+
| `backgroundChange` | `MapBackgroundOption` | Emitted when background selection changes |
|
|
1150
|
+
| `layerChange` | `MapDisplayOption` | Emitted when a layer is toggled |
|
|
1151
|
+
| `clearAllLayers` | `void` | Emitted when clear-all is clicked |
|
|
1152
|
+
|
|
1153
|
+
**MapDisplayOption interface**:
|
|
1154
|
+
|
|
1155
|
+
```typescript
|
|
1156
|
+
interface MapDisplayOption {
|
|
1157
|
+
id: string;
|
|
1158
|
+
name: string;
|
|
1159
|
+
active?: boolean;
|
|
1160
|
+
imageLink?: string;
|
|
1161
|
+
icon?: string;
|
|
1162
|
+
description?: string;
|
|
1163
|
+
}
|
|
1164
|
+
type MapBackgroundOption<T = string> = MapDisplayOption & { style: T };
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
---
|
|
1168
|
+
|
|
1169
|
+
### MapLegendComponent
|
|
1170
|
+
|
|
1171
|
+
**Selector**: `ndw-map-legend`
|
|
1172
|
+
**Import**: `MapLegendComponent`
|
|
1173
|
+
|
|
1174
|
+
| Input | Type | Default | Description |
|
|
1175
|
+
| ---------- | ------------------------ | ----------------- | ---------------------------------- |
|
|
1176
|
+
| `groups` | `MapLegendOptionGroup[]` | **required** | Legend option groups |
|
|
1177
|
+
| `icon` | `string` | `'legend_toggle'` | Trigger button icon |
|
|
1178
|
+
| `title` | `string` | `'Legenda'` | Panel title |
|
|
1179
|
+
| `viewMode` | `'dropdown' \| 'fixed'` | `'dropdown'` | Dropdown popover or always-visible |
|
|
1180
|
+
|
|
1181
|
+
| Model | Type | Description |
|
|
1182
|
+
| ------ | --------- | ----------------------- |
|
|
1183
|
+
| `open` | `boolean` | Panel open/closed state |
|
|
1184
|
+
|
|
1185
|
+
**MapLegendOptionGroup interface**:
|
|
1186
|
+
|
|
1187
|
+
```typescript
|
|
1188
|
+
interface MapLegendOptionGroup {
|
|
1189
|
+
label?: string;
|
|
1190
|
+
options: MapLegendOption[];
|
|
1191
|
+
}
|
|
1192
|
+
// MapLegendOption types: 'image', 'line', 'circle', 'polygon', 'area', 'icon'
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
---
|
|
1196
|
+
|
|
1197
|
+
### ModalComponent & ModalService
|
|
1198
|
+
|
|
1199
|
+
**Selector**: `ndw-modal`
|
|
1200
|
+
**Import**: `ModalComponent`, `ModalHeaderComponent`, `ModalService`
|
|
1201
|
+
|
|
1202
|
+
| Input | Type | Default | Description |
|
|
1203
|
+
| ------ | -------------- | ------- | ---------------------------- |
|
|
1204
|
+
| `size` | `'sm' \| 'md'` | `'sm'` | Modal width (500px or 720px) |
|
|
1205
|
+
|
|
1206
|
+
**ModalService** (injectable):
|
|
1207
|
+
|
|
1208
|
+
- `open(componentOrTemplate, config?)` - Opens a modal, returns `ModalRef`
|
|
1209
|
+
- `close()` - Closes the current modal
|
|
1210
|
+
- `backdropClick$` - Observable for backdrop clicks
|
|
1211
|
+
- `closed$` - Observable for modal close
|
|
1212
|
+
|
|
1213
|
+
```typescript
|
|
1214
|
+
// Opening a modal
|
|
1215
|
+
const ref = this.modalService.open(MyDialogComponent, {
|
|
1216
|
+
backdropClass: 'ndw-overlay-backdrop',
|
|
1217
|
+
});
|
|
1218
|
+
```
|
|
1219
|
+
|
|
1220
|
+
```html
|
|
1221
|
+
<!-- Inside the modal component template -->
|
|
1222
|
+
<ndw-modal size="md">
|
|
1223
|
+
<ndw-modal-header>Modal Title</ndw-modal-header>
|
|
1224
|
+
<ndw-card-content>Modal body</ndw-card-content>
|
|
1225
|
+
<ndw-card-footer>
|
|
1226
|
+
<button ndwButton (click)="close()">Close</button>
|
|
1227
|
+
</ndw-card-footer>
|
|
1228
|
+
</ndw-modal>
|
|
1229
|
+
```
|
|
1230
|
+
|
|
1231
|
+
---
|
|
1232
|
+
|
|
1233
|
+
### MultiSelectComponent
|
|
1234
|
+
|
|
1235
|
+
**Selector**: `ndw-multi-select`
|
|
1236
|
+
**Import**: `MultiSelectComponent`
|
|
1237
|
+
|
|
1238
|
+
| Input | Type | Default | Description |
|
|
1239
|
+
| -------------------- | --------------- | ------------------------------------------------------------ | ------------------------------------- |
|
|
1240
|
+
| `buttonText` | `string` | **required** | Dropdown trigger button label |
|
|
1241
|
+
| `searchLabel` | `string` | `'Zoek in lijst.'` | Aria label for search input |
|
|
1242
|
+
| `searchPlaceholder` | `string` | `'Zoek in lijst...'` | Search input placeholder |
|
|
1243
|
+
| `noResultText` | `string` | Dutch default | Text shown when search has no matches |
|
|
1244
|
+
| `prefixIcon` | `string` | `''` | Material icon before button text |
|
|
1245
|
+
| `chevron` | `boolean` | `true` | Show dropdown chevron icon |
|
|
1246
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
1247
|
+
| `selectAmountHidden` | `boolean` | `false` | Hide selected count badge |
|
|
1248
|
+
| `selectAllText` | `SelectAllText` | `{deselect: 'Deselecteer alles', select: 'Selecteer alles'}` | Select/deselect all button labels |
|
|
1249
|
+
| `allowSelectAll` | `boolean` | `true` | Show select-all toggle |
|
|
1250
|
+
|
|
1251
|
+
| Model | Type | Description |
|
|
1252
|
+
| ------------ | ---------------- | ----------------------------------- |
|
|
1253
|
+
| `dataSource` | `CheckboxData[]` | Checkbox items with selection state |
|
|
1254
|
+
|
|
1255
|
+
**CheckboxData interface**: `{ id: string \| number; label: string; value: boolean }`
|
|
1256
|
+
|
|
1257
|
+
```html
|
|
1258
|
+
<ndw-multi-select buttonText="Categories" [(dataSource)]="categories"></ndw-multi-select>
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
---
|
|
1262
|
+
|
|
1263
|
+
### PillComponent
|
|
1264
|
+
|
|
1265
|
+
**Selector**: `ndw-pill`
|
|
1266
|
+
**Import**: `PillComponent`
|
|
1267
|
+
|
|
1268
|
+
| Input | Type | Default | Description |
|
|
1269
|
+
| ------- | -------------------------------------------------------------- | --------- | ------------- |
|
|
1270
|
+
| `color` | `'blue' \| 'gray' \| 'green' \| 'purple' \| 'red' \| 'yellow'` | `'green'` | Color variant |
|
|
1271
|
+
|
|
1272
|
+
```html
|
|
1273
|
+
<ndw-pill color="blue">Active</ndw-pill>
|
|
1274
|
+
```
|
|
1275
|
+
|
|
1276
|
+
---
|
|
1277
|
+
|
|
1278
|
+
### PopoverTriggerDirective
|
|
1279
|
+
|
|
1280
|
+
**Selector**: `[ndwPopoverTrigger]`
|
|
1281
|
+
**Import**: `PopoverTriggerDirective`
|
|
1282
|
+
**Export as**: `ndwPopoverTrigger`
|
|
1283
|
+
|
|
1284
|
+
| Input | Type | Default | Description |
|
|
1285
|
+
| ------------------- | ---------------------------------------------- | ----------------------- | ------------------------------------- |
|
|
1286
|
+
| `ndwPopoverTrigger` | `TemplateRef` | **required** | Template to render as popover content |
|
|
1287
|
+
| `popoverPosition` | `'nextToTriggerButton' \| 'overTriggerButton'` | `'nextToTriggerButton'` | Popover placement relative to trigger |
|
|
1288
|
+
| `toggleOnClick` | `boolean` | `true` | Toggle open/close on click |
|
|
1289
|
+
|
|
1290
|
+
| Model | Type | Description |
|
|
1291
|
+
| -------- | --------- | ------------------------- |
|
|
1292
|
+
| `isOpen` | `boolean` | Popover open/closed state |
|
|
1293
|
+
|
|
1294
|
+
| Output | Type | Description |
|
|
1295
|
+
| ---------------- | --------- | ------------------------------------ |
|
|
1296
|
+
| `popoverToggled` | `boolean` | Emitted when popover opens or closes |
|
|
1297
|
+
|
|
1298
|
+
Close popover from inside with `ndwPopoverCloseTrigger` attribute.
|
|
1299
|
+
|
|
1300
|
+
```html
|
|
1301
|
+
<button [ndwPopoverTrigger]="popoverContent">Open</button>
|
|
1302
|
+
<ng-template #popoverContent>
|
|
1303
|
+
<div>Popover content</div>
|
|
1304
|
+
<button ndwPopoverCloseTrigger>Close</button>
|
|
1305
|
+
</ng-template>
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
---
|
|
1309
|
+
|
|
1310
|
+
### SplitterComponent
|
|
1311
|
+
|
|
1312
|
+
**Selector**: `ndw-splitter`
|
|
1313
|
+
**Import**: `SplitterComponent`
|
|
1314
|
+
|
|
1315
|
+
| Input | Type | Default | Description |
|
|
1316
|
+
| ------------------ | ---------------- | ------- | ----------------------------- |
|
|
1317
|
+
| `disabled` | `boolean` | `false` | Disable dragging |
|
|
1318
|
+
| `horizontal` | `boolean` | `false` | Horizontal split (top/bottom) |
|
|
1319
|
+
| `initialPanelSize` | `number \| null` | `null` | Initial first panel size (px) |
|
|
1320
|
+
| `minimumPanelSize` | `number` | `0` | Minimum panel size (px) |
|
|
1321
|
+
|
|
1322
|
+
Projects two panels via `ng-content` using `[first-panel]` and `[second-panel]` attribute selectors.
|
|
1323
|
+
|
|
1324
|
+
```html
|
|
1325
|
+
<ndw-splitter [initialPanelSize]="300" [minimumPanelSize]="100">
|
|
1326
|
+
<div first-panel>Left panel</div>
|
|
1327
|
+
<div second-panel>Right panel</div>
|
|
1328
|
+
</ndw-splitter>
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
---
|
|
1332
|
+
|
|
1333
|
+
### SwitcherComponent
|
|
1334
|
+
|
|
1335
|
+
**Selector**: `ndw-switcher`
|
|
1336
|
+
**Import**: `SwitcherComponent`
|
|
1337
|
+
**CVA**: Yes
|
|
1338
|
+
|
|
1339
|
+
| Input | Type | Default | Description |
|
|
1340
|
+
| ---------- | ------------------ | ------- | ------------------------ |
|
|
1341
|
+
| `options` | `SwitcherOption[]` | `[]` | Available toggle options |
|
|
1342
|
+
| `vertical` | `boolean` | `false` | Vertical layout |
|
|
1343
|
+
|
|
1344
|
+
| Model | Type | Description |
|
|
1345
|
+
| --------------- | --------------- | ------------------------ |
|
|
1346
|
+
| `selectedValue` | `SwitcherValue` | Currently selected value |
|
|
1347
|
+
| `disabled` | `boolean` | Disabled state |
|
|
1348
|
+
|
|
1349
|
+
| Output | Type | Description |
|
|
1350
|
+
| ----------------- | --------------- | ------------------------------ |
|
|
1351
|
+
| `selectionChange` | `SwitcherValue` | Emitted when selection changes |
|
|
1352
|
+
|
|
1353
|
+
**SwitcherOption**: `{ value: string \| number \| boolean; label: string; icon?: string; disabled?: boolean }`
|
|
1354
|
+
|
|
1355
|
+
```html
|
|
1356
|
+
<ndw-switcher
|
|
1357
|
+
[options]="[{value: 'map', label: 'Map'}, {value: 'list', label: 'List'}]"
|
|
1358
|
+
[(selectedValue)]="view"
|
|
1359
|
+
></ndw-switcher>
|
|
1360
|
+
```
|
|
1361
|
+
|
|
1362
|
+
---
|
|
1363
|
+
|
|
1364
|
+
### TabComponent & TabGroupComponent
|
|
1365
|
+
|
|
1366
|
+
**Selectors**: `ndw-tab`, `ndw-tab-group`
|
|
1367
|
+
**Import**: `TabComponent`, `TabGroupComponent`
|
|
1368
|
+
|
|
1369
|
+
**TabGroupComponent**:
|
|
1370
|
+
| Input | Type | Default | Description |
|
|
1371
|
+
|---|---|---|---|
|
|
1372
|
+
| `hasPadding` | `boolean` | `false` | Add padding around tab content |
|
|
1373
|
+
| `inlinePadding` | `number` | `0` | Inline padding in px for tab bar |
|
|
1374
|
+
|
|
1375
|
+
| Model | Type | Description |
|
|
1376
|
+
| ------------- | ------------------ | -------------------- |
|
|
1377
|
+
| `activeTabId` | `string \| number` | ID of the active tab |
|
|
1378
|
+
|
|
1379
|
+
**TabComponent**:
|
|
1380
|
+
| Input | Type | Default | Description |
|
|
1381
|
+
|---|---|---|---|
|
|
1382
|
+
| `title` | `string` | **required** | Tab label text |
|
|
1383
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
1384
|
+
| `hasError` | `boolean` | `false` | Show error indicator |
|
|
1385
|
+
| `icon` | `string` | `undefined` | Material icon in tab header |
|
|
1386
|
+
| `id` | `string \| number` | auto-generated | Unique tab identifier |
|
|
1387
|
+
|
|
1388
|
+
```html
|
|
1389
|
+
<ndw-tab-group [(activeTabId)]="activeTab">
|
|
1390
|
+
<ndw-tab title="Overview" id="overview">Tab 1 content</ndw-tab>
|
|
1391
|
+
<ndw-tab title="Details" id="details" icon="info">Tab 2 content</ndw-tab>
|
|
1392
|
+
<ndw-tab title="Disabled" [disabled]="true">Tab 3</ndw-tab>
|
|
1393
|
+
</ndw-tab-group>
|
|
1394
|
+
```
|
|
1395
|
+
|
|
1396
|
+
---
|
|
1397
|
+
|
|
1398
|
+
### TagComponent
|
|
1399
|
+
|
|
1400
|
+
**Selector**: `ndw-tag`
|
|
1401
|
+
**Import**: `TagComponent`
|
|
1402
|
+
|
|
1403
|
+
| Input | Type | Default | Description |
|
|
1404
|
+
| ----------------- | --------- | ------------- | -------------------------------------- |
|
|
1405
|
+
| `disabled` | `boolean` | `false` | Disabled state |
|
|
1406
|
+
| `suffixAriaLabel` | `string` | `'Verwijder'` | Aria label for the suffix/close button |
|
|
1407
|
+
| `suffixIcon` | `string` | `'close'` | Material icon for the suffix button |
|
|
1408
|
+
|
|
1409
|
+
| Output | Type | Description |
|
|
1410
|
+
| --------- | ------- | ------------------------------------- |
|
|
1411
|
+
| `clicked` | `Event` | Emitted when suffix button is clicked |
|
|
1412
|
+
|
|
1413
|
+
```html
|
|
1414
|
+
<ndw-tag (clicked)="removeTag()">Tag label</ndw-tag>
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
---
|
|
1418
|
+
|
|
1419
|
+
### ToastService & ToastComponent
|
|
1420
|
+
|
|
1421
|
+
**Import**: `ToastService` (injectable)
|
|
1422
|
+
|
|
1423
|
+
| Method | Parameters | Returns | Description |
|
|
1424
|
+
| ---------- | ----------------------------------------------------------------------------------------- | ------------------- | ---------------------------- |
|
|
1425
|
+
| `open()` | `message: string, duration?: number, closeButtonLabel?: string, type?: 'info' \| 'error'` | `string` (toast ID) | Show a toast |
|
|
1426
|
+
| `close()` | `id?: string` | `void` | Close specific or all toasts |
|
|
1427
|
+
| `pause()` | - | `void` | Pause auto-dismiss timer |
|
|
1428
|
+
| `resume()` | - | `void` | Resume timer |
|
|
1429
|
+
|
|
1430
|
+
Error toasts do not auto-dismiss. Max 3 toasts shown simultaneously.
|
|
1431
|
+
|
|
1432
|
+
```typescript
|
|
1433
|
+
this.toastService.open('Changes saved successfully');
|
|
1434
|
+
this.toastService.open('Something went wrong', 0, 'Dismiss', 'error');
|
|
1435
|
+
```
|
|
1436
|
+
|
|
1437
|
+
---
|
|
1438
|
+
|
|
1439
|
+
### TooltipDirective
|
|
1440
|
+
|
|
1441
|
+
**Selector**: `[ndwTooltip]`
|
|
1442
|
+
**Import**: `TooltipDirective`
|
|
1443
|
+
|
|
1444
|
+
| Input | Type | Description |
|
|
1445
|
+
| ------------ | -------- | ----------------------- |
|
|
1446
|
+
| `ndwTooltip` | `string` | Tooltip text (required) |
|
|
1447
|
+
|
|
1448
|
+
```html
|
|
1449
|
+
<ndw-icon [ndwTooltip]="'More information'">info</ndw-icon>
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
---
|
|
1453
|
+
|
|
1454
|
+
### Summary Card (CSS-only)
|
|
1455
|
+
|
|
1456
|
+
Uses CSS classes, not a component:
|
|
1457
|
+
|
|
1458
|
+
```html
|
|
1459
|
+
<div class="ndw-summary-card">
|
|
1460
|
+
<div class="ndw-summary-card__wrapper">
|
|
1461
|
+
<div class="ndw-summary-card__content">
|
|
1462
|
+
<div class="ndw-summary-card-header">
|
|
1463
|
+
<div class="ndw-summary-card-header__wrapper">
|
|
1464
|
+
<h3 class="ndw-summary-card-header__title">
|
|
1465
|
+
<a href="/detail">Card Title</a>
|
|
1466
|
+
</h3>
|
|
1467
|
+
<div class="ndw-summary-card-subtitle">
|
|
1468
|
+
<ndw-icon>location_on</ndw-icon>
|
|
1469
|
+
<span class="ndw-summary-card-subtitle__text">Subtitle</span>
|
|
1470
|
+
</div>
|
|
1471
|
+
</div>
|
|
1472
|
+
</div>
|
|
1473
|
+
<p class="ndw-summary-card-content">Description text</p>
|
|
1474
|
+
<div class="ndw-summary-card-tags">
|
|
1475
|
+
<span class="ndw-summary-card-tag"><ndw-icon>label</ndw-icon> Tag</span>
|
|
1476
|
+
</div>
|
|
1477
|
+
</div>
|
|
1478
|
+
</div>
|
|
1479
|
+
</div>
|
|
1480
|
+
```
|
|
1481
|
+
|
|
1482
|
+
---
|
|
1483
|
+
|
|
1484
|
+
### GuidedTourService
|
|
1485
|
+
|
|
1486
|
+
**Import**: `GuidedTourService` (injectable)
|
|
1487
|
+
|
|
1488
|
+
Wraps [Shepherd.js](https://shepherdjs.dev/) for guided tours.
|
|
1489
|
+
|
|
1490
|
+
| Method | Description |
|
|
1491
|
+
| -------------------------------- | -------------------------- |
|
|
1492
|
+
| `addSteps(steps: StepOptions[])` | Initialize tour with steps |
|
|
1493
|
+
| `start()` | Start the tour |
|
|
1494
|
+
| `next()` / `back()` | Navigate steps |
|
|
1495
|
+
| `cancel()` / `complete()` | End the tour |
|
|
1496
|
+
| `show(id)` | Show specific step |
|
|
1497
|
+
|
|
1498
|
+
| Property | Type | Default |
|
|
1499
|
+
| -------------------- | --------- | ------- |
|
|
1500
|
+
| `modal` | `boolean` | `false` |
|
|
1501
|
+
| `exitOnEsc` | `boolean` | `true` |
|
|
1502
|
+
| `keyboardNavigation` | `boolean` | `true` |
|
|
1503
|
+
|
|
1504
|
+
---
|
|
1505
|
+
|
|
1506
|
+
### AG Grid Theme
|
|
1507
|
+
|
|
1508
|
+
**Import**: `ndwAgGridTheme`
|
|
1509
|
+
|
|
1510
|
+
Pre-configured AG Grid theme using NDW design tokens.
|
|
1511
|
+
|
|
1512
|
+
```typescript
|
|
1513
|
+
import { ndwAgGridTheme } from '@ndwnu/design-system';
|
|
1514
|
+
import { themeQuartz } from 'ag-grid-community';
|
|
1515
|
+
|
|
1516
|
+
const theme = themeQuartz.withParams(ndwAgGridTheme);
|
|
1517
|
+
```
|
|
1518
|
+
|
|
1519
|
+
---
|
|
1520
|
+
|
|
1521
|
+
## List-item CSS directive
|
|
1522
|
+
|
|
1523
|
+
```html
|
|
1524
|
+
<div ndw-list-item>Styled list item with ndw-paragraph-md and cursor pointer</div>
|
|
1525
|
+
```
|