@dnd-mapp/shared-ui 1.1.0 → 2.0.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.
Files changed (82) hide show
  1. package/README.md +52 -15
  2. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkAnkaWzU.woff2 +0 -0
  3. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkBXkaWzU.woff2 +0 -0
  4. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkBnka.woff2 +0 -0
  5. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkC3kaWzU.woff2 +0 -0
  6. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCHkaWzU.woff2 +0 -0
  7. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCXkaWzU.woff2 +0 -0
  8. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkCnkaWzU.woff2 +0 -0
  9. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkaHkaWzU.woff2 +0 -0
  10. package/assets/fonts/KFO5CnqEu92Fr1Mu53ZEC9_Vu3r1gIhOszmkenkaWzU.woff2 +0 -0
  11. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3-UBGEe.woff2 +0 -0
  12. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3CUBGEe.woff2 +0 -0
  13. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3GUBGEe.woff2 +0 -0
  14. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2 +0 -0
  15. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3OUBGEe.woff2 +0 -0
  16. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3iUBGEe.woff2 +0 -0
  17. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3yUBA.woff2 +0 -0
  18. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMawCUBGEe.woff2 +0 -0
  19. package/assets/fonts/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMaxKUBGEe.woff2 +0 -0
  20. package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhEq3-OXg.woff2 +0 -0
  21. package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhFq3-OXg.woff2 +0 -0
  22. package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhGq3-OXg.woff2 +0 -0
  23. package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhIq3-OXg.woff2 +0 -0
  24. package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhLq38.woff2 +0 -0
  25. package/assets/fonts/L0x5DF4xlVMF-BfR8bXMIjhPq3-OXg.woff2 +0 -0
  26. package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm32WWg.woff2 +0 -0
  27. package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm36WWoKC.woff2 +0 -0
  28. package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3CWWoKC.woff2 +0 -0
  29. package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3KWWoKC.woff2 +0 -0
  30. package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3OWWoKC.woff2 +0 -0
  31. package/assets/fonts/L0x7DF4xlVMF-BfR8bXMIjhOm3mWWoKC.woff2 +0 -0
  32. package/assets/styles/_normalize.scss +380 -0
  33. package/assets/styles/colors/_amber.scss +11 -0
  34. package/assets/styles/colors/_blue.scss +11 -0
  35. package/assets/styles/colors/_common.scss +2 -0
  36. package/assets/styles/colors/_cyan.scss +11 -0
  37. package/assets/styles/colors/_emerald.scss +11 -0
  38. package/assets/styles/colors/_fuchsia.scss +11 -0
  39. package/assets/styles/colors/_gray.scss +11 -0
  40. package/assets/styles/colors/_green.scss +11 -0
  41. package/assets/styles/colors/_indigo.scss +11 -0
  42. package/assets/styles/colors/_lime.scss +11 -0
  43. package/assets/styles/colors/_mauve.scss +11 -0
  44. package/assets/styles/colors/_mist.scss +11 -0
  45. package/assets/styles/colors/_neutral.scss +11 -0
  46. package/assets/styles/colors/_olive.scss +11 -0
  47. package/assets/styles/colors/_orange.scss +11 -0
  48. package/assets/styles/colors/_pink.scss +11 -0
  49. package/assets/styles/colors/_purple.scss +11 -0
  50. package/assets/styles/colors/_red.scss +11 -0
  51. package/assets/styles/colors/_rose.scss +11 -0
  52. package/assets/styles/colors/_sky.scss +11 -0
  53. package/assets/styles/colors/_slate.scss +11 -0
  54. package/assets/styles/colors/_stone.scss +11 -0
  55. package/assets/styles/colors/_taupe.scss +11 -0
  56. package/assets/styles/colors/_teal.scss +11 -0
  57. package/assets/styles/colors/_violet.scss +11 -0
  58. package/assets/styles/colors/_yellow.scss +11 -0
  59. package/assets/styles/colors/_zinc.scss +11 -0
  60. package/assets/styles/colors/index.scss +27 -0
  61. package/assets/styles/font.scss +387 -0
  62. package/assets/styles/main.scss +17 -0
  63. package/assets/styles/theme-variables/_layout.scss +8 -0
  64. package/assets/styles/theme-variables/_shadows.scss +37 -0
  65. package/assets/styles/theme-variables/_spacing.scss +23 -0
  66. package/assets/styles/theme-variables/_text.scss +81 -0
  67. package/assets/styles/theme-variables/index.scss +4 -0
  68. package/fesm2022/dnd-mapp-shared-ui.mjs +329 -112
  69. package/fesm2022/dnd-mapp-shared-ui.mjs.map +1 -1
  70. package/package.json +3 -5
  71. package/src/lib/button/README.md +32 -34
  72. package/src/lib/dropdown/README.md +20 -16
  73. package/src/lib/forms/input/README.md +60 -36
  74. package/src/lib/nav/active-marker/README.md +35 -22
  75. package/src/lib/nav/app-top-bar/README.md +18 -35
  76. package/src/lib/nav/navbar/README.md +13 -18
  77. package/src/lib/nav/navbar-brand/README.md +32 -13
  78. package/src/lib/nav/navbar-link/README.md +22 -11
  79. package/src/lib/nav/navbar-menu/README.md +42 -68
  80. package/src/lib/vertical-rule/README.md +7 -5
  81. package/types/dnd-mapp-shared-ui.d.ts +157 -15
  82. 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), custom validation styling, and debounced input handling to optimize performance.
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 500 ms debounce on value changes to prevent excessive form updates during rapid typing.
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 MyComponent {}
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
- | Name | Type | Default | Description |
48
- |---------------|-----------|------------|-------------------------------------------------------------|
49
- | `inputId` | `string` | `required` | The unique ID for the internal input and label association. |
50
- | `label` | `string` | `required` | The text label displayed above the input field. |
51
- | `placeholder` | `string` | `''` | The hint text displayed when the input is empty. |
52
- | `readonly` | `boolean` | `false` | If true, the input is present but non-editable. |
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
- | Name | Type | Default | Description |
57
- |------------|-----------|---------|------------------------------------------------------------|
58
- | `value` | `string` | `''` | The current text value of the input. Supports `[(value)]`. |
59
- | `disabled` | `boolean` | `false` | Controls the disabled state of the input. |
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
- ### 1. Reactive Forms Integration
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, ChangeDetectionStrategy } from '@angular/core';
71
- import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
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
- username = new FormControl('', [Validators.required, Validators.minLength(3)]);
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
- ### 2. Read-only State
117
+ ### Read-only State
94
118
 
