@dnd-mapp/shared-ui 1.1.0 → 2.0.1
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 +57 -15
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkAnkaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkBXkaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkBnka.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkC3kaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCHkaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCXkaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCnkaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkaHkaWzU.woff2 +0 -0
- package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkenkaWzU.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3-UBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3CUBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3GUBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3OUBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3iUBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3yUBA.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMawCUBGEe.woff2 +0 -0
- package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMaxKUBGEe.woff2 +0 -0
- package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2 +0 -0
- package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2 +0 -0
- package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2 +0 -0
- package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2 +0 -0
- package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2 +0 -0
- package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2 +0 -0
- package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2 +0 -0
- package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2 +0 -0
- package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2 +0 -0
- package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2 +0 -0
- package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2 +0 -0
- package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2 +0 -0
- package/assets/styles/_normalize.scss +380 -0
- package/assets/styles/colors/_amber.scss +11 -0
- package/assets/styles/colors/_blue.scss +11 -0
- package/assets/styles/colors/_common.scss +2 -0
- package/assets/styles/colors/_cyan.scss +11 -0
- package/assets/styles/colors/_emerald.scss +11 -0
- package/assets/styles/colors/_fuchsia.scss +11 -0
- package/assets/styles/colors/_gray.scss +11 -0
- package/assets/styles/colors/_green.scss +11 -0
- package/assets/styles/colors/_indigo.scss +11 -0
- package/assets/styles/colors/_lime.scss +11 -0
- package/assets/styles/colors/_mauve.scss +11 -0
- package/assets/styles/colors/_mist.scss +11 -0
- package/assets/styles/colors/_neutral.scss +11 -0
- package/assets/styles/colors/_olive.scss +11 -0
- package/assets/styles/colors/_orange.scss +11 -0
- package/assets/styles/colors/_pink.scss +11 -0
- package/assets/styles/colors/_purple.scss +11 -0
- package/assets/styles/colors/_red.scss +11 -0
- package/assets/styles/colors/_rose.scss +11 -0
- package/assets/styles/colors/_sky.scss +11 -0
- package/assets/styles/colors/_slate.scss +11 -0
- package/assets/styles/colors/_stone.scss +11 -0
- package/assets/styles/colors/_taupe.scss +11 -0
- package/assets/styles/colors/_teal.scss +11 -0
- package/assets/styles/colors/_violet.scss +11 -0
- package/assets/styles/colors/_yellow.scss +11 -0
- package/assets/styles/colors/_zinc.scss +11 -0
- package/assets/styles/colors/index.scss +27 -0
- package/assets/styles/fonts.scss +387 -0
- package/assets/styles/main.scss +17 -0
- package/assets/styles/theme-variables/_layout.scss +8 -0
- package/assets/styles/theme-variables/_shadows.scss +37 -0
- package/assets/styles/theme-variables/_spacing.scss +23 -0
- package/assets/styles/theme-variables/_text.scss +81 -0
- package/assets/styles/theme-variables/index.scss +4 -0
- package/fesm2022/dnd-mapp-shared-ui.mjs +329 -112
- package/fesm2022/dnd-mapp-shared-ui.mjs.map +1 -1
- package/package.json +19 -9
- package/src/lib/button/README.md +32 -34
- package/src/lib/dropdown/README.md +20 -16
- package/src/lib/forms/input/README.md +60 -36
- package/src/lib/nav/active-marker/README.md +35 -22
- package/src/lib/nav/app-top-bar/README.md +18 -35
- package/src/lib/nav/navbar/README.md +13 -18
- package/src/lib/nav/navbar-brand/README.md +32 -13
- package/src/lib/nav/navbar-link/README.md +22 -11
- package/src/lib/nav/navbar-menu/README.md +42 -68
- package/src/lib/vertical-rule/README.md +7 -5
- package/types/dnd-mapp-shared-ui.d.ts +157 -15
- package/assets/styles/main.css +0 -6
|
@@ -4,38 +4,38 @@
|
|
|
4
4
|
|
|
5
5
|
# Input Component `dma-input`
|
|
6
6
|
|
|
7
|
-
A versatile, accessible text input component designed for the `@dnd-mapp` ecosystem. It features built-in support for Angular Forms (ControlValueAccessor),
|
|
7
|
+
A versatile, accessible text input component designed for the `@dnd-mapp` ecosystem. It features built-in support for Angular Forms (`ControlValueAccessor`), reactive validation styling, and an internal debounce mechanism to optimize performance.
|
|
8
8
|
|
|
9
9
|
## 🏰 Overview
|
|
10
10
|
|
|
11
|
-
The `InputComponent` provides a styled wrapper around the native HTML input element. It includes integrated label handling, status-based border coloring (valid/invalid/touched), and a
|
|
11
|
+
The `InputComponent` provides a styled wrapper around the native HTML input element. It includes integrated label handling, status-based border coloring (valid/invalid/touched), and a **500ms debounce** on value changes to prevent excessive form updates during rapid typing.
|
|
12
12
|
|
|
13
13
|
- **Selector**: `dma-input`
|
|
14
14
|
- **Format**: Standalone Component
|
|
15
|
-
- **Change Detection**: OnPush
|
|
15
|
+
- **Change Detection**: `OnPush`
|
|
16
|
+
- **Form Support**: Full `ControlValueAccessor` integration
|
|
16
17
|
|
|
17
18
|
---
|
|
18
19
|
|
|
19
20
|
## 🚀 Usage
|
|
20
21
|
|
|
22
|
+
### Basic Usage with Signals
|
|
23
|
+
|
|
24
|
+
The component uses Angular's `model()` for the value, allowing for easy two-way binding.
|
|
25
|
+
|
|
21
26
|
```ts
|
|
22
27
|
import { InputComponent } from '@dnd-mapp/shared-ui';
|
|
23
|
-
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
28
|
+
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
|
|
24
29
|
|
|
25
30
|
@Component({
|
|
26
31
|
selector: 'app-root',
|
|
27
|
-
template:
|
|
28
|
-
<dma-input
|
|
29
|
-
inputId="username"
|
|
30
|
-
label="Username"
|
|
31
|
-
placeholder="Enter your character name"
|
|
32
|
-
[(value)]="userName"
|
|
33
|
-
/>
|
|
34
|
-
`,
|
|
32
|
+
template: `<dma-input inputId="username-field" label="Username" placeholder="TheLegend27" [(value)]="username" />`,
|
|
35
33
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
36
34
|
imports: [InputComponent],
|
|
37
35
|
})
|
|
38
|
-
export class
|
|
36
|
+
export class RootComponent {
|
|
37
|
+
protected readonly username = signal('');
|
|
38
|
+
}
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
---
|
|
@@ -44,58 +44,82 @@ export class MyComponent {}
|
|
|
44
44
|
|
|
45
45
|
### Inputs
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
47
|
+
Controlled via Angular Signal inputs.
|
|
48
|
+
|
|
49
|
+
| Name | Type | Required | Default | Description |
|
|
50
|
+
|---------------|-----------|----------|---------|-----------------------------------------------------------------------------|
|
|
51
|
+
| `inputId` | `string` | Yes | - | The unique ID used to associate the label with the input. |
|
|
52
|
+
| `label` | `string` | Yes | - | The text label displayed above the input field. |
|
|
53
|
+
| `placeholder` | `string` | No | `''` | The hint text displayed when the input is empty. |
|
|
54
|
+
| `readonly` | `boolean` | No | `false` | If true, the input is present but non-editable (uses `booleanAttribute`). |
|
|
53
55
|
|
|
54
56
|
### Models (Two-way Data Binding)
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
58
|
+
Controlled via Angular Signal models. These can be used with `[(value)]` or updated via Reactive Forms.
|
|
59
|
+
|
|
60
|
+
| Name | Type | Default | Description |
|
|
61
|
+
|------------|-----------|---------|-----------------------------------------------------------------------|
|
|
62
|
+
| `value` | `string` | `''` | The current text value. |
|
|
63
|
+
| `disabled` | `boolean` | `false` | Controls the disabled state. Automatically handled by Reactive Forms. |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## ⚙️ Technical Details
|
|
68
|
+
|
|
69
|
+
### Debounce Logic
|
|
70
|
+
|
|
71
|
+
To improve performance and reduce unnecessary change detection cycles, the component uses an internal `Subject` and `debounceTime(500)`. When a user types:
|
|
72
|
+
|
|
73
|
+
1. The internal `onInput` event triggers.
|
|
74
|
+
2. The value is held for 500ms.
|
|
75
|
+
3. After the timer clears, `onChange` is called, updating the model and notifying any parent Angular Form.
|
|
76
|
+
|
|
77
|
+
### Validation States
|
|
78
|
+
|
|
79
|
+
The component automatically styles itself based on Angular Form CSS classes:
|
|
80
|
+
|
|
81
|
+
- **Valid & Touched**: Displays a green border.
|
|
82
|
+
- **Invalid & Touched**: Displays a red border and red text.
|
|
83
|
+
- **Disabled**: Applies a background tint, reduces opacity, and changes the cursor to `not-allowed`.
|
|
60
84
|
|
|
61
85
|
---
|
|
62
86
|
|
|
63
87
|
## 🧪 Examples
|
|
64
88
|
|
|
65
|
-
###
|
|
89
|
+
### Reactive Forms Integration
|
|
66
90
|
|
|
67
|
-
Since the component implements `ControlValueAccessor`, it integrates seamlessly with `FormControl`.
|
|
91
|
+
Since the component implements `ControlValueAccessor`, it integrates seamlessly with `FormControl`. The `onTouched` event is triggered when the input receives focus.
|
|
68
92
|
|
|
69
93
|
```ts
|
|
70
|
-
import { Component,
|
|
71
|
-
import {
|
|
94
|
+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
95
|
+
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
72
96
|
import { InputComponent } from '@dnd-mapp/shared-ui';
|
|
73
97
|
|
|
74
98
|
@Component({
|
|
75
99
|
selector: 'app-profile-form',
|
|
76
100
|
template: `
|
|
77
101
|
<form [formGroup]="form">
|
|
78
|
-
<dma-input
|
|
79
|
-
label="Username"
|
|
80
|
-
inputId="username-field"
|
|
81
|
-
formControlName="username"
|
|
82
|
-
/>
|
|
102
|
+
<dma-input label="Username" inputId="username-field" formControlName="username" />
|
|
83
103
|
</form>
|
|
84
104
|
`,
|
|
85
105
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
86
106
|
imports: [ReactiveFormsModule, InputComponent],
|
|
87
107
|
})
|
|
88
108
|
export class ProfileFormComponent {
|
|
89
|
-
|
|
109
|
+
private readonly formBuilder = inject(FormBuilder).nonNullable;
|
|
110
|
+
|
|
111
|
+
protected readonly form = this.formBuilder.group({
|
|
112
|
+
username: this.formBuilder.control('', [Validators.required, Validators.minLength(3)])
|
|
113
|
+
});
|
|
90
114
|
}
|
|
91
115
|
```
|
|
92
116
|
|
|
93
|
-
###
|
|
117
|
+
### Read-only State
|
|
94
118
|
|
|
95
|
-
|
|
119
|
+
The `readonly` attribute is transformed using `booleanAttribute`, allowing for easy usage in templates.
|
|
96
120
|
|
|
97
121
|
```html
|
|
98
|
-
<dma-input readonly inputId="
|
|
122
|
+
<dma-input readonly inputId="version-id" label="System Version" value="v1.0.4" />
|
|
99
123
|
```
|
|
100
124
|
|
|
101
125
|
---
|
|
@@ -4,15 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
# Active Marker
|
|
6
6
|
|
|
7
|
-
A specialized text component designed to prevent layout shifts (CLS) when toggling between normal and bold font weights. It achieves this by rendering an invisible, bold version of the label to reserve the maximum required space
|
|
7
|
+
A specialized text component designed to prevent layout shifts (CLS) when toggling between normal and bold font weights. It achieves this by using a CSS Grid-based "ghosting" technique: rendering an invisible, bold version of the label to reserve the maximum required space, ensuring the container dimensions remain constant regardless of the active state.
|
|
8
8
|
|
|
9
9
|
## 🏰 Overview
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
| **Change Detection** | `OnPush` |
|
|
11
|
+
- **Selector**: `dma-active-marker`
|
|
12
|
+
- **Format**: Standalone Component
|
|
13
|
+
- **Change Detection**: `ChangeDetectionStrategy.OnPush`
|
|
14
|
+
- **Styling**: Scoped SCSS (BEM-less)
|
|
16
15
|
|
|
17
16
|
---
|
|
18
17
|
|
|
@@ -37,10 +36,27 @@ export class RootComponent {}
|
|
|
37
36
|
|
|
38
37
|
### Inputs
|
|
39
38
|
|
|
40
|
-
| Name | Type | Default
|
|
41
|
-
|
|
42
|
-
| `label` | `string` |
|
|
43
|
-
| `active` | `boolean` | `false`
|
|
39
|
+
| Name | Type | Required | Default | Description |
|
|
40
|
+
|----------|-----------|----------|---------|------------------------------------------------------------------------------------------------------------------------|
|
|
41
|
+
| `label` | `string` | Yes | - | The text content to be displayed. |
|
|
42
|
+
| `active` | `boolean` | No | `false` | Controls the active state. Uses `booleanAttribute` for flexible template usage (e.g., `<dma-active-marker active />`). |
|
|
43
|
+
|
|
44
|
+
### Host Classes
|
|
45
|
+
|
|
46
|
+
| Class | Condition | Result |
|
|
47
|
+
|-----------|--------------------|-----------------------------------------------------------------------------|
|
|
48
|
+
| `.active` | `active()` is true | Changes color to `$neutral-900` and font-weight to `$font-weight-semibold`. |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 🛠️ Implementation Details
|
|
53
|
+
|
|
54
|
+
### Layout Shift Prevention
|
|
55
|
+
|
|
56
|
+
The component uses `display: grid` on the host. Both the visible label and the "spacer" label are assigned to `grid-column: 1` and `grid-row: 1`.
|
|
57
|
+
|
|
58
|
+
1. **`.label-spacer`**: Always rendered with `visibility: hidden` and `font-weight: $font-weight-semibold`. This forces the grid cell to always be wide enough for the boldest version of the text.
|
|
59
|
+
2. **Visible Span**: Layers directly on top of the spacer. Its weight and color toggle based on the `.active` host class.
|
|
44
60
|
|
|
45
61
|
---
|
|
46
62
|
|
|
@@ -51,7 +67,7 @@ export class RootComponent {}
|
|
|
51
67
|
Use the component in a sidebar or menu to highlight the current route without causing the menu width to "jitter" when the font weight increases.
|
|
52
68
|
|
|
53
69
|
```ts
|
|
54
|
-
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
70
|
+
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
|
|
55
71
|
import { ActiveMarkerComponent } from '@dnd-mapp/shared-ui';
|
|
56
72
|
|
|
57
73
|
@Component({
|
|
@@ -59,9 +75,9 @@ import { ActiveMarkerComponent } from '@dnd-mapp/shared-ui';
|
|
|
59
75
|
template: `
|
|
60
76
|
<nav>
|
|
61
77
|
@for (item of menuItems; track item.id) {
|
|
62
|
-
<
|
|
63
|
-
<dma-active-marker [label]="item.name" [active]="selectedId === item.id" />
|
|
64
|
-
</
|
|
78
|
+
<button (click)="selectedId.set(item.id)">
|
|
79
|
+
<dma-active-marker [label]="item.name" [active]="selectedId() === item.id" />
|
|
80
|
+
</button>
|
|
65
81
|
}
|
|
66
82
|
</nav>
|
|
67
83
|
`,
|
|
@@ -69,16 +85,13 @@ import { ActiveMarkerComponent } from '@dnd-mapp/shared-ui';
|
|
|
69
85
|
imports: [ActiveMarkerComponent],
|
|
70
86
|
})
|
|
71
87
|
export class NavListComponent {
|
|
72
|
-
protected selectedId = 1;
|
|
73
|
-
|
|
88
|
+
protected readonly selectedId = signal(1);
|
|
89
|
+
|
|
90
|
+
protected readonly menuItems = [
|
|
74
91
|
{ id: 1, name: 'Overview' },
|
|
75
92
|
{ id: 2, name: 'Analytics' },
|
|
76
93
|
{ id: 3, name: 'Settings' }
|
|
77
94
|
];
|
|
78
|
-
|
|
79
|
-
protected select(id: number) {
|
|
80
|
-
this.selectedId = id;
|
|
81
|
-
}
|
|
82
95
|
}
|
|
83
96
|
```
|
|
84
97
|
|
|
@@ -88,8 +101,8 @@ Ideal for tab headers where centered text must remain perfectly centered regardl
|
|
|
88
101
|
|
|
89
102
|
```html
|
|
90
103
|
<div class="flex gap-4">
|
|
91
|
-
<dma-active-marker label="Profile" [active]="
|
|
92
|
-
<dma-active-marker label="Security" [active]="
|
|
104
|
+
<dma-active-marker label="Profile" [active]="currentTab === 'profile'" />
|
|
105
|
+
<dma-active-marker label="Security" [active]="currentTab === 'security'" />
|
|
93
106
|
</div>
|
|
94
107
|
```
|
|
95
108
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# App Top Bar
|
|
5
|
+
# App Top Bar
|
|
6
6
|
|
|
7
7
|
A flexible and layout-oriented header component designed to host navigation, branding, and action elements. It uses a composition-based approach with dedicated sections to ensure consistent spacing and alignment across the application.
|
|
8
8
|
|
|
9
9
|
## 🏰 Overview
|
|
10
10
|
|
|
11
|
-
The `AppTopBarComponent` acts as a container that
|
|
11
|
+
The `AppTopBarComponent` acts as a flexbox container that provides a specific slot for `AppTopBarSectionComponent` instances. It handles the top-level layout, background colors, and borders, while the sections handle internal alignment and spacing.
|
|
12
12
|
|
|
13
13
|
- **Selector**: `dma-app-top-bar`
|
|
14
14
|
- **Format**: Standalone Component
|
|
@@ -26,8 +26,13 @@ import { AppTopBarComponent, AppTopBarSectionComponent } from '@dnd-mapp/shared-
|
|
|
26
26
|
selector: 'app-root',
|
|
27
27
|
template: `
|
|
28
28
|
<dma-app-top-bar>
|
|
29
|
-
<dma-app-top-bar-section
|
|
30
|
-
|
|
29
|
+
<dma-app-top-bar-section>
|
|
30
|
+
<span>Logo</span>
|
|
31
|
+
</dma-app-top-bar-section>
|
|
32
|
+
|
|
33
|
+
<dma-app-top-bar-section position="end">
|
|
34
|
+
<button>Profile</button>
|
|
35
|
+
</dma-app-top-bar-section>
|
|
31
36
|
</dma-app-top-bar>
|
|
32
37
|
`,
|
|
33
38
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -44,9 +49,9 @@ export class RootComponent {}
|
|
|
44
49
|
|
|
45
50
|
#### Content Projection
|
|
46
51
|
|
|
47
|
-
| Slot | Description
|
|
48
|
-
|
|
49
|
-
| `dma-app-top-bar-section` |
|
|
52
|
+
| Slot | Description |
|
|
53
|
+
|---------------------------|----------------------------------------------------------------------------------|
|
|
54
|
+
| `dma-app-top-bar-section` | Selects components of type `dma-app-top-bar-section` to define alignment groups. |
|
|
50
55
|
|
|
51
56
|
---
|
|
52
57
|
|
|
@@ -54,9 +59,9 @@ export class RootComponent {}
|
|
|
54
59
|
|
|
55
60
|
#### Inputs
|
|
56
61
|
|
|
57
|
-
| Name | Type | Default | Description
|
|
58
|
-
|
|
59
|
-
| `[position]` | `'start' \| 'end'` | `'start'` | Determines the alignment. `
|
|
62
|
+
| Name | Type | Default | Description |
|
|
63
|
+
|--------------|--------------------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------|
|
|
64
|
+
| `[position]` | `'start' \| 'end'` | `'start'` | Determines the alignment. Sections with `position="start"` will `flex-grow` to fill available space, pushing "end" sections to the right. |
|
|
60
65
|
|
|
61
66
|
#### Content Projection
|
|
62
67
|
|
|
@@ -74,34 +79,12 @@ A standard layout with a title on the left and a single action on the right.
|
|
|
74
79
|
|
|
75
80
|
```html
|
|
76
81
|
<dma-app-top-bar>
|
|
77
|
-
<dma-app-top-bar-section
|
|
78
|
-
|
|
79
|
-
<h1 class="text-lg font-bold">D&D Mapp</h1>
|
|
82
|
+
<dma-app-top-bar-section>
|
|
83
|
+
Start section
|
|
80
84
|
</dma-app-top-bar-section>
|
|
81
85
|
|
|
82
86
|
<dma-app-top-bar-section position="end">
|
|
83
|
-
|
|
84
|
-
</dma-app-top-bar-section>
|
|
85
|
-
</dma-app-top-bar>
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Complex Action Bar
|
|
89
|
-
|
|
90
|
-
Using multiple items within the sections to create a rich interface.
|
|
91
|
-
|
|
92
|
-
```html
|
|
93
|
-
<dma-app-top-bar>
|
|
94
|
-
<dma-app-top-bar-section position="start">
|
|
95
|
-
<dma-icon dma-bars-icon />
|
|
96
|
-
<nav>
|
|
97
|
-
<a href="#">Dashboard</a>
|
|
98
|
-
<a href="#">Campaigns</a>
|
|
99
|
-
</nav>
|
|
100
|
-
</dma-app-top-bar-section>
|
|
101
|
-
|
|
102
|
-
<dma-app-top-bar-section position="end">
|
|
103
|
-
<dma-search-input />
|
|
104
|
-
<dma-avatar user="Oscar" />
|
|
87
|
+
End Section
|
|
105
88
|
</dma-app-top-bar-section>
|
|
106
89
|
</dma-app-top-bar>
|
|
107
90
|
```
|
|
@@ -8,13 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
The `NavbarComponent` serves as a semantic navigation container for the `@dnd-mapp/shared-ui` library. It uses an attribute selector on the standard HTML `<nav>` element to provide consistent layout styling while maintaining accessibility and SEO standards.
|
|
10
10
|
|
|
11
|
-
Designed for high-performance applications, it utilizes `OnPush` change detection and leverages
|
|
11
|
+
Designed for high-performance applications, it utilizes `OnPush` change detection and leverages a Scss-based flexible, horizontal flexbox layout with standardized spacing derived from the library's theme variables.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| **Format** | Standalone Component (Attribute-based) |
|
|
17
|
-
| **Change Detection** | `ChangeDetectionStrategy.OnPush` |
|
|
13
|
+
- **Selector**: `nav[dma-navbar]`
|
|
14
|
+
- **Format**: Standalone Component (Attribute-based)
|
|
15
|
+
- **Change Detection**: `ChangeDetectionStrategy.OnPush`
|
|
18
16
|
|
|
19
17
|
---
|
|
20
18
|
|
|
@@ -28,12 +26,15 @@ import { NavbarComponent } from '@dnd-mapp/shared-ui';
|
|
|
28
26
|
|
|
29
27
|
@Component({
|
|
30
28
|
selector: 'app-root',
|
|
31
|
-
template:
|
|
29
|
+
template: `
|
|
30
|
+
<nav dma-navbar>
|
|
31
|
+
<!-- Content is projected here -->
|
|
32
|
+
</nav>
|
|
33
|
+
`,
|
|
32
34
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
33
35
|
imports: [NavbarComponent],
|
|
34
36
|
})
|
|
35
|
-
export class RootComponent {
|
|
36
|
-
}
|
|
37
|
+
export class RootComponent {}
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
---
|
|
@@ -46,12 +47,6 @@ export class RootComponent {
|
|
|
46
47
|
|----------------|--------------------------------------------------------------|
|
|
47
48
|
| `<ng-content>` | Default slot for navigation links, logos, or action buttons. |
|
|
48
49
|
|
|
49
|
-
### Host Bindings
|
|
50
|
-
|
|
51
|
-
| Property | Value | Description |
|
|
52
|
-
|----------|---------------------------|---------------------------------------------------|
|
|
53
|
-
| `class` | `flex items-center gap-4` | Applies horizontal alignment and default spacing. |
|
|
54
|
-
|
|
55
50
|
---
|
|
56
51
|
|
|
57
52
|
## 🧪 Examples
|
|
@@ -62,7 +57,7 @@ A simple implementation featuring a logo and primary navigation links.
|
|
|
62
57
|
|
|
63
58
|
```html
|
|
64
59
|
<nav dma-navbar>
|
|
65
|
-
<img src="logo.svg" alt="App Logo"
|
|
60
|
+
<img src="logo.svg" alt="App Logo" />
|
|
66
61
|
<a href="/dashboard">Dashboard</a>
|
|
67
62
|
<a href="/settings">Settings</a>
|
|
68
63
|
</nav>
|
|
@@ -81,8 +76,8 @@ import { NavbarComponent } from '@dnd-mapp/shared-ui';
|
|
|
81
76
|
template: `
|
|
82
77
|
<nav dma-navbar>
|
|
83
78
|
<span class="font-bold">D&D Mapp</span>
|
|
84
|
-
<div
|
|
85
|
-
<button
|
|
79
|
+
<div style="flex: 1"></div>
|
|
80
|
+
<button>Logout</button>
|
|
86
81
|
</nav>
|
|
87
82
|
`,
|
|
88
83
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# Navbar Brand
|
|
5
|
+
# Navbar Brand
|
|
6
6
|
|
|
7
7
|
The `NavbarBrandComponent` is a foundational UI element for application navigation bars. It provides a standardized way to display a brand logo alongside a brand name, automatically linking back to the application root.
|
|
8
8
|
|
|
@@ -21,11 +21,13 @@ The `NavbarBrandComponent` is a foundational UI element for application navigati
|
|
|
21
21
|
To use the `NavbarBrandComponent`, import it into your standalone component or Angular module, and then add it to your template.
|
|
22
22
|
|
|
23
23
|
```ts
|
|
24
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
24
25
|
import { NavbarBrandComponent } from '@dnd-mapp/shared-ui';
|
|
25
26
|
|
|
26
27
|
@Component({
|
|
27
28
|
selector: 'app-layout',
|
|
28
29
|
template: `<dma-navbar-brand imgSrc="assets/logo.svg" brandName="D&D Mapp" />`,
|
|
30
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
29
31
|
imports: [NavbarBrandComponent],
|
|
30
32
|
})
|
|
31
33
|
export class LayoutComponent {}
|
|
@@ -37,6 +39,8 @@ export class LayoutComponent {}
|
|
|
37
39
|
|
|
38
40
|
### Inputs
|
|
39
41
|
|
|
42
|
+
The component uses Angular Signals for its input properties.
|
|
43
|
+
|
|
40
44
|
| Name | Type | Required | Description |
|
|
41
45
|
|-------------|----------|----------|----------------------------------------------------|
|
|
42
46
|
| `imgSrc` | `string` | Yes | The source URL for the brand logo image. |
|
|
@@ -44,7 +48,7 @@ export class LayoutComponent {}
|
|
|
44
48
|
|
|
45
49
|
### Routing
|
|
46
50
|
|
|
47
|
-
The component internally uses `RouterLink` and is hardcoded to navigate to the root path (`/`). Ensure that
|
|
51
|
+
The component internally uses `RouterLink` and is hardcoded to navigate to the root path (`/`). Ensure that `provideRouter` is configured in your application bootstrap.
|
|
48
52
|
|
|
49
53
|
---
|
|
50
54
|
|
|
@@ -52,22 +56,37 @@ The component internally uses `RouterLink` and is hardcoded to navigate to the r
|
|
|
52
56
|
|
|
53
57
|
### Basic Branding
|
|
54
58
|
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
```ts
|
|
60
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
61
|
+
import { NavbarBrandComponent } from '@dnd-mapp/shared-ui';
|
|
62
|
+
|
|
63
|
+
@Component({
|
|
64
|
+
selector: 'app-root',
|
|
65
|
+
template: '<dma-navbar-brand imgSrc="/favicon.ico" brandName="My Application" />',
|
|
66
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
67
|
+
imports: [NavbarBrandComponent],
|
|
68
|
+
})
|
|
69
|
+
export class RootComponent {}
|
|
60
70
|
```
|
|
61
71
|
|
|
62
72
|
### Dynamic Branding
|
|
63
73
|
|
|
64
|
-
|
|
74
|
+
Since the component uses Signal inputs, you can pass values from other Signals or standard properties:
|
|
65
75
|
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
```ts
|
|
77
|
+
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
|
|
78
|
+
import { NavbarBrandComponent } from '@dnd-mapp/shared-ui';
|
|
79
|
+
|
|
80
|
+
@Component({
|
|
81
|
+
selector: 'app-root',
|
|
82
|
+
template: '<dma-navbar-brand [imgSrc]="logo()" [brandName]="name()" />',
|
|
83
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
84
|
+
imports: [NavbarBrandComponent],
|
|
85
|
+
})
|
|
86
|
+
export class RootComponent {
|
|
87
|
+
protected readonly logo = signal('assets/dynamic-logo.svg');
|
|
88
|
+
protected readonly name = signal('Prototyping App');
|
|
89
|
+
}
|
|
71
90
|
```
|
|
72
91
|
|
|
73
92
|
---
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# NavbarLink
|
|
5
|
+
# NavbarLink
|
|
6
6
|
|
|
7
|
-
A
|
|
7
|
+
A navigation-aware component designed for use within navigation bars. It handles active state detection using Angular's functional `isActive` utility and provides a consistent visual experience for routing.
|
|
8
8
|
|
|
9
|
-
The `NavbarLinkComponent`
|
|
9
|
+
The `NavbarLinkComponent` integrates with the Angular Router to automatically determine its active state. It manages navigation both through a standard `[routerLink]` directive for accessibility (allowing right-clicks/middle-clicks) and a programmatic `onClick` handler.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -14,25 +14,28 @@ The `NavbarLinkComponent` provides a wrapper around Angular's `RouterLink`. A ke
|
|
|
14
14
|
|
|
15
15
|
- **Selector:** `dma-navbar-link`
|
|
16
16
|
- **Format:** Angular Standalone Component
|
|
17
|
+
- **Change Detection:** `OnPush`
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
20
21
|
## 🚀 Usage
|
|
21
22
|
|
|
22
|
-
To use the `NavbarLinkComponent`, import it into your standalone component
|
|
23
|
+
To use the `NavbarLinkComponent`, import it into your standalone component and add it to your template.
|
|
23
24
|
|
|
24
25
|
```ts
|
|
26
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
25
27
|
import { NavbarLinkComponent } from '@dnd-mapp/shared-ui';
|
|
26
28
|
|
|
27
|
-
@Component({
|
|
28
|
-
selector: 'app-nav-container',
|
|
29
|
+
@Component({
|
|
30
|
+
selector: 'app-nav-container',
|
|
29
31
|
template: `
|
|
30
32
|
<nav>
|
|
31
33
|
<dma-navbar-link label="Dashboard" route="/dashboard" />
|
|
32
34
|
<dma-navbar-link label="Settings" route="/settings" />
|
|
33
35
|
</nav>
|
|
34
36
|
`,
|
|
35
|
-
|
|
37
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
38
|
+
imports: [NavbarLinkComponent],
|
|
36
39
|
})
|
|
37
40
|
export class NavContainerComponent {}
|
|
38
41
|
```
|
|
@@ -43,10 +46,18 @@ export class NavContainerComponent {}
|
|
|
43
46
|
|
|
44
47
|
### Inputs
|
|
45
48
|
|
|
46
|
-
| Name | Type | Required | Description
|
|
47
|
-
|
|
48
|
-
| `label` | `string` | Yes
|
|
49
|
-
| `route` | `string` | Yes
|
|
49
|
+
| Name | Type | Required | Description |
|
|
50
|
+
|---------|----------|----------|------------------------------------------------------------------------------|
|
|
51
|
+
| `label` | `string` | **Yes** | The text label passed to the internal active marker. |
|
|
52
|
+
| `route` | `string` | **Yes** | The destination URL path used for both navigation and active state matching. |
|
|
53
|
+
|
|
54
|
+
### Active State Logic
|
|
55
|
+
|
|
56
|
+
The component uses a `Signal<boolean>` to track the active state. It is considered active if the current URL matches the `route` input based on the following criteria:
|
|
57
|
+
|
|
58
|
+
- **Paths:** `subset` (Matches if the route is a prefix of the current URL).
|
|
59
|
+
- **Query Params:** `subset`.
|
|
60
|
+
- **Fragments/Matrix Params:** `ignored`.
|
|
50
61
|
|
|
51
62
|
---
|
|
52
63
|
|