@scania-nl/tegel-angular-extensions 0.0.7 → 0.0.9
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/README.md +508 -54
- package/esm2022/index.mjs +9 -1
- package/esm2022/lib/components/tae-date-time-picker/tae-date-time-picker.component.mjs +366 -0
- package/esm2022/lib/components/tae-date-time-picker/tae-date-time-picker.constants.mjs +24 -0
- package/esm2022/lib/components/tae-date-time-picker/tae-date-time-picker.utils.mjs +148 -0
- package/esm2022/lib/directives/typed-template.directive.mjs +38 -0
- package/esm2022/lib/env/angular/provide-runtime-config.mjs +7 -5
- package/esm2022/lib/modal/components/modal/modal.component.mjs +128 -0
- package/esm2022/lib/modal/components/modal-host/modal-host.component.mjs +32 -0
- package/esm2022/lib/modal/directives/dynamic-component.directive.mjs +135 -0
- package/esm2022/lib/modal/modal.service.mjs +156 -0
- package/esm2022/lib/modal/provide-modal.mjs +25 -0
- package/esm2022/lib/modal/schema/modal-ref.mjs +2 -0
- package/esm2022/lib/modal/schema/modal.config.mjs +15 -0
- package/esm2022/lib/modal/schema/modal.model.mjs +2 -0
- package/esm2022/lib/modal/schema/modal.types.mjs +3 -0
- package/esm2022/lib/toast/provide-toast.mjs +7 -1
- package/esm2022/lib/utils/angular-component-io.mjs +2 -0
- package/index.d.ts +415 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,24 +5,30 @@
|
|
|
5
5
|
|
|
6
6
|
# @scania-nl/tegel-angular-extensions
|
|
7
7
|
|
|
8
|
-
Angular services for working with the [Tegel Angular 17](https://www.npmjs.com/package/@scania/tegel-angular-17) component library.
|
|
9
|
-
Provides simple wrappers for toast and modal
|
|
8
|
+
Angular components, services, and directives for working with the [Tegel Angular 17](https://www.npmjs.com/package/@scania/tegel-angular-17) component library.
|
|
9
|
+
Provides simple wrappers for toast and modal functionality using Angular 19+ **standalone components** and **dependency injection configuration**.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Features
|
|
14
16
|
|
|
15
17
|
1. **Runtime environment configuration**
|
|
16
18
|
- Schema-driven configuration and validation using Zod
|
|
17
19
|
- Deep-partial runtime overrides
|
|
18
20
|
- Runtime-required key enforcements
|
|
19
21
|
- Strong TypeScript inference
|
|
20
|
-
2. **
|
|
21
|
-
- Drop-in UI integrations for Tegel Angular
|
|
22
|
+
2. **Toast management**
|
|
22
23
|
- Signal-based `ToastService` for displaying toasts
|
|
23
24
|
- Customizable toast appearance and behavior
|
|
24
|
-
3. **
|
|
25
|
-
|
|
25
|
+
3. **Modal management**
|
|
26
|
+
- Strongly typed modal API
|
|
27
|
+
- Dynamic body content (string, template, or component)
|
|
28
|
+
- Configurable actions and lifecycle callbacks
|
|
29
|
+
4. **Standalone components and directives**
|
|
30
|
+
- Drop-in UI integrations for Tegel Angular
|
|
31
|
+
5. **Default Nginx config**
|
|
26
32
|
|
|
27
33
|
- Zero boilerplate - no Angular modules required
|
|
28
34
|
- Fully typed and configurable via DI
|
|
@@ -30,10 +36,12 @@ Provides simple wrappers for toast and modal (TBC) functionality using Angular 1
|
|
|
30
36
|
|
|
31
37
|
---
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Table of Contents
|
|
34
42
|
|
|
35
|
-
1. [Installation](
|
|
36
|
-
2. [Environment Configuration Overview](
|
|
43
|
+
1. [Installation](#installation)
|
|
44
|
+
2. [Environment Configuration Overview](#environment-configuration-overview)
|
|
37
45
|
1. [Defining your schema with createEnvKit](#defining-your-schema-with-createenvkit)
|
|
38
46
|
2. [Defining Static Environments (Dev/Prod)](#defining-static-environments-devprod)
|
|
39
47
|
3. [Providing Runtime Configuration](#providing-runtime-configuration)
|
|
@@ -43,28 +51,40 @@ Provides simple wrappers for toast and modal (TBC) functionality using Angular 1
|
|
|
43
51
|
2. [`extract-env-vars.sh`](#extract-env-varssh)
|
|
44
52
|
3. [`nginx.conf`](#nginxconf)
|
|
45
53
|
4. [Example Docker Commands](#example-docker-commands)
|
|
46
|
-
3. [Toasts](
|
|
47
|
-
1. [Quick Start](
|
|
54
|
+
3. [Toasts](#toasts)
|
|
55
|
+
1. [Quick Start](#quick-start)
|
|
48
56
|
1. [Add Providers](#add-providers)
|
|
49
57
|
2. [Use in components](#use-in-components)
|
|
50
|
-
2. [Configuration Options](
|
|
51
|
-
3. [ToastService API](
|
|
52
|
-
1. [ToastService Properties](
|
|
53
|
-
2. [ToastService Methods](
|
|
54
|
-
3. [Toast Lifecycle Hooks](
|
|
55
|
-
4. [
|
|
56
|
-
1. [
|
|
58
|
+
2. [Toast Configuration Options](#toast-configuration-options)
|
|
59
|
+
3. [ToastService API](#toastservice-api)
|
|
60
|
+
1. [ToastService Properties](#toastservice-properties)
|
|
61
|
+
2. [ToastService Methods](#toastservice-methods)
|
|
62
|
+
3. [Toast Lifecycle Hooks](#toast-lifecycle-hooks)
|
|
63
|
+
4. [Modals](#modals)
|
|
64
|
+
1. [Quick Start](#quick-start-1)
|
|
65
|
+
1. [Add Providers](#add-providers-1)
|
|
66
|
+
2. [Use in components](#use-in-components-1)
|
|
67
|
+
2. [Modal Configuration Options](#modal-configuration-options)
|
|
68
|
+
3. [ModalService API](#modalservice-api)
|
|
69
|
+
1. [ModalService Properties](#modalservice-properties)
|
|
70
|
+
2. [ModalService Methods](#modalservice-methods)
|
|
71
|
+
3. [Modal Lifecycle Hooks](#modal-lifecycle-hooks)
|
|
72
|
+
5. [Components & Directives](#components--directives)
|
|
73
|
+
1. [Components](#components)
|
|
74
|
+
1. [DateTime Picker](#datetime-picker-component-tae-date-time-picker)
|
|
57
75
|
1. [Footer](#footer-component-tae-footer)
|
|
58
|
-
2. [Directives](
|
|
76
|
+
2. [Directives](#directives)
|
|
59
77
|
1. [Hard Refresh](#hard-refresh-directive-taehardrefresh)
|
|
60
78
|
2. [Barcode Scanner](#barcode-scanner-directive-taebarcodescanner)
|
|
61
|
-
|
|
79
|
+
6. [Appendix](#appendix)
|
|
62
80
|
1. [Dockerfile Example](#runtime-config-dockerfile-example)
|
|
63
|
-
|
|
81
|
+
7. [License](#license)
|
|
64
82
|
|
|
65
83
|
---
|
|
66
84
|
|
|
67
|
-
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Installation
|
|
68
88
|
|
|
69
89
|
```bash
|
|
70
90
|
npm install @scania-nl/tegel-angular-extensions @scania/tegel-angular-17 @traversable/zod zod
|
|
@@ -76,16 +96,18 @@ When creating an Angular project, the following dependencies already should have
|
|
|
76
96
|
|
|
77
97
|
```json
|
|
78
98
|
{
|
|
79
|
-
"@angular/common": "
|
|
80
|
-
"@angular/core": "
|
|
81
|
-
"@angular/router": "
|
|
99
|
+
"@angular/common": ">=19",
|
|
100
|
+
"@angular/core": ">=19",
|
|
101
|
+
"@angular/router": ">=19",
|
|
82
102
|
"rxjs": ">=7.8.0"
|
|
83
103
|
}
|
|
84
104
|
```
|
|
85
105
|
|
|
86
106
|
---
|
|
87
107
|
|
|
88
|
-
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# Environment Configuration Overview
|
|
89
111
|
|
|
90
112
|
The runtime-config system provides:
|
|
91
113
|
|
|
@@ -94,6 +116,8 @@ The runtime-config system provides:
|
|
|
94
116
|
- Runtime overrides via .env files (shell scripts included)
|
|
95
117
|
- Guaranteed config availability before app bootstrap
|
|
96
118
|
|
|
119
|
+
|
|
120
|
+
|
|
97
121
|
## Defining your schema with createEnvKit
|
|
98
122
|
|
|
99
123
|
Create a local file: `src/environments/environment-config.ts`
|
|
@@ -207,7 +231,7 @@ This setup involves several key steps:
|
|
|
207
231
|
- At application startup, the code loads `/env/runtime.env`, parses any overrides using Zod (via a deep-partial schema), and merges them with the static configuration.
|
|
208
232
|
- Required configuration keys are enforced **only** in production.
|
|
209
233
|
- The validated configuration is exposed through Angular DI using the `ENV_CONFIG` InjectionToken.
|
|
210
|
-
- The `environment` file is referenced directly here. Angular
|
|
234
|
+
- The `environment` file is referenced directly here. Angular's build process replaces the `development` environment with the `production` environment via file replacement based on the selected build configuration.
|
|
211
235
|
|
|
212
236
|
> The `/env/runtime.env` file must be generated by the container during startup.
|
|
213
237
|
> Shell script binaries to support this are included the package.
|
|
@@ -218,12 +242,16 @@ This setup involves several key steps:
|
|
|
218
242
|
|
|
219
243
|
This package ships with two lightweight shell scripts used to generate a runtime configuration file inside the container. They enable true runtime configurability without rebuilding the Angular image. Additionally, the package contains a default `nginx.conf` optimized for Angular application. The files are located in the `/docker` directory.
|
|
220
244
|
|
|
245
|
+
|
|
246
|
+
|
|
221
247
|
### `docker-entrypoint.sh`
|
|
222
248
|
|
|
223
249
|
- Entry point executed every time the container starts
|
|
224
250
|
- Calls the `extract-env-vars.sh` to generate a fresh `runtime.env`
|
|
225
251
|
- Lastly, executes the provided Dockerfile `CMD`
|
|
226
252
|
|
|
253
|
+
|
|
254
|
+
|
|
227
255
|
### `extract-env-vars.sh`
|
|
228
256
|
|
|
229
257
|
- Reads all container environment variables matching a prefix (default: `NG__`)
|
|
@@ -231,6 +259,8 @@ This package ships with two lightweight shell scripts used to generate a runtime
|
|
|
231
259
|
- Supports nested keys via ** (e.g., `NG**myFeature\_\_myThreshold`)
|
|
232
260
|
- Defaults output to `/usr/share/nginx/html/env/runtime.env`
|
|
233
261
|
|
|
262
|
+
|
|
263
|
+
|
|
234
264
|
### `nginx.conf`
|
|
235
265
|
|
|
236
266
|
A default Nginx configuration optimized for Angular applications. It provides:
|
|
@@ -240,6 +270,8 @@ A default Nginx configuration optimized for Angular applications. It provides:
|
|
|
240
270
|
- Gzip compression where supported
|
|
241
271
|
- Automatic fallback to `index.html` for client-side routing
|
|
242
272
|
|
|
273
|
+
|
|
274
|
+
|
|
243
275
|
### **Example Docker Commands**
|
|
244
276
|
|
|
245
277
|
```Dockerfile
|
|
@@ -255,21 +287,24 @@ CMD ["nginx", "-g", "daemon off;"]
|
|
|
255
287
|
|
|
256
288
|
For a complete Dockerfile example with the shipped `nginx.conf` config, refer to [Runtime Config Dockerfile Example](#runtime-config-dockerfile-example)
|
|
257
289
|
|
|
258
|
-
|
|
259
|
-
|
|
260
290
|
---
|
|
261
291
|
|
|
262
|
-
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# Toasts
|
|
263
295
|
|
|
264
296
|
A lightweight, standalone toast system that integrates seamlessly with Tegel Angular. Provides configurable, signal-driven notifications for success, error, warning, and information messages.
|
|
265
297
|
|
|
266
|
-
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
## Quick Start
|
|
267
301
|
|
|
268
302
|
### Add Providers
|
|
269
303
|
|
|
270
304
|
In your `app.config.ts`, specify the provider with `provideToast()`:
|
|
271
305
|
|
|
272
306
|
```ts
|
|
307
|
+
// app.config.ts
|
|
273
308
|
import { provideToast } from '@scania-nl/tegel-angular-extensions';
|
|
274
309
|
|
|
275
310
|
export const appConfig: ApplicationConfig = {
|
|
@@ -288,6 +323,8 @@ export const appConfig: ApplicationConfig = {
|
|
|
288
323
|
|
|
289
324
|
> Note: The configuration is optional, all values shown above are the default settings.
|
|
290
325
|
|
|
326
|
+
|
|
327
|
+
|
|
291
328
|
### Use in components
|
|
292
329
|
|
|
293
330
|
In any standalone component:
|
|
@@ -315,7 +352,7 @@ export class MyToastDemoComponent {
|
|
|
315
352
|
|
|
316
353
|
|
|
317
354
|
|
|
318
|
-
##
|
|
355
|
+
## Toast Configuration Options
|
|
319
356
|
|
|
320
357
|
You can configure the default appearance and behavior of toasts by passing a `ToastConfig` object to `provideToast()` in your `app.config.ts`.
|
|
321
358
|
|
|
@@ -336,22 +373,22 @@ All options are optional. Defaults will be applied if values are not provided.
|
|
|
336
373
|
|
|
337
374
|
|
|
338
375
|
|
|
339
|
-
##
|
|
376
|
+
## ToastService API
|
|
340
377
|
|
|
341
378
|
The `ToastService` provides a signal-based API to create, manage, and dismiss toast notifications in Angular standalone apps. It is automatically available after registering `provideToast()` in your `app.config.ts`.
|
|
342
379
|
|
|
343
|
-
|
|
380
|
+
|
|
344
381
|
|
|
345
|
-
###
|
|
382
|
+
### ToastService Properties
|
|
346
383
|
|
|
347
384
|
| Property | Type | Description |
|
|
348
385
|
| -------------- | ----------------- | ----------------------------------------------------- |
|
|
349
386
|
| `toasts` | `Signal<Toast[]>` | Read-only list of all toasts (including closed) |
|
|
350
387
|
| `activeToasts` | `Signal<Toast[]>` | List of currently active toasts (`Open` or `Closing`) |
|
|
351
388
|
|
|
352
|
-
|
|
389
|
+
|
|
353
390
|
|
|
354
|
-
###
|
|
391
|
+
### ToastService Methods
|
|
355
392
|
|
|
356
393
|
#### `create(toastOptions: Partial<ToastOptions>): number`
|
|
357
394
|
|
|
@@ -425,7 +462,9 @@ Force-removes all toasts instantly (no animations).
|
|
|
425
462
|
|
|
426
463
|
---
|
|
427
464
|
|
|
428
|
-
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
### Toast Lifecycle Hooks
|
|
429
468
|
|
|
430
469
|
Each toast supports optional lifecycle callbacks:
|
|
431
470
|
|
|
@@ -449,12 +488,425 @@ toastService.success({
|
|
|
449
488
|
|
|
450
489
|
|
|
451
490
|
|
|
452
|
-
#
|
|
491
|
+
# Modals
|
|
492
|
+
|
|
493
|
+
Standalone modal service + host for Tegel's `tds-modal`, with strongly‑typed options and dynamic body support.
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
## Quick Start
|
|
498
|
+
|
|
499
|
+
### Add Providers
|
|
500
|
+
|
|
501
|
+
In your `app.config.ts`, specify the provider with `provideModal()`:
|
|
502
|
+
|
|
503
|
+
```ts
|
|
504
|
+
// app.config.ts
|
|
505
|
+
import { provideModal } from '@scania-nl/tegel-angular-extensions';
|
|
506
|
+
|
|
507
|
+
export const appConfig: ApplicationConfig = {
|
|
508
|
+
providers: [
|
|
509
|
+
provideModal({
|
|
510
|
+
size: 'md', // Modal size
|
|
511
|
+
actionsPosition: 'static', // Actions slot behavior
|
|
512
|
+
prevent: false, // Prevent overlay click from closing the modal
|
|
513
|
+
closable: true, // Show or hide the close [X] button
|
|
514
|
+
alertDialog: 'dialog', // ARIA role of the modal component
|
|
515
|
+
lazy: false, // Render body only while open
|
|
516
|
+
startOpen: true, // Open modal on creation
|
|
517
|
+
removeOnClose: true, // Remove modal from DOM when closed
|
|
518
|
+
}),
|
|
519
|
+
],
|
|
520
|
+
};
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Most of these options are inherited from `tds-modal`.
|
|
524
|
+
|
|
525
|
+
> Note: The configuration is optional, all values shown above are the default settings.
|
|
526
|
+
|
|
527
|
+
### Use in components
|
|
528
|
+
|
|
529
|
+
`create()` returns a `ModalRef` that can control the modal instance.
|
|
530
|
+
|
|
531
|
+
```ts
|
|
532
|
+
import { inject } from '@angular/core';
|
|
533
|
+
import { ModalService } from '@scania-nl/tegel-angular-extensions';
|
|
534
|
+
|
|
535
|
+
export class MyComponent {
|
|
536
|
+
private readonly modalService = inject(ModalService);
|
|
537
|
+
|
|
538
|
+
openModal() {
|
|
539
|
+
const ref = this.modalService.create({
|
|
540
|
+
header: 'Demo Modal',
|
|
541
|
+
body: 'Hello from modal',
|
|
542
|
+
startOpen: false,
|
|
543
|
+
removeOnClose: false,
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
ref.open(); // Opens the modal
|
|
547
|
+
ref.close(); // Closes (hides) the modal
|
|
548
|
+
ref.remove(); // Removes the modal from the DOM
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
You get a `ModalRef` back from `create()`, which you can use to control that specific modal instance (`open()`, `close()`, `remove()`).
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
## Modal Configuration Options
|
|
560
|
+
|
|
561
|
+
| Option | Type | Default | Description |
|
|
562
|
+
| ----------------- | ------------------------------ | -------- | --------------------------- |
|
|
563
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | `md` | Modal size |
|
|
564
|
+
| `actionsPosition` | `'static' \| 'sticky'` | `static` | Actions slot behavior |
|
|
565
|
+
| `prevent` | `boolean` | `false` | Prevent overlay close |
|
|
566
|
+
| `closable` | `boolean` | `true` | Show/hide close button |
|
|
567
|
+
| `alertDialog` | `'dialog' \| 'alertdialog'` | `dialog` | ARIA role |
|
|
568
|
+
| `lazy` | `boolean` | `false` | Render body only while open |
|
|
569
|
+
| `startOpen` | `boolean` | `true` | Open immediately on create |
|
|
570
|
+
| `removeOnClose` | `boolean` | `true` | Remove modal after close |
|
|
571
|
+
|
|
572
|
+
> Be aware that when `removeOnClose` is set to `false`, the modal content is hidden but **not destroyed**. If your body uses a component with active subscriptions, timers, or sockets, they will continue to run while the modal is hidden. Consider `removeOnClose: true` for component bodies if you want their resources to be disposed on close.
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
### Per-modal options (create)
|
|
579
|
+
|
|
580
|
+
These options are passed to `modalService.create()` and override defaults from `provideModal()` on a per‑modal basis. For shared defaults like `size`, `actionsPosition`, `prevent`, `closable`, `alertDialog`, `lazy`, `startOpen`, and `removeOnClose`, see [Modal Configuration Options](#modal-configuration-options) above.
|
|
581
|
+
|
|
582
|
+
| Option | Type | Description |
|
|
583
|
+
| ------------- | ------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
584
|
+
| `header` | `string \| TemplateRef<unknown>` | Modal header text or template |
|
|
585
|
+
| `body` | `string \| { template, context } \| { component, inputs, outputs }` | Modal body content (string, template+context, or component) |
|
|
586
|
+
| `buttons` | `ModalButton[]` | Action buttons to render in the actions slot |
|
|
587
|
+
| `selector` | `string` | CSS selector for focus return element |
|
|
588
|
+
| `referenceEl` | `HTMLElement` | Element to return focus to (preferred over selector) |
|
|
589
|
+
| `onClosed` | `() => void \| Promise<void>` | Called when the modal is closed |
|
|
590
|
+
| `onRemoved` | `() => void \| Promise<void>` | Called after the modal is removed |
|
|
591
|
+
|
|
592
|
+
> Note: If you want focus to return to the element that opened the modal, pass either `selector` or `referenceEl` when creating the modal. This avoids Tegel's "Missing focus origin" warning.
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
### Body content options
|
|
599
|
+
|
|
600
|
+
The modal body can be provided as a simple string, a template body, or a component descriptor.
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
#### 1) String body
|
|
605
|
+
|
|
606
|
+
```ts
|
|
607
|
+
this.modalService.create({
|
|
608
|
+
header: 'Simple',
|
|
609
|
+
body: 'This is a simple modal body',
|
|
610
|
+
});
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
#### 2) Template body (template + optional context)
|
|
616
|
+
|
|
617
|
+
Signature:
|
|
618
|
+
|
|
619
|
+
```
|
|
620
|
+
body: {
|
|
621
|
+
template: TemplateRef<TContext>;
|
|
622
|
+
context?: TContext;
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
Example:
|
|
628
|
+
|
|
629
|
+
```html
|
|
630
|
+
<ng-template #bodyTpl let-context>
|
|
631
|
+
<p>
|
|
632
|
+
<b>{{ context.substance }}<b> boils at
|
|
633
|
+
<b>{{ context.value }}</b> degrees {{ context.units }}.
|
|
634
|
+
</p>
|
|
635
|
+
</ng-template>
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
```ts
|
|
639
|
+
interface SubstanceTemperature {
|
|
640
|
+
substance: string;
|
|
641
|
+
value: number;
|
|
642
|
+
units: string;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const bodyTpl =
|
|
646
|
+
viewChild.required<TemplateRef<SubstanceTemperature>>('bodyTpl');
|
|
647
|
+
this.modalService.create({
|
|
648
|
+
header: 'Template',
|
|
649
|
+
body: {
|
|
650
|
+
template: bodyTpl(),
|
|
651
|
+
context: {
|
|
652
|
+
substance: 'Water',
|
|
653
|
+
value: 100,
|
|
654
|
+
units: 'Celcius',
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
For typed templates, you can use `TypedTemplateDirective` to enforce context types in the template:
|
|
663
|
+
|
|
664
|
+
```html
|
|
665
|
+
<ng-template #bodyTpl let-context [typedContext]="this.bodyTpl()">
|
|
666
|
+
...
|
|
667
|
+
</ng-template>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
#### 3) Component body (with inputs/outputs)
|
|
673
|
+
|
|
674
|
+
Signature:
|
|
675
|
+
|
|
676
|
+
```ts
|
|
677
|
+
body: {
|
|
678
|
+
component: Type<TComponent>;
|
|
679
|
+
inputs: ComponentInputs<TComponent>;
|
|
680
|
+
outputs?: ComponentOutputs<TComponent>;
|
|
681
|
+
}
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
When you pass a component as the modal body, the `inputs` and `outputs` objects are fully typed. This means you get IntelliSense for signal inputs/outputs, and any `input.required(...)` fields are enforced at compile time (missing required inputs will fail the build).
|
|
687
|
+
|
|
688
|
+
```ts
|
|
689
|
+
export class ExampleComponent {
|
|
690
|
+
readonly requiredField = input.required<string>();
|
|
691
|
+
readonly optionalField = input<string>();
|
|
692
|
+
readonly outputField = output<string>();
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
```ts
|
|
697
|
+
const ref = this.modalService.create({
|
|
698
|
+
header: 'Example',
|
|
699
|
+
body: {
|
|
700
|
+
component: ExampleComponent,
|
|
701
|
+
inputs: {
|
|
702
|
+
requiredField: 'Required',
|
|
703
|
+
// optionalField: 'Optional'
|
|
704
|
+
},
|
|
705
|
+
outputs: {
|
|
706
|
+
outputField: (value: string) => {
|
|
707
|
+
console.log('Value:', value);
|
|
708
|
+
ref.close();
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
});
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
### Action buttons
|
|
718
|
+
|
|
719
|
+
```ts
|
|
720
|
+
this.modalService.create({
|
|
721
|
+
header: 'Confirm',
|
|
722
|
+
body: 'Are you sure?',
|
|
723
|
+
buttons: [
|
|
724
|
+
{ text: 'OK', variant: 'primary', onClick: async () => console.log('OK') },
|
|
725
|
+
{ text: 'Cancel', variant: 'secondary', dismiss: true },
|
|
726
|
+
],
|
|
727
|
+
startOpen: true,
|
|
728
|
+
});
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
- `dismiss`: true adds `data-dismiss-modal` for Tegel's built‑in close behavior.
|
|
732
|
+
- `onClick` supports sync or async handlers.
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
#### ModalButton options
|
|
737
|
+
|
|
738
|
+
Modal action buttons map directly to Tegel's `tds-button` configuration. The following options are supported:
|
|
739
|
+
|
|
740
|
+
| Option | Type | Description |
|
|
741
|
+
| ---------- | --------------------------------------------------- | ----------------------------------------------------------- |
|
|
742
|
+
| `text` | `string` | Button label text |
|
|
743
|
+
| `variant` | `'primary' \| 'secondary' \| 'success' \| 'danger'` | Visual variant |
|
|
744
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | Button size |
|
|
745
|
+
| `disabled` | `boolean` | Disable the button |
|
|
746
|
+
| `dismiss` | `boolean` | Adds `data-dismiss-modal` to trigger Tegel's close behavior |
|
|
747
|
+
| `onClick` | `() => void \| Promise<void>` | Optional click handler (sync or async) |
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
## ModalService API
|
|
754
|
+
|
|
755
|
+
The `ModalService` provides a signal-based API to create, manage, and dismiss modal instances. It is available after registering `provideModal()` in your `app.config.ts`.
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
### ModalService Properties
|
|
760
|
+
|
|
761
|
+
| Property | Type | Description |
|
|
762
|
+
| -------- | ---------------------------- | -------------------------------------------------- |
|
|
763
|
+
| `modals` | `Signal<Map<string, Modal>>` | Read-only map of all registered modals keyed by id |
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
### ModalService Methods
|
|
768
|
+
|
|
769
|
+
#### `create<T>(options?: ModalOptions<T>): ModalRef`
|
|
770
|
+
|
|
771
|
+
Creates and registers a new modal. Returns a `ModalRef` for controlling that instance.
|
|
772
|
+
|
|
773
|
+
```ts
|
|
774
|
+
const ref = modalService.create({
|
|
775
|
+
header: 'Hello',
|
|
776
|
+
body: 'Modal content',
|
|
777
|
+
startOpen: false,
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
ref.open();
|
|
781
|
+
ref.close();
|
|
782
|
+
ref.remove();
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
#### ModalRef
|
|
788
|
+
|
|
789
|
+
`create()` returns a `ModalRef` with `open()`, `close()`, and `remove()` methods to control that specific modal instance.
|
|
790
|
+
|
|
791
|
+
#### `open(id: string): void`
|
|
792
|
+
|
|
793
|
+
Opens an existing modal by id.
|
|
794
|
+
|
|
795
|
+
Example:
|
|
796
|
+
|
|
797
|
+
```ts
|
|
798
|
+
const ref = modalService.create({
|
|
799
|
+
header: 'Example',
|
|
800
|
+
body: 'Hello',
|
|
801
|
+
startOpen: false,
|
|
802
|
+
});
|
|
803
|
+
modalService.open(ref.id); // Equivalent to ref.open()
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
#### `close(id: string): void`
|
|
809
|
+
|
|
810
|
+
Closes (hides) a modal by id. If `removeOnClose` is `true`, it is removed from the DOM after closing.
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
#### `remove(id: string): void`
|
|
815
|
+
|
|
816
|
+
Removes a modal from the registry/DOM. If the modal is open, it is closed first.
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
#### `closeAll(): void`
|
|
821
|
+
|
|
822
|
+
Closes all registered modals.
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
#### `removeAll(): void`
|
|
827
|
+
|
|
828
|
+
Removes all registered modals.
|
|
829
|
+
|
|
830
|
+
---
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
### Modal Lifecycle Hooks
|
|
835
|
+
|
|
836
|
+
Each modal supports optional lifecycle callbacks:
|
|
837
|
+
|
|
838
|
+
| Callback | Description |
|
|
839
|
+
| ------------- | ------------------------------------------------------- |
|
|
840
|
+
| `onClosed()` | Called when the modal is closed |
|
|
841
|
+
| `onRemoved()` | Called after the modal is removed from the registry/DOM |
|
|
842
|
+
|
|
843
|
+
Example:
|
|
844
|
+
|
|
845
|
+
```ts
|
|
846
|
+
modalService.create({
|
|
847
|
+
header: 'Example',
|
|
848
|
+
body: 'Hello',
|
|
849
|
+
onClosed: () => console.log('Modal closed'),
|
|
850
|
+
onRemoved: () => console.log('Modal removed'),
|
|
851
|
+
});
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
---
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
# Components & Directives
|
|
453
859
|
|
|
454
860
|
This library includes a set of standalone UI components and utility directives, all prefixed with **`tae`**, designed to extend and complement the Tegel Angular ecosystem. Each piece is lightweight, fully typed, and easy to import into any Angular 19+ application.
|
|
455
861
|
|
|
456
862
|
|
|
457
|
-
##
|
|
863
|
+
## Components
|
|
864
|
+
|
|
865
|
+
### DateTime Picker Component (`tae-date-time-picker`) [BETA]
|
|
866
|
+
|
|
867
|
+
`TaeDateTimePickerComponent` is a standalone, form‑compatible picker that supports `date`, `datetime`, and `time` modes. It implements Angular's `ControlValueAccessor`, so it works with both reactive and template‑driven forms.
|
|
868
|
+
|
|
869
|
+
> Beta: This component is still evolving. Improvements are planned and minor bugs may occur.
|
|
870
|
+
|
|
871
|
+
**Inputs:**
|
|
872
|
+
|
|
873
|
+
| Input | Type | Default | Description |
|
|
874
|
+
| --------------- | ------------------------------------- | --------- | ------------------- |
|
|
875
|
+
| `label` | `string` | `''` | Label text |
|
|
876
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `lg` | Control size |
|
|
877
|
+
| `labelPosition` | `'inside' \| 'outside' \| 'no-label'` | `outside` | Label placement |
|
|
878
|
+
| `state` | `'error' \| undefined` | — | Error state styling |
|
|
879
|
+
| `helper` | `string` | `''` | Helper text |
|
|
880
|
+
| `mode` | `'date' \| 'datetime' \| 'time'` | `date` | Picker mode |
|
|
881
|
+
|
|
882
|
+
> Note: `labelPosition` is currently not implemented; it will be supported in a future update.
|
|
883
|
+
> Note: `state` is currently only used for styling in the template and does not affect behavior.
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
**Example (reactive forms):**
|
|
888
|
+
|
|
889
|
+
```ts
|
|
890
|
+
readonly form = this.fb.group({
|
|
891
|
+
date: this.fb.control<string | null>(null),
|
|
892
|
+
time: this.fb.control<string | null>(null),
|
|
893
|
+
dateTime: this.fb.control<string | null>(null),
|
|
894
|
+
});
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
```html
|
|
898
|
+
<form [formGroup]="form">
|
|
899
|
+
<tae-date-time-picker label="Date" formControlName="date" mode="date" />
|
|
900
|
+
<tae-date-time-picker label="Time" formControlName="time" mode="time" />
|
|
901
|
+
<tae-date-time-picker
|
|
902
|
+
label="DateTime"
|
|
903
|
+
formControlName="dateTime"
|
|
904
|
+
mode="datetime"
|
|
905
|
+
/>
|
|
906
|
+
</form>
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
|
|
458
910
|
|
|
459
911
|
### Footer Component (`tae-footer`)
|
|
460
912
|
|
|
@@ -480,7 +932,7 @@ This makes it ideal for full-viewport layouts that benefit from space efficiency
|
|
|
480
932
|
|
|
481
933
|
|
|
482
934
|
|
|
483
|
-
##
|
|
935
|
+
## Directives
|
|
484
936
|
|
|
485
937
|
### Hard Refresh Directive (`taeHardRefresh`)
|
|
486
938
|
|
|
@@ -490,10 +942,10 @@ This is especially useful for hard-reloading tablet or mobile applications which
|
|
|
490
942
|
|
|
491
943
|
**Inputs:**
|
|
492
944
|
|
|
493
|
-
| Property | Type | Default
|
|
494
|
-
| ---------------- | -------- |
|
|
495
|
-
| `clicksRequired` | `number` | `3`
|
|
496
|
-
| `clickWindowMs` | `number` | `500`
|
|
945
|
+
| Property | Type | Default | Description |
|
|
946
|
+
| ---------------- | -------- | ------- | ---------------------------------------------------------------------- |
|
|
947
|
+
| `clicksRequired` | `number` | `3` | Number of clicks required within the window to trigger a hard refresh. |
|
|
948
|
+
| `clickWindowMs` | `number` | `500` | Time window in milliseconds between two subsequent clicks. |
|
|
497
949
|
|
|
498
950
|
**Example:**
|
|
499
951
|
|
|
@@ -517,16 +969,16 @@ It operates outside of Angular's zone to prevent unnecessary change detection cy
|
|
|
517
969
|
|
|
518
970
|
**Inputs:**
|
|
519
971
|
|
|
520
|
-
| Input
|
|
521
|
-
|
|
|
522
|
-
| `inputWindowMs`
|
|
523
|
-
| `terminatorKey`
|
|
972
|
+
| Input | Type | Default | Description |
|
|
973
|
+
| --------------- | -------- | --------- | ------------------------------------------------------------------ |
|
|
974
|
+
| `inputWindowMs` | `number` | `100` | Max time allowed between consecutive keypresses before discarding. |
|
|
975
|
+
| `terminatorKey` | `string` | `'Enter'` | The key that signals the end of a barcode sequence. |
|
|
524
976
|
|
|
525
977
|
**Outputs:**
|
|
526
978
|
|
|
527
|
-
| Output | Type
|
|
528
|
-
| ---------------- |
|
|
529
|
-
| `barcodeScanned` | `string`
|
|
979
|
+
| Output | Type | Description |
|
|
980
|
+
| ---------------- | -------- | ----------------------------------------------------------- |
|
|
981
|
+
| `barcodeScanned` | `string` | **Required**. Emits the full barcode string once completed. |
|
|
530
982
|
|
|
531
983
|
**Example:**
|
|
532
984
|
|
|
@@ -597,7 +1049,9 @@ CMD ["nginx", "-c", "/etc/nginx/nginx.conf", "-g", "daemon off;"]
|
|
|
597
1049
|
|
|
598
1050
|
---
|
|
599
1051
|
|
|
600
|
-
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
# License
|
|
601
1055
|
|
|
602
1056
|
Copyright 2025 Scania CV AB.
|
|
603
1057
|
|