95
- Useful for displaying data that was previously entered but cannot be changed in the current context.
119
+ The `readonly` attribute is transformed using `booleanAttribute`, allowing for easy usage in templates.
96
120
 
97
121
  ```html
98
- <dma-input readonly inputId="char-id-001" label="Character ID" value="#88219" />
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 in the DOM grid.
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
- | Feature | Details |
12
- |----------------------|----------------------|
13
- | **Selector** | `dma-active-marker` |
14
- | **Format** | Standalone Component |
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 | Description |
41
- |----------|-----------|------------|------------------------------------------------------------------------|
42
- | `label` | `string` | `required` | The text content to be displayed. |
43
- | `active` | `boolean` | `false` | Controls the active (bold) state. Uses `booleanAttribute` transformer. |
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
- <a (click)="select(item.id)">
63
- <dma-active-marker [label]="item.name" [active]="selectedId === item.id" />
64
- </a>
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
- protected menuItems = [
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]="tab === 'profile'" />
92
- <dma-active-marker label="Security" [active]="tab === 'security'" />
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 `dma-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 leverages Tailwind CSS for layout and provides a specific slot for `AppTopBarSectionComponent` instances. This allows developers to easily group elements at the start or end of the bar.
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 position="start"><span>Logo</span></dma-app-top-bar-section>
30
- <dma-app-top-bar-section position="end"><button>Profile</button></dma-app-top-bar-section>
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` | Used to define alignment groups within the top bar. |
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. `'start'` sections will grow to fill available space if applicable. |
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 position="start">
78
- <img src="logo.png" alt="Logo" class="h-6" />
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
- <button class="btn-primary">Logout</button>
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 Tailwind CSS for a flexible, horizontal flexbox layout with standardized spacing.
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
- | Feature | Details |
14
- |----------------------|----------------------------------------|
15
- | **Selector** | `nav[dma-navbar]` |
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: `<nav dma-navbar><!-- Content is projected here --></nav>`,
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" class="h-8" />
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 class="flex-1"></div>
85
- <button class="btn-primary">Logout</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 Component (`dma-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 the `provideRouter` or `RouterModule` is configured in your application.
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
- ```html
56
- <dma-navbar-brand
57
- imgSrc="/favicon.ico"
58
- brandName="My Application"
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
- If your brand information comes from a configuration object or a signal:
74
+ Since the component uses Signal inputs, you can pass values from other Signals or standard properties:
65
75
 
66
- ```html
67
- <dma-navbar-brand
68
- [imgSrc]="config.logoPath"
69
- [brandName]="config.appName"
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 Component (`dma-navbar-link`)
5
+ # NavbarLink
6
6
 
7
- A lightweight, navigation-aware component designed for use within navigation bars. It handles active state detection automatically, ensuring that the link is visually highlighted when the current route matches its destination.
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` provides a wrapper around Angular's `RouterLink`. A key feature of this component is its layout stability: it uses a hidden "bold" placeholder to pre-calculate the space required for its active state. This prevents the "shaking" or layout shifting effect that often occurs when a font weight changes from normal to bold upon selection.
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 or Angular module and add it to your template.
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
- imports: [NavbarLinkComponent],
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 | The text to be displayed inside the link. |
49
- | `route` | `string` | Yes | The destination URL path (passed to `routerLink`). |
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