@compsych-ui-components/angular 6.0.10 → 6.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/angular/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOzD,MAAM,OAAO,qBAAqB;wGAArB,qBAAqB;yGAArB,qBAAqB,YAHtB,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,aACzE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB;yGAExE,qBAAqB;;4FAArB,qBAAqB;kBAJjC,QAAQ;mBAAC;oBACR,OAAO,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC;oBACpF,OAAO,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC;iBACrF","sourcesContent":["import { NgModule } from '@angular/core';\nimport { ButtonComponent } from './lib/button/button';\nimport { AccordionComponent } from './lib/accordion/accordion';\nimport { HeaderNavComponent } from './lib/header-nav/header-nav';\nimport { SidebarComponent } from './lib/sidebar/sidebar';\n\nexport { ButtonComponent } from './lib/button/button';\nexport type { ButtonVariant } from './lib/button/button';\nexport { AccordionComponent } from './lib/accordion/accordion';\nexport type { AccordionItem, AccordionButton, AccordionVariant, NestedAccordionItem } from './lib/accordion/accordion-types';\nexport { HeaderNavComponent } from './lib/header-nav/header-nav';\nexport type { HeaderNavLevel, NavAction } from './lib/header-nav/header-nav';\nexport { SidebarComponent } from './lib/sidebar/sidebar';\nexport type { SidebarItem } from './lib/sidebar/sidebar';\n\n@NgModule({\n imports: [ButtonComponent, AccordionComponent, HeaderNavComponent, SidebarComponent],\n exports: [ButtonComponent, AccordionComponent, HeaderNavComponent, SidebarComponent],\n})\nexport class CompsychAngularModule {}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/angular/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOzD,MAAM,OAAO,qBAAqB;wGAArB,qBAAqB;yGAArB,qBAAqB,YAHtB,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,aACzE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB;yGAExE,qBAAqB;;4FAArB,qBAAqB;kBAJjC,QAAQ;mBAAC;oBACR,OAAO,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC;oBACpF,OAAO,EAAE,CAAC,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC;iBACrF","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { ButtonComponent } from './lib/button/button';\r\nimport { AccordionComponent } from './lib/accordion/accordion';\r\nimport { HeaderNavComponent } from './lib/header-nav/header-nav';\r\nimport { SidebarComponent } from './lib/sidebar/sidebar';\r\n\r\nexport { ButtonComponent } from './lib/button/button';\r\nexport type { ButtonVariant } from './lib/button/button';\r\nexport { AccordionComponent } from './lib/accordion/accordion';\r\nexport type { AccordionItem, AccordionButton, AccordionVariant, NestedAccordionItem } from './lib/accordion/accordion-types';\r\nexport { HeaderNavComponent } from './lib/header-nav/header-nav';\r\nexport type { HeaderNavLevel, NavAction } from './lib/header-nav/header-nav';\r\nexport { SidebarComponent } from './lib/sidebar/sidebar';\r\nexport type { SidebarItem } from './lib/sidebar/sidebar';\r\n\r\n@NgModule({\r\n imports: [ButtonComponent, AccordionComponent, HeaderNavComponent, SidebarComponent],\r\n exports: [ButtonComponent, AccordionComponent, HeaderNavComponent, SidebarComponent],\r\n})\r\nexport class CompsychAngularModule {}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"accordion-types.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/accordion/accordion-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Visual style variant applied to the accordion and all its items.\n * - `'default'` — standard card style with borders and a background surface.\n * - `'level-2'` — compact nested style used inside another accordion panel.\n * - `'text-only'` — no card chrome; plain text trigger rows.\n */\nexport type AccordionVariant = 'default' | 'level-2' | 'text-only';\n\n/** An action button rendered at the bottom of an accordion panel. */\nexport interface AccordionButton {\n /** Text displayed on the button. */\n label: string;\n /** Called when the button is clicked. */\n action: () => void;\n}\n\n/**\n * A simplified accordion item used inside `AccordionItem.nestedContent`.\n * Identical to `AccordionItem` but without `buttons` and `nestedContent` —\n * nesting beyond one level is not supported.\n */\nexport type NestedAccordionItem = Omit<AccordionItem, 'buttons' | 'nestedContent'>;\n\n/** Data model for a single expandable row in a `compsych-accordion`. */\nexport interface AccordionItem {\n /** Text shown in the trigger button header. */\n title: string;\n /** HTML string rendered in the panel body when expanded. Sanitized before display. Omit when using `nestedContent`. */\n content?: string;\n /** Lucide icon name (kebab-case) shown to the left of the title, e.g. `'globe'` or `'folder'`. */\n icon?: string;\n /** Whether this panel starts expanded on initial render. Defaults to false. */\n expanded?: boolean;\n /** Action buttons rendered at the bottom of the panel, below `content`. */\n buttons?: AccordionButton[];\n /** Items rendered as a nested level-2 accordion inside this panel. Cannot contain `buttons` or further nesting. */\n nestedContent?: NestedAccordionItem[];\n}\n"]}
1
+ {"version":3,"file":"accordion-types.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/accordion/accordion-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\r\n * Visual style variant applied to the accordion and all its items.\r\n * - `'default'` — standard card style with borders and a background surface.\r\n * - `'level-2'` — compact nested style used inside another accordion panel.\r\n * - `'text-only'` — no card chrome; plain text trigger rows.\r\n */\r\nexport type AccordionVariant = 'default' | 'level-2' | 'text-only';\r\n\r\n/** An action button rendered at the bottom of an accordion panel. */\r\nexport interface AccordionButton {\r\n /** Text displayed on the button. */\r\n label: string;\r\n /** Called when the button is clicked. */\r\n action: () => void;\r\n}\r\n\r\n/**\r\n * A simplified accordion item used inside `AccordionItem.nestedContent`.\r\n * Identical to `AccordionItem` but without `buttons` and `nestedContent` —\r\n * nesting beyond one level is not supported.\r\n */\r\nexport type NestedAccordionItem = Omit<AccordionItem, 'buttons' | 'nestedContent'>;\r\n\r\n/** Data model for a single expandable row in a `compsych-accordion`. */\r\nexport interface AccordionItem {\r\n /** Text shown in the trigger button header. */\r\n title: string;\r\n /** HTML string rendered in the panel body when expanded. Sanitized before display. Omit when using `nestedContent`. */\r\n content?: string;\r\n /** Lucide icon name (kebab-case) shown to the left of the title, e.g. `'globe'` or `'folder'`. */\r\n icon?: string;\r\n /** Whether this panel starts expanded on initial render. Defaults to false. */\r\n expanded?: boolean;\r\n /** Action buttons rendered at the bottom of the panel, below `content`. */\r\n buttons?: AccordionButton[];\r\n /** Items rendered as a nested level-2 accordion inside this panel. Cannot contain `buttons` or further nesting. */\r\n nestedContent?: NestedAccordionItem[];\r\n}\r\n"]}
@@ -84,80 +84,80 @@ export class AccordionItemComponent {
84
84
  }
85
85
  }
86
86
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AccordionItemComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
87
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: AccordionItemComponent, isStandalone: true, selector: "compsych-accordion-item", inputs: { title: "title", content: "content", buttons: "buttons", nestedContent: "nestedContent", variant: "variant", nested: "nested", icon: "icon", expanded: "expanded" }, outputs: { expandedChange: "expandedChange" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class.level-2": "variant === \"level-2\"", "class.text-only": "variant === \"text-only\"", "class.nested": "nested" }, classAttribute: "compsych-accordion-item" }, ngImport: i0, template: `
88
- <button
89
- class="trigger"
90
- type="button"
91
- [id]="triggerId"
92
- [attr.aria-expanded]="expanded"
93
- [attr.aria-controls]="panelId"
94
- (click)="toggle()"
95
- >
96
- @if (iconSvg) {
97
- <span class="trigger-leading-icon" [innerHTML]="iconSvg" aria-hidden="true"></span>
98
- }
99
- <span class="trigger-label">{{ title }}</span>
100
- <span class="trigger-toggle material-symbols-rounded" aria-hidden="true">{{ expanded ? 'remove' : 'add' }}</span>
101
- </button>
102
- <div
103
- [id]="panelId"
104
- role="region"
105
- [attr.aria-labelledby]="triggerId"
106
- [hidden]="!expanded"
107
- >
108
- @if (content) {
109
- <div class="content" [innerHTML]="sanitizedContent"></div>
110
- }
111
- @if (nestedContent.length) {
112
- <compsych-accordion [items]="nestedContent" variant="level-2" [nested]="true" />
113
- }
114
- @if (buttons.length) {
115
- <div class="actions">
116
- @for (btn of buttons; track btn.label) {
117
- <compsych-button [label]="btn.label" variant="filled" size="small" (click)="btn.action()" />
118
- }
119
- </div>
120
- }
121
- </div>
87
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: AccordionItemComponent, isStandalone: true, selector: "compsych-accordion-item", inputs: { title: "title", content: "content", buttons: "buttons", nestedContent: "nestedContent", variant: "variant", nested: "nested", icon: "icon", expanded: "expanded" }, outputs: { expandedChange: "expandedChange" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class.level-2": "variant === \"level-2\"", "class.text-only": "variant === \"text-only\"", "class.nested": "nested" }, classAttribute: "compsych-accordion-item" }, ngImport: i0, template: `
88
+ <button
89
+ class="trigger"
90
+ type="button"
91
+ [id]="triggerId"
92
+ [attr.aria-expanded]="expanded"
93
+ [attr.aria-controls]="panelId"
94
+ (click)="toggle()"
95
+ >
96
+ @if (iconSvg) {
97
+ <span class="trigger-leading-icon" [innerHTML]="iconSvg" aria-hidden="true"></span>
98
+ }
99
+ <span class="trigger-label">{{ title }}</span>
100
+ <span class="trigger-toggle material-symbols-rounded" aria-hidden="true">{{ expanded ? 'remove' : 'add' }}</span>
101
+ </button>
102
+ <div
103
+ [id]="panelId"
104
+ role="region"
105
+ [attr.aria-labelledby]="triggerId"
106
+ [hidden]="!expanded"
107
+ >
108
+ @if (content) {
109
+ <div class="content" [innerHTML]="sanitizedContent"></div>
110
+ }
111
+ @if (nestedContent.length) {
112
+ <compsych-accordion [items]="nestedContent" variant="level-2" [nested]="true" />
113
+ }
114
+ @if (buttons.length) {
115
+ <div class="actions">
116
+ @for (btn of buttons; track btn.label) {
117
+ <compsych-button [label]="btn.label" variant="filled" size="small" (click)="btn.action()" />
118
+ }
119
+ </div>
120
+ }
121
+ </div>
122
122
  `, isInline: true, styles: [":host{display:block;border-bottom:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}:host:first-child{border-top:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant)}.trigger{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);width:100%;padding:var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-24);background:none;border:none;cursor:pointer;text-align:left;color:var(--surface-surface-sys-on-surface);font-family:var(--font-core-title);font-size:var(--size-core-lg);font-weight:var(--label-large-sys-font-weight);line-height:var(--size-core-2xl);letter-spacing:var(--spacing-core-spacing-0);position:relative;overflow:hidden;border-radius:0}.trigger:before{content:\"\";position:absolute;inset:0;background-color:currentColor;opacity:0;transition:opacity .15s ease;pointer-events:none}.trigger:hover:before{opacity:.08}.trigger:active:before{opacity:.1}.trigger-label{flex:1;min-width:0}.trigger-leading-icon{display:flex;align-items:center;justify-content:center;width:var(--sys-size-sm);height:var(--sys-size-sm);color:var(--surface-surface-sys-on-surface);flex-shrink:0}.trigger-leading-icon svg{width:100%;height:100%}.trigger-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.5rem;height:1.5rem;font-size:1rem;line-height:1;color:var(--surface-surface-sys-on-surface-variant);background-color:var(--surface-surface-container-sys-surface-container);border-radius:var(--border-radius-sys-radius-full);box-sizing:border-box}.trigger[aria-expanded=true] .trigger-toggle{color:var(--add-on-primary-fixed-sys-on-primary-fixed);background-color:var(--add-on-primary-fixed-sys-primary-fixed-dim)}.actions{display:flex;flex-wrap:wrap;gap:var(--spacing-padding-sys-padding-12);align-items:center;justify-content:flex-end;padding:var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-24);border-top:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline)}:host(.level-2){border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant);border-radius:0;overflow:hidden}:host(.level-2):first-child{border-radius:var(--border-radius-sys-radius-sm) var(--border-radius-sys-radius-sm) 0 0}:host(.level-2):last-child{border-radius:0 0 var(--border-radius-sys-radius-sm) var(--border-radius-sys-radius-sm)}:host(.level-2):only-child{border-radius:var(--border-radius-sys-radius-sm)}:host(.level-2.nested){border-radius:var(--border-radius-sys-radius-sm)}:host(.level-2) .trigger{padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-16);gap:var(--spacing-padding-sys-padding-4);font-size:var(--size-core-base);line-height:var(--size-core-xl)}:host(.level-2) .actions{padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-24)}:host(.level-2) .content{padding:0 var(--spacing-padding-sys-padding-24) var(--spacing-padding-sys-padding-8)}:host(.text-only){border:none}:host(.text-only) .trigger{padding:var(--spacing-padding-sys-padding-8) 0;font-size:var(--size-core-base);font-weight:var(--label-large-sys-font-weight-emphasized);line-height:var(--size-core-xl)}:host(.text-only) .trigger-leading-icon{display:none}:host(.text-only) .trigger-toggle{order:-1;color:var(--surface-surface-sys-on-surface-variant);background-color:var(--surface-surface-container-sys-surface-container)}.content{padding:0 var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-16);color:var(--surface-surface-sys-on-surface-variant);font-family:var(--font-core-body);font-size:var(--size-core-base);font-weight:var(--label-large-sys-font-weight);line-height:var(--size-core-xl);letter-spacing:var(--spacing-core-spacing-0)}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => ButtonComponent), selector: "compsych-button", inputs: ["label", "variant", "size", "icon", "iconOnly", "disabled"] }, { kind: "component", type: i0.forwardRef(() => AccordionComponent), selector: "compsych-accordion", inputs: ["items", "variant", "nested", "multi"] }] });
123
123
  }
124
124
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AccordionItemComponent, decorators: [{
125
125
  type: Component,
126
- args: [{ selector: 'compsych-accordion-item', standalone: true, imports: [ButtonComponent, forwardRef(() => AccordionComponent)], template: `
127
- <button
128
- class="trigger"
129
- type="button"
130
- [id]="triggerId"
131
- [attr.aria-expanded]="expanded"
132
- [attr.aria-controls]="panelId"
133
- (click)="toggle()"
134
- >
135
- @if (iconSvg) {
136
- <span class="trigger-leading-icon" [innerHTML]="iconSvg" aria-hidden="true"></span>
137
- }
138
- <span class="trigger-label">{{ title }}</span>
139
- <span class="trigger-toggle material-symbols-rounded" aria-hidden="true">{{ expanded ? 'remove' : 'add' }}</span>
140
- </button>
141
- <div
142
- [id]="panelId"
143
- role="region"
144
- [attr.aria-labelledby]="triggerId"
145
- [hidden]="!expanded"
146
- >
147
- @if (content) {
148
- <div class="content" [innerHTML]="sanitizedContent"></div>
149
- }
150
- @if (nestedContent.length) {
151
- <compsych-accordion [items]="nestedContent" variant="level-2" [nested]="true" />
152
- }
153
- @if (buttons.length) {
154
- <div class="actions">
155
- @for (btn of buttons; track btn.label) {
156
- <compsych-button [label]="btn.label" variant="filled" size="small" (click)="btn.action()" />
157
- }
158
- </div>
159
- }
160
- </div>
126
+ args: [{ selector: 'compsych-accordion-item', standalone: true, imports: [ButtonComponent, forwardRef(() => AccordionComponent)], template: `
127
+ <button
128
+ class="trigger"
129
+ type="button"
130
+ [id]="triggerId"
131
+ [attr.aria-expanded]="expanded"
132
+ [attr.aria-controls]="panelId"
133
+ (click)="toggle()"
134
+ >
135
+ @if (iconSvg) {
136
+ <span class="trigger-leading-icon" [innerHTML]="iconSvg" aria-hidden="true"></span>
137
+ }
138
+ <span class="trigger-label">{{ title }}</span>
139
+ <span class="trigger-toggle material-symbols-rounded" aria-hidden="true">{{ expanded ? 'remove' : 'add' }}</span>
140
+ </button>
141
+ <div
142
+ [id]="panelId"
143
+ role="region"
144
+ [attr.aria-labelledby]="triggerId"
145
+ [hidden]="!expanded"
146
+ >
147
+ @if (content) {
148
+ <div class="content" [innerHTML]="sanitizedContent"></div>
149
+ }
150
+ @if (nestedContent.length) {
151
+ <compsych-accordion [items]="nestedContent" variant="level-2" [nested]="true" />
152
+ }
153
+ @if (buttons.length) {
154
+ <div class="actions">
155
+ @for (btn of buttons; track btn.label) {
156
+ <compsych-button [label]="btn.label" variant="filled" size="small" (click)="btn.action()" />
157
+ }
158
+ </div>
159
+ }
160
+ </div>
161
161
  `, host: {
162
162
  class: 'compsych-accordion-item',
163
163
  '[class.level-2]': 'variant === "level-2"',
@@ -210,38 +210,38 @@ export class AccordionComponent {
210
210
  this.expandedSet = new Set(this.expandedSet);
211
211
  }
212
212
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
213
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: AccordionComponent, isStandalone: true, selector: "compsych-accordion", inputs: { items: "items", variant: "variant", nested: "nested", multi: "multi" }, host: { properties: { "class.level-2": "variant === \"level-2\"", "class.text-only": "variant === \"text-only\"", "class.nested": "nested" } }, ngImport: i0, template: `
214
- @for (item of items; track $index; let i = $index) {
215
- <compsych-accordion-item
216
- [title]="item.title"
217
- [content]="item.content ?? ''"
218
- [icon]="item.icon ?? ''"
219
- [buttons]="item.buttons ?? []"
220
- [nestedContent]="item.nestedContent ?? []"
221
- [variant]="variant"
222
- [nested]="nested"
223
- [expanded]="expandedSet.has(i)"
224
- (expandedChange)="onExpandedChange(i, $event)"
225
- />
226
- }
213
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: AccordionComponent, isStandalone: true, selector: "compsych-accordion", inputs: { items: "items", variant: "variant", nested: "nested", multi: "multi" }, host: { properties: { "class.level-2": "variant === \"level-2\"", "class.text-only": "variant === \"text-only\"", "class.nested": "nested" } }, ngImport: i0, template: `
214
+ @for (item of items; track $index; let i = $index) {
215
+ <compsych-accordion-item
216
+ [title]="item.title"
217
+ [content]="item.content ?? ''"
218
+ [icon]="item.icon ?? ''"
219
+ [buttons]="item.buttons ?? []"
220
+ [nestedContent]="item.nestedContent ?? []"
221
+ [variant]="variant"
222
+ [nested]="nested"
223
+ [expanded]="expandedSet.has(i)"
224
+ (expandedChange)="onExpandedChange(i, $event)"
225
+ />
226
+ }
227
227
  `, isInline: true, styles: [":host{display:block;background-color:var(--surface-surface-container-sys-surface-container-lowest);border:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);border-radius:var(--border-radius-sys-radius-md);overflow:hidden}:host(.level-2){display:flex;flex-direction:column;background-color:transparent;border:none;border-radius:0;overflow:visible}:host(.level-2.nested){gap:var(--spacing-padding-sys-padding-12);padding:0 var(--spacing-padding-sys-padding-24) var(--spacing-padding-sys-padding-24)}:host(.text-only){background-color:transparent;border:none;border-radius:0;overflow:visible}\n"], dependencies: [{ kind: "component", type: AccordionItemComponent, selector: "compsych-accordion-item", inputs: ["title", "content", "buttons", "nestedContent", "variant", "nested", "icon", "expanded"], outputs: ["expandedChange"] }] });
228
228
  }
229
229
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AccordionComponent, decorators: [{
230
230
  type: Component,
231
- args: [{ selector: 'compsych-accordion', standalone: true, imports: [AccordionItemComponent], template: `
232
- @for (item of items; track $index; let i = $index) {
233
- <compsych-accordion-item
234
- [title]="item.title"
235
- [content]="item.content ?? ''"
236
- [icon]="item.icon ?? ''"
237
- [buttons]="item.buttons ?? []"
238
- [nestedContent]="item.nestedContent ?? []"
239
- [variant]="variant"
240
- [nested]="nested"
241
- [expanded]="expandedSet.has(i)"
242
- (expandedChange)="onExpandedChange(i, $event)"
243
- />
244
- }
231
+ args: [{ selector: 'compsych-accordion', standalone: true, imports: [AccordionItemComponent], template: `
232
+ @for (item of items; track $index; let i = $index) {
233
+ <compsych-accordion-item
234
+ [title]="item.title"
235
+ [content]="item.content ?? ''"
236
+ [icon]="item.icon ?? ''"
237
+ [buttons]="item.buttons ?? []"
238
+ [nestedContent]="item.nestedContent ?? []"
239
+ [variant]="variant"
240
+ [nested]="nested"
241
+ [expanded]="expandedSet.has(i)"
242
+ (expandedChange)="onExpandedChange(i, $event)"
243
+ />
244
+ }
245
245
  `, host: {
246
246
  '[class.level-2]': 'variant === "level-2"',
247
247
  '[class.text-only]': 'variant === "text-only"',
@@ -1 +1 @@
1
- {"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/accordion/accordion.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n ElementRef,\n EventEmitter,\n forwardRef,\n HostListener,\n Input,\n Output,\n SecurityContext,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\nimport { ButtonComponent } from '../button/button';\nimport { AccordionButton, AccordionItem, AccordionVariant, NestedAccordionItem } from './accordion-types';\n\nexport type { AccordionButton, AccordionItem, AccordionVariant, NestedAccordionItem };\n\nlet nextId = 0;\n\n// AccordionItemComponent is defined before AccordionComponent because AccordionComponent\n// uses it directly in its imports. AccordionItemComponent references AccordionComponent\n// via forwardRef to break the forward-reference cycle within this file.\n@Component({\n selector: 'compsych-accordion-item',\n standalone: true,\n imports: [ButtonComponent, forwardRef(() => AccordionComponent)],\n template: `\n <button\n class=\"trigger\"\n type=\"button\"\n [id]=\"triggerId\"\n [attr.aria-expanded]=\"expanded\"\n [attr.aria-controls]=\"panelId\"\n (click)=\"toggle()\"\n >\n @if (iconSvg) {\n <span class=\"trigger-leading-icon\" [innerHTML]=\"iconSvg\" aria-hidden=\"true\"></span>\n }\n <span class=\"trigger-label\">{{ title }}</span>\n <span class=\"trigger-toggle material-symbols-rounded\" aria-hidden=\"true\">{{ expanded ? 'remove' : 'add' }}</span>\n </button>\n <div\n [id]=\"panelId\"\n role=\"region\"\n [attr.aria-labelledby]=\"triggerId\"\n [hidden]=\"!expanded\"\n >\n @if (content) {\n <div class=\"content\" [innerHTML]=\"sanitizedContent\"></div>\n }\n @if (nestedContent.length) {\n <compsych-accordion [items]=\"nestedContent\" variant=\"level-2\" [nested]=\"true\" />\n }\n @if (buttons.length) {\n <div class=\"actions\">\n @for (btn of buttons; track btn.label) {\n <compsych-button [label]=\"btn.label\" variant=\"filled\" size=\"small\" (click)=\"btn.action()\" />\n }\n </div>\n }\n </div>\n `,\n styleUrl: './accordion-item.css',\n host: {\n class: 'compsych-accordion-item',\n '[class.level-2]': 'variant === \"level-2\"',\n '[class.text-only]': 'variant === \"text-only\"',\n '[class.nested]': 'nested',\n },\n})\n/**\n * A single expandable row used internally by `AccordionComponent`.\n * Consumers should use `compsych-accordion` with an `items` array rather\n * than placing `compsych-accordion-item` elements directly.\n */\nexport class AccordionItemComponent {\n readonly triggerId = `accordion-trigger-${nextId}`;\n readonly panelId = `accordion-panel-${nextId++}`;\n\n /** Text shown in the trigger button header. */\n @Input() title = '';\n /** HTML string rendered in the panel body when expanded. Sanitized before display. */\n @Input() content = '';\n /** Action buttons rendered at the bottom of the panel. */\n @Input() buttons: AccordionButton[] = [];\n /** Items rendered as a nested level-2 accordion inside this panel. */\n @Input() nestedContent: NestedAccordionItem[] = [];\n /** Visual style — inherited from the parent AccordionComponent. */\n @Input() variant: AccordionVariant = 'default';\n /** True when this item is rendered inside a parent accordion panel. Adds nested styling. Set automatically by AccordionComponent — do not set directly. */\n @Input() nested = false;\n\n /** Lucide icon name (kebab-case) shown to the left of the title. Pass an empty string to show no icon. */\n @Input()\n set icon(name: string) {\n const svg = LUCIDE_ICONS[name];\n this.iconSvg = svg ? this.sanitizer.bypassSecurityTrustHtml(svg) : null;\n }\n\n iconSvg: SafeHtml | null = null;\n\n get sanitizedContent(): SafeHtml {\n return this.sanitizer.sanitize(SecurityContext.HTML, this.content) ?? '';\n }\n\n constructor(\n private readonly sanitizer: DomSanitizer,\n private readonly el: ElementRef<HTMLElement>,\n ) {}\n\n /** Whether this panel is currently open. Supports boolean coercion (e.g. `[expanded]=\"true\"`). */\n @Input()\n get expanded(): boolean { return this._expanded; }\n set expanded(value: BooleanInput) { this._expanded = coerceBooleanProperty(value); }\n private _expanded = false;\n\n /** Emitted when the panel is toggled. `true` = opening, `false` = closing. */\n @Output() expandedChange = new EventEmitter<boolean>();\n\n toggle(): void {\n this._expanded = !this._expanded;\n this.expandedChange.emit(this._expanded);\n }\n\n @HostListener('keydown', ['$event'])\n onKeydown(event: KeyboardEvent): void {\n const target = event.target as HTMLElement;\n if (!(target instanceof HTMLButtonElement) || !target.classList.contains('trigger')) return;\n\n const parent = this.el.nativeElement.parentElement;\n if (!parent) return;\n\n const triggers = Array.from(\n parent.querySelectorAll<HTMLButtonElement>(':scope > compsych-accordion-item > button.trigger'),\n );\n const currentIndex = triggers.indexOf(target);\n let focusIndex = -1;\n\n switch (event.key) {\n case 'ArrowDown': focusIndex = currentIndex + 1; break;\n case 'ArrowUp': focusIndex = currentIndex - 1; break;\n case 'Home': focusIndex = 0; break;\n case 'End': focusIndex = triggers.length - 1; break;\n default: return;\n }\n\n if (focusIndex >= 0 && focusIndex < triggers.length) {\n triggers[focusIndex].focus();\n event.preventDefault();\n }\n }\n}\n\n@Component({\n selector: 'compsych-accordion',\n standalone: true,\n imports: [AccordionItemComponent],\n template: `\n @for (item of items; track $index; let i = $index) {\n <compsych-accordion-item\n [title]=\"item.title\"\n [content]=\"item.content ?? ''\"\n [icon]=\"item.icon ?? ''\"\n [buttons]=\"item.buttons ?? []\"\n [nestedContent]=\"item.nestedContent ?? []\"\n [variant]=\"variant\"\n [nested]=\"nested\"\n [expanded]=\"expandedSet.has(i)\"\n (expandedChange)=\"onExpandedChange(i, $event)\"\n />\n }\n `,\n styleUrl: './accordion.css',\n host: {\n '[class.level-2]': 'variant === \"level-2\"',\n '[class.text-only]': 'variant === \"text-only\"',\n '[class.nested]': 'nested',\n },\n})\nexport class AccordionComponent {\n /** Items to render as expandable rows. */\n @Input() items: AccordionItem[] = [];\n /** Visual style applied to all items. `'default'` is the standard card style; `'level-2'` is compact nested style; `'text-only'` removes card chrome. */\n @Input() variant: AccordionVariant = 'default';\n /** Set automatically when this accordion is rendered inside another accordion panel. Do not set directly. */\n @Input() nested = false;\n /** When true, multiple panels can be open simultaneously. Defaults to false — opening one panel closes any others. Supports boolean coercion. */\n @Input()\n get multi(): boolean { return this._multi; }\n set multi(value: BooleanInput) { this._multi = coerceBooleanProperty(value); }\n private _multi = false;\n\n expandedSet = new Set<number>();\n\n onExpandedChange(index: number, isExpanded: boolean): void {\n if (isExpanded) {\n if (!this._multi) this.expandedSet.clear();\n this.expandedSet.add(index);\n } else {\n this.expandedSet.delete(index);\n }\n this.expandedSet = new Set(this.expandedSet);\n }\n}\n"]}
1
+ {"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/accordion/accordion.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n forwardRef,\r\n HostListener,\r\n Input,\r\n Output,\r\n SecurityContext,\r\n} from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\r\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\r\nimport { ButtonComponent } from '../button/button';\r\nimport { AccordionButton, AccordionItem, AccordionVariant, NestedAccordionItem } from './accordion-types';\r\n\r\nexport type { AccordionButton, AccordionItem, AccordionVariant, NestedAccordionItem };\r\n\r\nlet nextId = 0;\r\n\r\n// AccordionItemComponent is defined before AccordionComponent because AccordionComponent\r\n// uses it directly in its imports. AccordionItemComponent references AccordionComponent\r\n// via forwardRef to break the forward-reference cycle within this file.\r\n@Component({\r\n selector: 'compsych-accordion-item',\r\n standalone: true,\r\n imports: [ButtonComponent, forwardRef(() => AccordionComponent)],\r\n template: `\r\n <button\r\n class=\"trigger\"\r\n type=\"button\"\r\n [id]=\"triggerId\"\r\n [attr.aria-expanded]=\"expanded\"\r\n [attr.aria-controls]=\"panelId\"\r\n (click)=\"toggle()\"\r\n >\r\n @if (iconSvg) {\r\n <span class=\"trigger-leading-icon\" [innerHTML]=\"iconSvg\" aria-hidden=\"true\"></span>\r\n }\r\n <span class=\"trigger-label\">{{ title }}</span>\r\n <span class=\"trigger-toggle material-symbols-rounded\" aria-hidden=\"true\">{{ expanded ? 'remove' : 'add' }}</span>\r\n </button>\r\n <div\r\n [id]=\"panelId\"\r\n role=\"region\"\r\n [attr.aria-labelledby]=\"triggerId\"\r\n [hidden]=\"!expanded\"\r\n >\r\n @if (content) {\r\n <div class=\"content\" [innerHTML]=\"sanitizedContent\"></div>\r\n }\r\n @if (nestedContent.length) {\r\n <compsych-accordion [items]=\"nestedContent\" variant=\"level-2\" [nested]=\"true\" />\r\n }\r\n @if (buttons.length) {\r\n <div class=\"actions\">\r\n @for (btn of buttons; track btn.label) {\r\n <compsych-button [label]=\"btn.label\" variant=\"filled\" size=\"small\" (click)=\"btn.action()\" />\r\n }\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styleUrl: './accordion-item.css',\r\n host: {\r\n class: 'compsych-accordion-item',\r\n '[class.level-2]': 'variant === \"level-2\"',\r\n '[class.text-only]': 'variant === \"text-only\"',\r\n '[class.nested]': 'nested',\r\n },\r\n})\r\n/**\r\n * A single expandable row used internally by `AccordionComponent`.\r\n * Consumers should use `compsych-accordion` with an `items` array rather\r\n * than placing `compsych-accordion-item` elements directly.\r\n */\r\nexport class AccordionItemComponent {\r\n readonly triggerId = `accordion-trigger-${nextId}`;\r\n readonly panelId = `accordion-panel-${nextId++}`;\r\n\r\n /** Text shown in the trigger button header. */\r\n @Input() title = '';\r\n /** HTML string rendered in the panel body when expanded. Sanitized before display. */\r\n @Input() content = '';\r\n /** Action buttons rendered at the bottom of the panel. */\r\n @Input() buttons: AccordionButton[] = [];\r\n /** Items rendered as a nested level-2 accordion inside this panel. */\r\n @Input() nestedContent: NestedAccordionItem[] = [];\r\n /** Visual style — inherited from the parent AccordionComponent. */\r\n @Input() variant: AccordionVariant = 'default';\r\n /** True when this item is rendered inside a parent accordion panel. Adds nested styling. Set automatically by AccordionComponent — do not set directly. */\r\n @Input() nested = false;\r\n\r\n /** Lucide icon name (kebab-case) shown to the left of the title. Pass an empty string to show no icon. */\r\n @Input()\r\n set icon(name: string) {\r\n const svg = LUCIDE_ICONS[name];\r\n this.iconSvg = svg ? this.sanitizer.bypassSecurityTrustHtml(svg) : null;\r\n }\r\n\r\n iconSvg: SafeHtml | null = null;\r\n\r\n get sanitizedContent(): SafeHtml {\r\n return this.sanitizer.sanitize(SecurityContext.HTML, this.content) ?? '';\r\n }\r\n\r\n constructor(\r\n private readonly sanitizer: DomSanitizer,\r\n private readonly el: ElementRef<HTMLElement>,\r\n ) {}\r\n\r\n /** Whether this panel is currently open. Supports boolean coercion (e.g. `[expanded]=\"true\"`). */\r\n @Input()\r\n get expanded(): boolean { return this._expanded; }\r\n set expanded(value: BooleanInput) { this._expanded = coerceBooleanProperty(value); }\r\n private _expanded = false;\r\n\r\n /** Emitted when the panel is toggled. `true` = opening, `false` = closing. */\r\n @Output() expandedChange = new EventEmitter<boolean>();\r\n\r\n toggle(): void {\r\n this._expanded = !this._expanded;\r\n this.expandedChange.emit(this._expanded);\r\n }\r\n\r\n @HostListener('keydown', ['$event'])\r\n onKeydown(event: KeyboardEvent): void {\r\n const target = event.target as HTMLElement;\r\n if (!(target instanceof HTMLButtonElement) || !target.classList.contains('trigger')) return;\r\n\r\n const parent = this.el.nativeElement.parentElement;\r\n if (!parent) return;\r\n\r\n const triggers = Array.from(\r\n parent.querySelectorAll<HTMLButtonElement>(':scope > compsych-accordion-item > button.trigger'),\r\n );\r\n const currentIndex = triggers.indexOf(target);\r\n let focusIndex = -1;\r\n\r\n switch (event.key) {\r\n case 'ArrowDown': focusIndex = currentIndex + 1; break;\r\n case 'ArrowUp': focusIndex = currentIndex - 1; break;\r\n case 'Home': focusIndex = 0; break;\r\n case 'End': focusIndex = triggers.length - 1; break;\r\n default: return;\r\n }\r\n\r\n if (focusIndex >= 0 && focusIndex < triggers.length) {\r\n triggers[focusIndex].focus();\r\n event.preventDefault();\r\n }\r\n }\r\n}\r\n\r\n@Component({\r\n selector: 'compsych-accordion',\r\n standalone: true,\r\n imports: [AccordionItemComponent],\r\n template: `\r\n @for (item of items; track $index; let i = $index) {\r\n <compsych-accordion-item\r\n [title]=\"item.title\"\r\n [content]=\"item.content ?? ''\"\r\n [icon]=\"item.icon ?? ''\"\r\n [buttons]=\"item.buttons ?? []\"\r\n [nestedContent]=\"item.nestedContent ?? []\"\r\n [variant]=\"variant\"\r\n [nested]=\"nested\"\r\n [expanded]=\"expandedSet.has(i)\"\r\n (expandedChange)=\"onExpandedChange(i, $event)\"\r\n />\r\n }\r\n `,\r\n styleUrl: './accordion.css',\r\n host: {\r\n '[class.level-2]': 'variant === \"level-2\"',\r\n '[class.text-only]': 'variant === \"text-only\"',\r\n '[class.nested]': 'nested',\r\n },\r\n})\r\nexport class AccordionComponent {\r\n /** Items to render as expandable rows. */\r\n @Input() items: AccordionItem[] = [];\r\n /** Visual style applied to all items. `'default'` is the standard card style; `'level-2'` is compact nested style; `'text-only'` removes card chrome. */\r\n @Input() variant: AccordionVariant = 'default';\r\n /** Set automatically when this accordion is rendered inside another accordion panel. Do not set directly. */\r\n @Input() nested = false;\r\n /** When true, multiple panels can be open simultaneously. Defaults to false — opening one panel closes any others. Supports boolean coercion. */\r\n @Input()\r\n get multi(): boolean { return this._multi; }\r\n set multi(value: BooleanInput) { this._multi = coerceBooleanProperty(value); }\r\n private _multi = false;\r\n\r\n expandedSet = new Set<number>();\r\n\r\n onExpandedChange(index: number, isExpanded: boolean): void {\r\n if (isExpanded) {\r\n if (!this._multi) this.expandedSet.clear();\r\n this.expandedSet.add(index);\r\n } else {\r\n this.expandedSet.delete(index);\r\n }\r\n this.expandedSet = new Set(this.expandedSet);\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/button/button.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Component,\r\n HostBinding,\r\n HostListener,\r\n Input,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy,\r\n inject,\r\n} from '@angular/core';\r\nimport { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';\r\n\r\n/** Visual style of a `compsych-button`. Controls color, border, and elevation. Icon variants (e.g. `'filled-icon'`) are used by `NavAction` to render icon buttons in the header nav and are not handled by the button component itself. */\r\nexport type ButtonVariant =\r\n | 'filled' | 'tonal' | 'outlined' | 'elevated' | 'text' | 'danger' | 'danger-outlined'\r\n | 'filled-icon' | 'tonal-icon' | 'outlined-icon' | 'elevated-icon' | 'text-icon' | 'danger-icon' | 'danger-outlined-icon';\r\nimport { coerceBooleanProperty, BooleanInput } from '@angular/cdk/coercion';\r\n\r\n@Component({\r\n selector: 'compsych-button',\r\n standalone: true,\r\n template: `\r\n @if (icon) {\r\n <span class=\"icon material-symbols-rounded\" aria-hidden=\"true\">{{ icon }}</span>\r\n }\r\n <span class=\"label\">{{ label }}</span>\r\n `,\r\n styleUrl: './button.css',\r\n host: {\r\n 'tabindex': '0',\r\n 'role': 'button',\r\n },\r\n})\r\nexport class ButtonComponent implements AfterViewInit, OnDestroy {\r\n private readonly focusMonitor = inject(FocusMonitor);\r\n private readonly elementRef = inject(ElementRef<HTMLElement>);\r\n\r\n /** Text label rendered on the button. */\r\n @Input() label = '';\r\n /** Visual style of the button. Defaults to `'filled'`. */\r\n @Input() variant: ButtonVariant = 'filled';\r\n /** Button dimensions — controls height, padding, and font size. Defaults to `'small'`. */\r\n @Input() size: 'small' | 'medium' | 'large' | 'xlarge' = 'small';\r\n /** Material Symbols icon name shown to the left of the label (e.g. `'search'`, `'add'`). Omit to show label only. */\r\n @Input() icon?: string;\r\n\r\n /** When true, hides the label and renders a square icon-only button. Requires `icon` to be set. Supports boolean coercion. */\r\n @Input()\r\n get iconOnly(): boolean { return this._iconOnly; }\r\n set iconOnly(value: BooleanInput) { this._iconOnly = coerceBooleanProperty(value); }\r\n private _iconOnly = false;\r\n\r\n /** When true, the button is non-interactive — `disabled` and `aria-disabled` attributes are set and `tabIndex` is set to `-1`. Supports boolean coercion. */\r\n @Input()\r\n get disabled(): boolean { return this._disabled; }\r\n set disabled(value: BooleanInput) {\r\n this._disabled = coerceBooleanProperty(value);\r\n this.elementRef.nativeElement.tabIndex = this._disabled ? -1 : 0;\r\n }\r\n private _disabled = false;\r\n\r\n protected _focused = false;\r\n protected _focusOrigin: FocusOrigin = null;\r\n\r\n @HostBinding('class') get hostClass(): string {\r\n return [\r\n this.variant,\r\n this.size,\r\n this._iconOnly ? 'icon-only' : '',\r\n this._focused && this._focusOrigin === 'keyboard' ? 'focus-keyboard' : '',\r\n ].filter(Boolean).join(' ');\r\n }\r\n\r\n @HostBinding('attr.aria-disabled') get ariaDisabled(): string | null {\r\n return this._disabled ? 'true' : null;\r\n }\r\n\r\n @HostBinding('attr.disabled') get attrDisabled(): '' | null {\r\n return this._disabled ? '' : null;\r\n }\r\n\r\n @HostListener('keydown.enter', ['$event'])\r\n onEnterKeydown(event: Event): void {\r\n if (!this._disabled) {\r\n event.preventDefault();\r\n this.elementRef.nativeElement.click();\r\n }\r\n }\r\n\r\n // Space: prevent scroll on keydown; fire action on keyup (matches native button behaviour).\r\n @HostListener('keydown.space', ['$event'])\r\n onSpaceKeydown(event: Event): void {\r\n event.preventDefault();\r\n }\r\n\r\n @HostListener('keyup.space')\r\n onSpaceKeyup(): void {\r\n if (!this._disabled) {\r\n this.elementRef.nativeElement.click();\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n this.focusMonitor.monitor(this.elementRef).subscribe(origin => {\r\n this._focused = !!origin;\r\n this._focusOrigin = origin;\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.focusMonitor.stopMonitoring(this.elementRef);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/button/button.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Component,\r\n HostBinding,\r\n HostListener,\r\n Input,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy,\r\n inject,\r\n} from '@angular/core';\r\nimport { FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';\r\n\r\n/** Visual style of a `compsych-button`. Controls color, border, and elevation. */\r\nexport type ButtonVariant = 'filled' | 'tonal' | 'outlined' | 'elevated' | 'text' | 'danger' | 'danger-outlined';\r\nimport { coerceBooleanProperty, BooleanInput } from '@angular/cdk/coercion';\r\n\r\n@Component({\r\n selector: 'compsych-button',\r\n standalone: true,\r\n template: `\r\n @if (icon) {\r\n <span class=\"icon material-symbols-rounded\" aria-hidden=\"true\">{{ icon }}</span>\r\n }\r\n <span class=\"label\">{{ label }}</span>\r\n `,\r\n styleUrl: './button.css',\r\n host: {\r\n 'tabindex': '0',\r\n 'role': 'button',\r\n },\r\n})\r\nexport class ButtonComponent implements AfterViewInit, OnDestroy {\r\n private readonly focusMonitor = inject(FocusMonitor);\r\n private readonly elementRef = inject(ElementRef<HTMLElement>);\r\n\r\n /** Text label rendered on the button. */\r\n @Input() label = '';\r\n /** Visual style of the button. Defaults to `'filled'`. */\r\n @Input() variant: ButtonVariant = 'filled';\r\n /** Button dimensions — controls height, padding, and font size. Defaults to `'small'`. */\r\n @Input() size: 'small' | 'medium' | 'large' | 'xlarge' = 'small';\r\n /** Material Symbols icon name shown to the left of the label (e.g. `'search'`, `'add'`). Omit to show label only. */\r\n @Input() icon?: string;\r\n\r\n /** When true, hides the label and renders a square icon-only button. Requires `icon` to be set. Supports boolean coercion. */\r\n @Input()\r\n get iconOnly(): boolean { return this._iconOnly; }\r\n set iconOnly(value: BooleanInput) { this._iconOnly = coerceBooleanProperty(value); }\r\n private _iconOnly = false;\r\n\r\n /** When true, the button is non-interactive — `disabled` and `aria-disabled` attributes are set and `tabIndex` is set to `-1`. Supports boolean coercion. */\r\n @Input()\r\n get disabled(): boolean { return this._disabled; }\r\n set disabled(value: BooleanInput) {\r\n this._disabled = coerceBooleanProperty(value);\r\n this.elementRef.nativeElement.tabIndex = this._disabled ? -1 : 0;\r\n }\r\n private _disabled = false;\r\n\r\n protected _focused = false;\r\n protected _focusOrigin: FocusOrigin = null;\r\n\r\n @HostBinding('class') get hostClass(): string {\r\n return [\r\n this.variant,\r\n this.size,\r\n this._iconOnly ? 'icon-only' : '',\r\n this._focused && this._focusOrigin === 'keyboard' ? 'focus-keyboard' : '',\r\n ].filter(Boolean).join(' ');\r\n }\r\n\r\n @HostBinding('attr.aria-disabled') get ariaDisabled(): string | null {\r\n return this._disabled ? 'true' : null;\r\n }\r\n\r\n @HostBinding('attr.disabled') get attrDisabled(): '' | null {\r\n return this._disabled ? '' : null;\r\n }\r\n\r\n @HostListener('keydown.enter', ['$event'])\r\n onEnterKeydown(event: Event): void {\r\n if (!this._disabled) {\r\n event.preventDefault();\r\n this.elementRef.nativeElement.click();\r\n }\r\n }\r\n\r\n // Space: prevent scroll on keydown; fire action on keyup (matches native button behaviour).\r\n @HostListener('keydown.space', ['$event'])\r\n onSpaceKeydown(event: Event): void {\r\n event.preventDefault();\r\n }\r\n\r\n @HostListener('keyup.space')\r\n onSpaceKeyup(): void {\r\n if (!this._disabled) {\r\n this.elementRef.nativeElement.click();\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n this.focusMonitor.monitor(this.elementRef).subscribe(origin => {\r\n this._focused = !!origin;\r\n this._focusOrigin = origin;\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.focusMonitor.stopMonitoring(this.elementRef);\r\n }\r\n}\r\n"]}
@@ -7,24 +7,27 @@ import * as i1 from "@angular/platform-browser";
7
7
  * Header Navigation — top app bar from the ComPsych Design System.
8
8
  *
9
9
  * Three layout levels controlled by `level`:
10
- * - `'main'` — menu toggle, brand logo + wordmark, action buttons.
11
- * - `'sub-page'` — menu toggle, logo mark + breadcrumb trail, action buttons.
12
- * - `'not-logged'` — menu toggle, brand, action buttons.
10
+ * - `'main'` — menu toggle, brand logo + wordmark, logged-in action cluster.
11
+ * - `'sub-page'` — menu toggle, logo mark + breadcrumb trail, logged-in action cluster.
12
+ * - `'not-logged'` — menu toggle, brand, public action cluster (language, help, CTA buttons).
13
13
  *
14
- * Icon and labeled buttons in the right action area are configured via `actionButtons`.
15
14
  * All interactive elements emit a string id via the `action` output.
15
+ * For breadcrumbs and action buttons the emitted value is the `NavAction.id`.
16
+ * For built-in icon buttons a fixed string is emitted (see `action` docs).
16
17
  */
17
18
  export class HeaderNavComponent {
18
19
  sanitizer;
19
20
  /**
20
- * Layout of the header left region.
21
- * - `'main'` — logo + brand label.
22
- * - `'sub-page'` — symbol mark + breadcrumb trail.
23
- * - `'not-logged'` — logo + brand label.
21
+ * Layout and feature set of the header.
22
+ * - `'main'` — logo + brand label, logged-in action cluster (search, notifications, documents, language, avatar, logout).
23
+ * - `'sub-page'` — symbol mark + breadcrumb trail, same logged-in action cluster.
24
+ * - `'not-logged'` — logo + brand label, public action cluster (language, help, action buttons).
24
25
  */
25
26
  level = 'main';
26
27
  /** Whether the paired sidebar is open — toggles the menu icon (☰ ↔ ✕). */
27
28
  sidebarOpen = false;
29
+ /** Show the hamburger / close menu toggle button. */
30
+ showMenuToggle = true;
28
31
  /** Accessible label for the brand area (logo + wordmark) used by screen readers. */
29
32
  brandLabelAria = 'ComPsych';
30
33
  /** Brand wordmark text rendered next to the logo on `main` and `not-logged` levels. */
@@ -44,10 +47,29 @@ export class HeaderNavComponent {
44
47
  * via the `action` output when clicked.
45
48
  */
46
49
  breadcrumbs = [];
50
+ /** Notification badge count. Badge is hidden when 0. */
51
+ notificationCount = 0;
52
+ /** Avatar initials for the logged-in user. */
53
+ avatarInitials = 'CP';
54
+ /** Show the search icon button (logged-in levels). */
55
+ showSearch = true;
56
+ /** Show the calendar-check icon button (logged-in levels). */
57
+ showCalendarChecked = true;
58
+ /** Show the notifications icon button (logged-in levels). */
59
+ showNotifications = true;
60
+ /** Show the documents icon button (logged-in levels). */
61
+ showDocuments = true;
62
+ /** Show the avatar button (logged-in levels). */
63
+ showAvatar = true;
64
+ /** Show the language icon button (main, sub-page, and not-logged levels). */
65
+ showLanguage = true;
66
+ /** Show the help icon button (not-logged level). */
67
+ showHelp = true;
68
+ /** Show the logout icon button (main and sub-page levels). */
69
+ showLogout = false;
47
70
  /**
48
- * Buttons rendered in the right action area.
49
- * - When `variant` ends in `'-icon'`, renders an icon button using `icon` as the Lucide name; `label` is used as aria-label.
50
- * - Otherwise, renders a labeled `<compsych-button>` using `label` and `variant`.
71
+ * Additional configurable buttons rendered in the actions area.
72
+ * Each entry requires `id` and `label`; `variant` defaults to `'filled'`.
51
73
  * Clicking any button emits its `id` via the `action` output.
52
74
  */
53
75
  actionButtons = [];
@@ -56,37 +78,77 @@ export class HeaderNavComponent {
56
78
  * Fixed values for built-in controls:
57
79
  * - `'menu-toggle'` — hamburger / close button
58
80
  * - `'logo'` — brand / logo button
81
+ * - `'search'` — search icon button
82
+ * - `'calendar-checked'` — calendar-check icon button
83
+ * - `'notifications'` — notifications icon button
84
+ * - `'documents'` — documents icon button
85
+ * - `'language'` — language icon button
86
+ * - `'help'` — help icon button
87
+ * - `'avatar'` — avatar button
88
+ * - `'logout'` — logout icon button
59
89
  *
60
90
  * For `breadcrumbs` and `actionButtons` items, the item's `NavAction.id` is emitted.
61
91
  */
62
92
  action = new EventEmitter();
93
+ searchIconSvg;
94
+ calendarCheckedIconSvg;
95
+ bellIconSvg;
96
+ fileTextIconSvg;
97
+ globeIconSvg;
98
+ helpIconSvg;
99
+ logOutIconSvg;
100
+ userIconSvg;
63
101
  constructor(sanitizer) {
64
102
  this.sanitizer = sanitizer;
103
+ this.searchIconSvg = this.trustedIcon('search');
104
+ this.calendarCheckedIconSvg = this.trustedIcon('calendar-check');
105
+ this.bellIconSvg = this.trustedIcon('bell');
106
+ this.fileTextIconSvg = this.trustedIcon('file-text');
107
+ this.globeIconSvg = this.trustedIcon('globe');
108
+ this.helpIconSvg = this.trustedIcon('circle-question-mark');
109
+ this.logOutIconSvg = this.trustedIcon('log-out');
110
+ this.userIconSvg = this.trustedIcon('user');
111
+ }
112
+ get isLoggedOut() {
113
+ return this.level === 'not-logged';
65
114
  }
66
115
  get isSubPage() {
67
116
  return this.level === 'sub-page';
68
117
  }
69
118
  get menuIconSvg() {
70
- return this.iconSvg(this.sidebarOpen ? 'x' : 'menu');
119
+ return this.trustedIcon(this.sidebarOpen ? 'x' : 'menu');
120
+ }
121
+ get badgeText() {
122
+ return this.notificationCount > 99 ? '99+' : `${this.notificationCount}`;
123
+ }
124
+ get notificationAriaLabel() {
125
+ return this.notificationCount > 0
126
+ ? `Notifications, ${this.notificationCount} unread`
127
+ : 'Notifications';
71
128
  }
72
129
  /**
73
- * Returns a trusted SVG for the given Lucide icon name, sized at 20 × 20.
74
- * Used in the template for dynamic icon buttons via `actionButtons`.
130
+ * Looks up a Lucide icon by name and injects explicit width/height attributes
131
+ * (20 × 20) so the SVG renders at the correct size when injected via [innerHTML].
132
+ * Angular's CSS encapsulation does not add _ngcontent attributes to dynamically
133
+ * injected content, so CSS descendant selectors targeting `svg` would not apply —
134
+ * explicit SVG attributes are the reliable solution.
75
135
  */
76
- iconSvg(name) {
136
+ trustedIcon(name) {
77
137
  const svg = (LUCIDE_ICONS[name] ?? '').replace('<svg ', '<svg width="20" height="20" ');
78
138
  return this.sanitizer.bypassSecurityTrustHtml(svg);
79
139
  }
80
140
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: HeaderNavComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
81
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: HeaderNavComponent, isStandalone: true, selector: "compsych-header-nav", inputs: { level: "level", sidebarOpen: "sidebarOpen", brandLabelAria: "brandLabelAria", brandLabel: "brandLabel", brandLabelColor: "brandLabelColor", clientLogoUrl: "clientLogoUrl", breadcrumbs: "breadcrumbs", actionButtons: "actionButtons" }, outputs: { action: "action" }, host: { attributes: { "role": "banner" } }, ngImport: i0, template: "<!-- Left: menu toggle + brand / breadcrumb -->\r\n<div class=\"compsych-hnav__left\">\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn\"\r\n [attr.aria-label]=\"sidebarOpen ? 'Close menu' : 'Open menu'\"\r\n [attr.aria-expanded]=\"sidebarOpen\"\r\n (click)=\"action.emit('menu-toggle')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"menuIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n\r\n @if (isSubPage) {\r\n <span class=\"compsych-hnav__symbol\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 25.73 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n <nav class=\"compsych-hnav__breadcrumb\" aria-label=\"Breadcrumb\">\r\n <ol role=\"list\">\r\n @for (crumb of breadcrumbs; track crumb.id; let last = $last) {\r\n <li>\r\n <span class=\"compsych-hnav__sep\" aria-hidden=\"true\">/</span>\r\n @if (last) {\r\n <span class=\"compsych-hnav__crumb compsych-hnav__crumb--current\" aria-current=\"page\">{{ crumb.label }}</span>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__crumb\" (click)=\"action.emit(crumb.id)\">{{ crumb.label }}</button>\r\n }\r\n </li>\r\n }\r\n </ol>\r\n </nav>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__brand\" [attr.aria-label]=\"brandLabelAria\" (click)=\"action.emit('logo')\">\r\n @if (clientLogoUrl) {\r\n <img [src]=\"clientLogoUrl\" class=\"compsych-hnav__logo\" [attr.aria-label]=\"brandLabelAria\" alt=\"\">\r\n } @else {\r\n <svg class=\"compsych-hnav__logo\" role=\"img\" [attr.aria-label]=\"brandLabelAria\" viewBox=\"0 0 118 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n <path d=\"M100.224 10.1401C99.6034 10.1778 99.2832 10.4202 98.9648 11.1655L95.2646 20.0396C94.401 22.0893 93.2696 23.0217 92.0479 23.1187C90.1758 23.2669 89.8026 22.2909 90.001 21.8384C90.1891 21.4101 90.7857 21.432 91.376 21.688C92.9483 22.3923 94.1901 21.1819 94.7578 19.9478L95.0771 19.1646L91.7148 11.1675C91.3769 10.4225 91.0572 10.1795 90.457 10.1431V9.88135H94.4385V10.1431C93.5556 10.1807 93.1605 10.5339 93.4238 11.1489L95.8848 17.2085L98.4014 11.1694C98.6648 10.5356 98.3066 10.1804 97.4805 10.144V9.87939H100.224V10.1401ZM42.1875 6.48486C44.4823 6.48486 46.2325 7.53169 46.7402 9.23096L46.7695 9.32764C46.9127 9.82287 46.5881 10.3309 46.0771 10.4155C45.6244 10.4908 45.1893 10.2032 45.0869 9.75928V9.75439C44.6901 8.07409 43.4871 6.99187 41.9629 6.9917C39.5355 6.9917 37.8613 9.25128 37.8613 12.5366C37.8615 15.8216 39.8557 18.1185 42.6963 18.1187C44.6906 18.1187 46.1534 17.0358 46.7363 15.355L47.042 15.4116C46.4028 17.9504 44.5009 19.519 41.9619 19.519L41.9609 19.5181L41.9619 19.5171L41.6426 19.5093C38.3673 19.3473 36.0548 16.7007 36.0547 13.3003C36.0547 9.34151 38.4247 6.48504 42.1875 6.48486ZM52.25 9.60107C54.8819 9.60107 56.543 11.5448 56.543 14.3667C56.543 17.4128 54.7326 19.5063 52.082 19.5063C49.4316 19.5063 47.7891 17.5624 47.7891 14.7593C47.7891 11.7132 49.6182 9.60114 52.25 9.60107ZM103.946 9.6167C105.862 9.61671 107.065 10.8474 107.252 11.8726C107.256 11.8884 107.455 12.641 106.806 12.8394C106.402 12.9623 105.897 12.7605 105.769 12.2085C105.556 11.2968 104.979 10.1392 103.702 10.1392C102.124 10.1392 101.054 11.7431 101.054 13.8667C101.054 16.4016 102.35 18.1538 104.436 18.1538C105.544 18.1537 106.615 17.576 107.29 16.3833L107.516 16.439C107.027 18.3032 105.675 19.4956 103.759 19.4956V19.4976C101.166 19.4974 99.457 17.3907 99.457 14.6685C99.4572 11.9463 101.166 9.6167 103.946 9.6167ZM86.9658 9.60693C88.5252 9.60693 90.0049 10.2854 90.3486 11.4526C90.4274 11.7209 90.4283 12.2344 90.0801 12.4097C89.7292 12.5859 89.3006 12.3929 89.1406 12.0493C88.6399 10.9763 88.1187 10.1296 86.749 10.1294C85.6223 10.1294 84.9748 10.7634 84.9746 11.6772C84.9746 12.8172 86.1343 13.2135 87.3945 13.6431C88.8752 14.1476 90.4945 14.6992 90.5352 16.562C90.5733 18.2954 88.971 19.4887 86.96 19.4888L86.959 19.4878V19.4858C85.3417 19.4872 83.9282 19.0132 83.3555 17.9028C83.1887 17.5793 83.2679 17.1326 83.5967 16.9761C83.9951 16.7863 84.3966 17.1152 84.6123 17.5005C85.1159 18.4011 86.1587 18.9632 87.0879 18.9634C88.2717 18.9634 89.2381 18.2926 89.2383 17.2681C89.2201 15.9311 87.9619 15.5017 86.6465 15.0532C85.2106 14.5636 83.7073 14.0505 83.6777 12.3091C83.6595 10.7051 84.9748 9.60708 86.9658 9.60693ZM110.52 11.6938C111.509 10.3857 112.498 9.60107 113.805 9.60107C115.447 9.60115 116.399 10.6471 116.399 12.4595V17.8608C116.399 18.6829 116.959 18.8511 117.631 18.9819V19.2437H113.618V18.9819C114.29 18.8511 114.85 18.6828 114.85 17.8608V12.5532C114.85 11.3947 114.197 10.6842 113.133 10.6841C112.218 10.6841 111.453 11.0956 110.52 12.1606V17.8608C110.52 18.6829 111.079 18.8511 111.751 18.9819V19.2437H107.72V18.9819C108.41 18.8511 108.97 18.6829 108.97 17.8608V8.04932C108.97 7.41406 108.671 7.11501 107.999 7.07764H107.552V6.81592L110.258 6.05029H110.52V11.6938ZM78.2471 6.76709L78.249 6.76807C81.1606 6.76807 83.1533 7.86945 83.1533 10.2554C83.1531 12.641 81.1615 13.7222 78.249 13.7222H77.0264V13.4331C80.258 13.4331 81.3154 11.9881 81.3105 10.2554C81.3055 8.52254 80.1832 7.29064 78.043 7.29053H76.3525L76.3506 17.562C76.3506 18.6802 76.8959 18.8865 78.0215 18.9604V19.2212H68.7891V18.9604C69.4654 18.8304 70.0283 18.6616 70.0283 17.8413V12.5474C70.0282 11.391 69.3706 10.6831 68.2998 10.6831C67.3412 10.6831 66.5705 11.1121 65.6133 12.231V17.8423C65.6133 18.6635 66.177 18.8314 66.8535 18.9614V19.2231H62.8145V18.9614C63.491 18.8314 64.0547 18.6627 64.0547 17.8423V12.5483C64.0545 11.3921 63.3963 10.6841 62.3271 10.6841C61.4441 10.6841 60.711 11.0579 59.8291 12.0083V17.8442C59.8293 18.6649 60.3921 18.8324 61.0684 18.9624V19.2241H57.0098V18.9624C57.7046 18.8316 58.2684 18.6643 58.2686 17.8442V11.5991C58.2686 10.9653 57.9682 10.6659 57.292 10.6099H56.8418V10.3481L59.5654 9.5835H59.8291V11.522C60.7869 10.31 61.7449 9.60208 63.0029 9.60205C64.4503 9.60205 65.3706 10.4033 65.5762 11.8198C66.6086 10.4401 67.6239 9.60208 68.9766 9.60205C70.629 9.60205 71.5879 10.6464 71.5879 12.4546V17.8423L71.5859 17.8403C71.5859 18.3871 71.8364 18.6442 72.2041 18.7935C72.5694 18.9413 73.0559 18.9637 73.4463 18.9058C74.2358 18.788 74.6386 18.4873 74.6387 17.561V8.40674C74.6386 7.32569 74.094 7.10187 72.9482 7.02686V6.76514H78.2461L78.2471 6.76709ZM51.9512 10.1245C50.4208 10.1247 49.4503 11.7317 49.4502 14.0112C49.4502 16.1043 50.2529 18.9829 52.3994 18.9829C53.9487 18.9829 54.9004 17.3567 54.9004 15.0581C54.9004 13.0024 54.0791 10.1245 51.9512 10.1245Z\" fill=\"currentColor\"/>\r\n </svg>\r\n }\r\n @if (brandLabel) {\r\n <span class=\"compsych-hnav__brand-label\" [attr.aria-label]=\"brandLabelAria\" [style.color]=\"brandLabelColor\">{{ brandLabel }}</span>\r\n }\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Right: actions -->\r\n<div class=\"compsych-hnav__actions\">\r\n @for (btn of actionButtons; track btn.id) {\r\n @if (btn.variant.endsWith('-icon')) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn\" [attr.aria-label]=\"btn.label ?? btn.id\" (click)=\"action.emit(btn.id)\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"iconSvg(btn.icon!)\" aria-hidden=\"true\"></span>\r\n </button>\r\n } @else {\r\n <compsych-button [variant]=\"btn.variant\" size=\"medium\" [label]=\"btn.label ?? ''\" (click)=\"action.emit(btn.id)\"></compsych-button>\r\n }\r\n }\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-16);height:4rem;padding:0 var(--spacing-padding-sys-padding-24);background:var(--surface-surface-container-sys-surface-container-lowest);border-bottom:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);box-sizing:border-box;font-family:var(--label-medium-sys-font-family);container-type:inline-size}.compsych-hnav__left{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);min-width:0;flex:1 1 auto}.compsych-hnav__brand{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);padding:0;border:0;background:transparent;color:var(--surface-surface-sys-on-surface);cursor:pointer;min-width:0}.compsych-hnav__brand:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.25rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__logo{display:block;height:1.5rem;width:auto;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__brand-label{border-left:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-fixed);padding-left:var(--spacing-padding-sys-padding-6);margin-top:var(--spacing-padding-sys-padding-4);line-height:1.5;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);font-weight:var(--label-medium-sys-font-weight-emphasized);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.compsych-hnav__symbol{display:inline-flex;align-items:center;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__symbol svg{display:block;height:1.5rem;width:auto}.compsych-hnav__breadcrumb{min-width:0;overflow:hidden}.compsych-hnav__breadcrumb ol{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__breadcrumb li{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__sep{color:var(--outline-sys-outline-fixed);font-size:var(--label-medium-sys-font-size)}.compsych-hnav__crumb{padding:0;border:0;background:transparent;font-family:inherit;font-size:var(--label-medium-sys-font-size);font-weight:500;color:var(--surface-surface-sys-on-surface-variant);white-space:nowrap;cursor:pointer}.compsych-hnav__crumb:hover{color:var(--surface-surface-sys-on-surface)}.compsych-hnav__crumb:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__crumb--current{color:var(--surface-surface-sys-on-surface);overflow:hidden;text-overflow:ellipsis;cursor:default}.compsych-hnav__actions{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);flex-shrink:0}.compsych-hnav__icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;box-sizing:border-box;padding:0;border:0;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface-variant);cursor:pointer;flex-shrink:0;transition:background-color .12s ease-out,color .12s ease-out}.compsych-hnav__icon-btn:hover{background:var(--surface-surface-container-sys-surface-container-high);color:var(--surface-surface-sys-on-surface)}.compsych-hnav__icon-btn:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem}.compsych-hnav__icon{display:flex;align-items:center;justify-content:center}@container (max-width: 40rem){.compsych-hnav__breadcrumb{display:none}}@media(max-width:40rem){:host{height:3.5rem;padding:0 var(--spacing-padding-sys-padding-16);gap:var(--spacing-padding-sys-padding-8)}.compsych-hnav__logo{height:1.25rem}.compsych-hnav__symbol svg{height:1.25rem;width:auto}}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "compsych-button", inputs: ["label", "variant", "size", "icon", "iconOnly", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
141
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: HeaderNavComponent, isStandalone: true, selector: "compsych-header-nav", inputs: { level: "level", sidebarOpen: "sidebarOpen", showMenuToggle: "showMenuToggle", brandLabelAria: "brandLabelAria", brandLabel: "brandLabel", brandLabelColor: "brandLabelColor", clientLogoUrl: "clientLogoUrl", breadcrumbs: "breadcrumbs", notificationCount: "notificationCount", avatarInitials: "avatarInitials", showSearch: "showSearch", showCalendarChecked: "showCalendarChecked", showNotifications: "showNotifications", showDocuments: "showDocuments", showAvatar: "showAvatar", showLanguage: "showLanguage", showHelp: "showHelp", showLogout: "showLogout", actionButtons: "actionButtons" }, outputs: { action: "action" }, host: { attributes: { "role": "banner" } }, ngImport: i0, template: "<!-- Left: menu toggle + brand / breadcrumb -->\r\n<div class=\"compsych-hnav__left\">\r\n @if (showMenuToggle) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn\"\r\n [attr.aria-label]=\"sidebarOpen ? 'Close menu' : 'Open menu'\"\r\n [attr.aria-expanded]=\"sidebarOpen\"\r\n (click)=\"action.emit('menu-toggle')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"menuIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n\r\n @if (isSubPage) {\r\n <span class=\"compsych-hnav__symbol\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 25.73 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n <nav class=\"compsych-hnav__breadcrumb\" aria-label=\"Breadcrumb\">\r\n <ol role=\"list\">\r\n @for (crumb of breadcrumbs; track crumb.id; let last = $last) {\r\n <li>\r\n <span class=\"compsych-hnav__sep\" aria-hidden=\"true\">/</span>\r\n @if (last) {\r\n <span class=\"compsych-hnav__crumb compsych-hnav__crumb--current\" aria-current=\"page\">{{ crumb.label }}</span>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__crumb\" (click)=\"action.emit(crumb.id)\">{{ crumb.label }}</button>\r\n }\r\n </li>\r\n }\r\n </ol>\r\n </nav>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__brand\" [attr.aria-label]=\"brandLabelAria\" (click)=\"action.emit('logo')\">\r\n @if (clientLogoUrl) {\r\n <img [src]=\"clientLogoUrl\" class=\"compsych-hnav__logo\" [attr.aria-label]=\"brandLabelAria\" alt=\"\">\r\n } @else {\r\n <svg class=\"compsych-hnav__logo\" role=\"img\" [attr.aria-label]=\"brandLabelAria\" viewBox=\"0 0 118 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n <path d=\"M100.224 10.1401C99.6034 10.1778 99.2832 10.4202 98.9648 11.1655L95.2646 20.0396C94.401 22.0893 93.2696 23.0217 92.0479 23.1187C90.1758 23.2669 89.8026 22.2909 90.001 21.8384C90.1891 21.4101 90.7857 21.432 91.376 21.688C92.9483 22.3923 94.1901 21.1819 94.7578 19.9478L95.0771 19.1646L91.7148 11.1675C91.3769 10.4225 91.0572 10.1795 90.457 10.1431V9.88135H94.4385V10.1431C93.5556 10.1807 93.1605 10.5339 93.4238 11.1489L95.8848 17.2085L98.4014 11.1694C98.6648 10.5356 98.3066 10.1804 97.4805 10.144V9.87939H100.224V10.1401ZM42.1875 6.48486C44.4823 6.48486 46.2325 7.53169 46.7402 9.23096L46.7695 9.32764C46.9127 9.82287 46.5881 10.3309 46.0771 10.4155C45.6244 10.4908 45.1893 10.2032 45.0869 9.75928V9.75439C44.6901 8.07409 43.4871 6.99187 41.9629 6.9917C39.5355 6.9917 37.8613 9.25128 37.8613 12.5366C37.8615 15.8216 39.8557 18.1185 42.6963 18.1187C44.6906 18.1187 46.1534 17.0358 46.7363 15.355L47.042 15.4116C46.4028 17.9504 44.5009 19.519 41.9619 19.519L41.9609 19.5181L41.9619 19.5171L41.6426 19.5093C38.3673 19.3473 36.0548 16.7007 36.0547 13.3003C36.0547 9.34151 38.4247 6.48504 42.1875 6.48486ZM52.25 9.60107C54.8819 9.60107 56.543 11.5448 56.543 14.3667C56.543 17.4128 54.7326 19.5063 52.082 19.5063C49.4316 19.5063 47.7891 17.5624 47.7891 14.7593C47.7891 11.7132 49.6182 9.60114 52.25 9.60107ZM103.946 9.6167C105.862 9.61671 107.065 10.8474 107.252 11.8726C107.256 11.8884 107.455 12.641 106.806 12.8394C106.402 12.9623 105.897 12.7605 105.769 12.2085C105.556 11.2968 104.979 10.1392 103.702 10.1392C102.124 10.1392 101.054 11.7431 101.054 13.8667C101.054 16.4016 102.35 18.1538 104.436 18.1538C105.544 18.1537 106.615 17.576 107.29 16.3833L107.516 16.439C107.027 18.3032 105.675 19.4956 103.759 19.4956V19.4976C101.166 19.4974 99.457 17.3907 99.457 14.6685C99.4572 11.9463 101.166 9.6167 103.946 9.6167ZM86.9658 9.60693C88.5252 9.60693 90.0049 10.2854 90.3486 11.4526C90.4274 11.7209 90.4283 12.2344 90.0801 12.4097C89.7292 12.5859 89.3006 12.3929 89.1406 12.0493C88.6399 10.9763 88.1187 10.1296 86.749 10.1294C85.6223 10.1294 84.9748 10.7634 84.9746 11.6772C84.9746 12.8172 86.1343 13.2135 87.3945 13.6431C88.8752 14.1476 90.4945 14.6992 90.5352 16.562C90.5733 18.2954 88.971 19.4887 86.96 19.4888L86.959 19.4878V19.4858C85.3417 19.4872 83.9282 19.0132 83.3555 17.9028C83.1887 17.5793 83.2679 17.1326 83.5967 16.9761C83.9951 16.7863 84.3966 17.1152 84.6123 17.5005C85.1159 18.4011 86.1587 18.9632 87.0879 18.9634C88.2717 18.9634 89.2381 18.2926 89.2383 17.2681C89.2201 15.9311 87.9619 15.5017 86.6465 15.0532C85.2106 14.5636 83.7073 14.0505 83.6777 12.3091C83.6595 10.7051 84.9748 9.60708 86.9658 9.60693ZM110.52 11.6938C111.509 10.3857 112.498 9.60107 113.805 9.60107C115.447 9.60115 116.399 10.6471 116.399 12.4595V17.8608C116.399 18.6829 116.959 18.8511 117.631 18.9819V19.2437H113.618V18.9819C114.29 18.8511 114.85 18.6828 114.85 17.8608V12.5532C114.85 11.3947 114.197 10.6842 113.133 10.6841C112.218 10.6841 111.453 11.0956 110.52 12.1606V17.8608C110.52 18.6829 111.079 18.8511 111.751 18.9819V19.2437H107.72V18.9819C108.41 18.8511 108.97 18.6829 108.97 17.8608V8.04932C108.97 7.41406 108.671 7.11501 107.999 7.07764H107.552V6.81592L110.258 6.05029H110.52V11.6938ZM78.2471 6.76709L78.249 6.76807C81.1606 6.76807 83.1533 7.86945 83.1533 10.2554C83.1531 12.641 81.1615 13.7222 78.249 13.7222H77.0264V13.4331C80.258 13.4331 81.3154 11.9881 81.3105 10.2554C81.3055 8.52254 80.1832 7.29064 78.043 7.29053H76.3525L76.3506 17.562C76.3506 18.6802 76.8959 18.8865 78.0215 18.9604V19.2212H68.7891V18.9604C69.4654 18.8304 70.0283 18.6616 70.0283 17.8413V12.5474C70.0282 11.391 69.3706 10.6831 68.2998 10.6831C67.3412 10.6831 66.5705 11.1121 65.6133 12.231V17.8423C65.6133 18.6635 66.177 18.8314 66.8535 18.9614V19.2231H62.8145V18.9614C63.491 18.8314 64.0547 18.6627 64.0547 17.8423V12.5483C64.0545 11.3921 63.3963 10.6841 62.3271 10.6841C61.4441 10.6841 60.711 11.0579 59.8291 12.0083V17.8442C59.8293 18.6649 60.3921 18.8324 61.0684 18.9624V19.2241H57.0098V18.9624C57.7046 18.8316 58.2684 18.6643 58.2686 17.8442V11.5991C58.2686 10.9653 57.9682 10.6659 57.292 10.6099H56.8418V10.3481L59.5654 9.5835H59.8291V11.522C60.7869 10.31 61.7449 9.60208 63.0029 9.60205C64.4503 9.60205 65.3706 10.4033 65.5762 11.8198C66.6086 10.4401 67.6239 9.60208 68.9766 9.60205C70.629 9.60205 71.5879 10.6464 71.5879 12.4546V17.8423L71.5859 17.8403C71.5859 18.3871 71.8364 18.6442 72.2041 18.7935C72.5694 18.9413 73.0559 18.9637 73.4463 18.9058C74.2358 18.788 74.6386 18.4873 74.6387 17.561V8.40674C74.6386 7.32569 74.094 7.10187 72.9482 7.02686V6.76514H78.2461L78.2471 6.76709ZM51.9512 10.1245C50.4208 10.1247 49.4503 11.7317 49.4502 14.0112C49.4502 16.1043 50.2529 18.9829 52.3994 18.9829C53.9487 18.9829 54.9004 17.3567 54.9004 15.0581C54.9004 13.0024 54.0791 10.1245 51.9512 10.1245Z\" fill=\"currentColor\"/>\r\n </svg>\r\n }\r\n @if (brandLabel) {\r\n <span class=\"compsych-hnav__brand-label\" [attr.aria-label]=\"brandLabelAria\" [style.color]=\"brandLabelColor\">{{ brandLabel }}</span>\r\n }\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Right: actions -->\r\n<div class=\"compsych-hnav__actions\">\r\n @if (isLoggedOut) {\r\n @if (showLanguage) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Language\" (click)=\"action.emit('language')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"globeIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showHelp) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Help\" (click)=\"action.emit('help')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"helpIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (actionButtons.length) {\r\n <div class=\"compsych-hnav__action-btns\">\r\n @for (btn of actionButtons; track btn.id) {\r\n <compsych-button [variant]=\"btn.variant ?? 'filled'\" size=\"medium\" [label]=\"btn.label\" (click)=\"action.emit(btn.id)\"></compsych-button>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (showSearch) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Search\" (click)=\"action.emit('search')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"searchIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showCalendarChecked) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Calendar\" (click)=\"action.emit('calendar-checked')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"calendarCheckedIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showNotifications) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn compsych-hnav__overflow-aux\"\r\n [attr.aria-label]=\"notificationAriaLabel\"\r\n (click)=\"action.emit('notifications')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"bellIconSvg\" aria-hidden=\"true\"></span>\r\n @if (notificationCount > 0) {\r\n <span class=\"compsych-hnav__badge\" aria-hidden=\"true\">{{ badgeText }}</span>\r\n }\r\n </button>\r\n }\r\n @if (showDocuments) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn compsych-hnav__overflow-aux\"\r\n aria-label=\"Documents\"\r\n (click)=\"action.emit('documents')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"fileTextIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showLanguage) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Language\" (click)=\"action.emit('language')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"globeIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (actionButtons.length) {\r\n <div class=\"compsych-hnav__action-btns\">\r\n @for (btn of actionButtons; track btn.id) {\r\n <compsych-button\r\n [variant]=\"btn.variant ?? 'filled'\"\r\n size=\"medium\"\r\n [label]=\"btn.label\"\r\n (click)=\"action.emit(btn.id)\"\r\n ></compsych-button>\r\n }\r\n </div>\r\n }\r\n @if (showAvatar) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__avatar compsych-hnav__overflow-core\"\r\n [attr.aria-label]=\"avatarInitials ? 'Account: ' + avatarInitials : 'Account'\"\r\n (click)=\"action.emit('avatar')\"\r\n >\r\n @if (avatarInitials) {\r\n {{ avatarInitials }}\r\n } @else {\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"userIconSvg\" aria-hidden=\"true\"></span>\r\n }\r\n </button>\r\n }\r\n @if (showLogout) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn\" aria-label=\"Logout\" (click)=\"action.emit('logout')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"logOutIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n }\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-16);height:4rem;padding:0 var(--spacing-padding-sys-padding-24);background:var(--surface-surface-container-sys-surface-container-lowest);border-bottom:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);box-sizing:border-box;font-family:var(--label-medium-sys-font-family);container-type:inline-size}.compsych-hnav__left{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);min-width:0;flex:1 1 auto}.compsych-hnav__brand{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);padding:0;border:0;background:transparent;color:var(--surface-surface-sys-on-surface);cursor:pointer;min-width:0}.compsych-hnav__brand:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.25rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__logo{display:block;height:1.5rem;width:auto;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__brand-label{border-left:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-fixed);padding-left:var(--spacing-padding-sys-padding-6);margin-top:var(--spacing-padding-sys-padding-6);line-height:1.5;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);font-weight:var(--label-medium-sys-font-weight-emphasized);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.compsych-hnav__symbol{display:inline-flex;align-items:center;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__symbol svg{display:block;height:1.5rem;width:auto}.compsych-hnav__breadcrumb{min-width:0;overflow:hidden}.compsych-hnav__breadcrumb ol{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__breadcrumb li{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__sep{color:var(--outline-sys-outline-fixed);font-size:var(--label-medium-sys-font-size)}.compsych-hnav__crumb{padding:0;border:0;background:transparent;font-family:inherit;font-size:var(--label-medium-sys-font-size);font-weight:500;color:var(--surface-surface-sys-on-surface-variant);white-space:nowrap;cursor:pointer}.compsych-hnav__crumb:hover{color:var(--surface-surface-sys-on-surface)}.compsych-hnav__crumb:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__crumb--current{color:var(--surface-surface-sys-on-surface);overflow:hidden;text-overflow:ellipsis;cursor:default}.compsych-hnav__actions{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);flex-shrink:0}.compsych-hnav__icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;box-sizing:border-box;padding:0;border:0;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface-variant);cursor:pointer;flex-shrink:0;transition:background-color .12s ease-out,color .12s ease-out}.compsych-hnav__icon-btn:hover{background:var(--surface-surface-container-sys-surface-container-high);color:var(--surface-surface-sys-on-surface)}.compsych-hnav__icon-btn:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem}.compsych-hnav__icon{display:flex;align-items:center;justify-content:center}.compsych-hnav__badge{position:absolute;top:.125rem;right:.125rem;min-width:1rem;height:1rem;padding:0 .25rem;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sys-radius-full);background:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary);font-size:.625rem;line-height:1;font-weight:600;box-shadow:0 0 0 .125rem var(--surface-surface-container-sys-surface-container-lowest)}.compsych-hnav__avatar{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;box-sizing:border-box;padding:0;border:0;border-radius:var(--border-radius-sys-radius-full);background:var(--add-on-primary-fixed-sys-primary-fixed-dim);color:var(--add-on-primary-fixed-sys-on-primary-fixed);font-size:var(--label-small-sys-font-size);font-weight:600;letter-spacing:.02em;cursor:pointer;flex-shrink:0}.compsych-hnav__avatar:hover{filter:brightness(.97)}.compsych-hnav__avatar:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem}.compsych-hnav__action-btns{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}@container (max-width: 45rem){.compsych-hnav__action-btns{display:none}}@container (max-width: 40rem){.compsych-hnav__breadcrumb{display:none}}@container (max-width: 30rem){.compsych-hnav__overflow-aux{display:none}}@container (max-width: 25rem){.compsych-hnav__overflow-core{display:none}}@media(max-width:40rem){:host{height:3.5rem;padding:0 var(--spacing-padding-sys-padding-16);gap:var(--spacing-padding-sys-padding-8)}.compsych-hnav__logo{height:1.25rem}.compsych-hnav__symbol svg{height:1.25rem;width:auto}}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "compsych-button", inputs: ["label", "variant", "size", "icon", "iconOnly", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
82
142
  }
83
143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: HeaderNavComponent, decorators: [{
84
144
  type: Component,
85
- args: [{ selector: 'compsych-header-nav', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent], host: { role: 'banner' }, template: "<!-- Left: menu toggle + brand / breadcrumb -->\r\n<div class=\"compsych-hnav__left\">\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn\"\r\n [attr.aria-label]=\"sidebarOpen ? 'Close menu' : 'Open menu'\"\r\n [attr.aria-expanded]=\"sidebarOpen\"\r\n (click)=\"action.emit('menu-toggle')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"menuIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n\r\n @if (isSubPage) {\r\n <span class=\"compsych-hnav__symbol\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 25.73 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n <nav class=\"compsych-hnav__breadcrumb\" aria-label=\"Breadcrumb\">\r\n <ol role=\"list\">\r\n @for (crumb of breadcrumbs; track crumb.id; let last = $last) {\r\n <li>\r\n <span class=\"compsych-hnav__sep\" aria-hidden=\"true\">/</span>\r\n @if (last) {\r\n <span class=\"compsych-hnav__crumb compsych-hnav__crumb--current\" aria-current=\"page\">{{ crumb.label }}</span>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__crumb\" (click)=\"action.emit(crumb.id)\">{{ crumb.label }}</button>\r\n }\r\n </li>\r\n }\r\n </ol>\r\n </nav>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__brand\" [attr.aria-label]=\"brandLabelAria\" (click)=\"action.emit('logo')\">\r\n @if (clientLogoUrl) {\r\n <img [src]=\"clientLogoUrl\" class=\"compsych-hnav__logo\" [attr.aria-label]=\"brandLabelAria\" alt=\"\">\r\n } @else {\r\n <svg class=\"compsych-hnav__logo\" role=\"img\" [attr.aria-label]=\"brandLabelAria\" viewBox=\"0 0 118 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n <path d=\"M100.224 10.1401C99.6034 10.1778 99.2832 10.4202 98.9648 11.1655L95.2646 20.0396C94.401 22.0893 93.2696 23.0217 92.0479 23.1187C90.1758 23.2669 89.8026 22.2909 90.001 21.8384C90.1891 21.4101 90.7857 21.432 91.376 21.688C92.9483 22.3923 94.1901 21.1819 94.7578 19.9478L95.0771 19.1646L91.7148 11.1675C91.3769 10.4225 91.0572 10.1795 90.457 10.1431V9.88135H94.4385V10.1431C93.5556 10.1807 93.1605 10.5339 93.4238 11.1489L95.8848 17.2085L98.4014 11.1694C98.6648 10.5356 98.3066 10.1804 97.4805 10.144V9.87939H100.224V10.1401ZM42.1875 6.48486C44.4823 6.48486 46.2325 7.53169 46.7402 9.23096L46.7695 9.32764C46.9127 9.82287 46.5881 10.3309 46.0771 10.4155C45.6244 10.4908 45.1893 10.2032 45.0869 9.75928V9.75439C44.6901 8.07409 43.4871 6.99187 41.9629 6.9917C39.5355 6.9917 37.8613 9.25128 37.8613 12.5366C37.8615 15.8216 39.8557 18.1185 42.6963 18.1187C44.6906 18.1187 46.1534 17.0358 46.7363 15.355L47.042 15.4116C46.4028 17.9504 44.5009 19.519 41.9619 19.519L41.9609 19.5181L41.9619 19.5171L41.6426 19.5093C38.3673 19.3473 36.0548 16.7007 36.0547 13.3003C36.0547 9.34151 38.4247 6.48504 42.1875 6.48486ZM52.25 9.60107C54.8819 9.60107 56.543 11.5448 56.543 14.3667C56.543 17.4128 54.7326 19.5063 52.082 19.5063C49.4316 19.5063 47.7891 17.5624 47.7891 14.7593C47.7891 11.7132 49.6182 9.60114 52.25 9.60107ZM103.946 9.6167C105.862 9.61671 107.065 10.8474 107.252 11.8726C107.256 11.8884 107.455 12.641 106.806 12.8394C106.402 12.9623 105.897 12.7605 105.769 12.2085C105.556 11.2968 104.979 10.1392 103.702 10.1392C102.124 10.1392 101.054 11.7431 101.054 13.8667C101.054 16.4016 102.35 18.1538 104.436 18.1538C105.544 18.1537 106.615 17.576 107.29 16.3833L107.516 16.439C107.027 18.3032 105.675 19.4956 103.759 19.4956V19.4976C101.166 19.4974 99.457 17.3907 99.457 14.6685C99.4572 11.9463 101.166 9.6167 103.946 9.6167ZM86.9658 9.60693C88.5252 9.60693 90.0049 10.2854 90.3486 11.4526C90.4274 11.7209 90.4283 12.2344 90.0801 12.4097C89.7292 12.5859 89.3006 12.3929 89.1406 12.0493C88.6399 10.9763 88.1187 10.1296 86.749 10.1294C85.6223 10.1294 84.9748 10.7634 84.9746 11.6772C84.9746 12.8172 86.1343 13.2135 87.3945 13.6431C88.8752 14.1476 90.4945 14.6992 90.5352 16.562C90.5733 18.2954 88.971 19.4887 86.96 19.4888L86.959 19.4878V19.4858C85.3417 19.4872 83.9282 19.0132 83.3555 17.9028C83.1887 17.5793 83.2679 17.1326 83.5967 16.9761C83.9951 16.7863 84.3966 17.1152 84.6123 17.5005C85.1159 18.4011 86.1587 18.9632 87.0879 18.9634C88.2717 18.9634 89.2381 18.2926 89.2383 17.2681C89.2201 15.9311 87.9619 15.5017 86.6465 15.0532C85.2106 14.5636 83.7073 14.0505 83.6777 12.3091C83.6595 10.7051 84.9748 9.60708 86.9658 9.60693ZM110.52 11.6938C111.509 10.3857 112.498 9.60107 113.805 9.60107C115.447 9.60115 116.399 10.6471 116.399 12.4595V17.8608C116.399 18.6829 116.959 18.8511 117.631 18.9819V19.2437H113.618V18.9819C114.29 18.8511 114.85 18.6828 114.85 17.8608V12.5532C114.85 11.3947 114.197 10.6842 113.133 10.6841C112.218 10.6841 111.453 11.0956 110.52 12.1606V17.8608C110.52 18.6829 111.079 18.8511 111.751 18.9819V19.2437H107.72V18.9819C108.41 18.8511 108.97 18.6829 108.97 17.8608V8.04932C108.97 7.41406 108.671 7.11501 107.999 7.07764H107.552V6.81592L110.258 6.05029H110.52V11.6938ZM78.2471 6.76709L78.249 6.76807C81.1606 6.76807 83.1533 7.86945 83.1533 10.2554C83.1531 12.641 81.1615 13.7222 78.249 13.7222H77.0264V13.4331C80.258 13.4331 81.3154 11.9881 81.3105 10.2554C81.3055 8.52254 80.1832 7.29064 78.043 7.29053H76.3525L76.3506 17.562C76.3506 18.6802 76.8959 18.8865 78.0215 18.9604V19.2212H68.7891V18.9604C69.4654 18.8304 70.0283 18.6616 70.0283 17.8413V12.5474C70.0282 11.391 69.3706 10.6831 68.2998 10.6831C67.3412 10.6831 66.5705 11.1121 65.6133 12.231V17.8423C65.6133 18.6635 66.177 18.8314 66.8535 18.9614V19.2231H62.8145V18.9614C63.491 18.8314 64.0547 18.6627 64.0547 17.8423V12.5483C64.0545 11.3921 63.3963 10.6841 62.3271 10.6841C61.4441 10.6841 60.711 11.0579 59.8291 12.0083V17.8442C59.8293 18.6649 60.3921 18.8324 61.0684 18.9624V19.2241H57.0098V18.9624C57.7046 18.8316 58.2684 18.6643 58.2686 17.8442V11.5991C58.2686 10.9653 57.9682 10.6659 57.292 10.6099H56.8418V10.3481L59.5654 9.5835H59.8291V11.522C60.7869 10.31 61.7449 9.60208 63.0029 9.60205C64.4503 9.60205 65.3706 10.4033 65.5762 11.8198C66.6086 10.4401 67.6239 9.60208 68.9766 9.60205C70.629 9.60205 71.5879 10.6464 71.5879 12.4546V17.8423L71.5859 17.8403C71.5859 18.3871 71.8364 18.6442 72.2041 18.7935C72.5694 18.9413 73.0559 18.9637 73.4463 18.9058C74.2358 18.788 74.6386 18.4873 74.6387 17.561V8.40674C74.6386 7.32569 74.094 7.10187 72.9482 7.02686V6.76514H78.2461L78.2471 6.76709ZM51.9512 10.1245C50.4208 10.1247 49.4503 11.7317 49.4502 14.0112C49.4502 16.1043 50.2529 18.9829 52.3994 18.9829C53.9487 18.9829 54.9004 17.3567 54.9004 15.0581C54.9004 13.0024 54.0791 10.1245 51.9512 10.1245Z\" fill=\"currentColor\"/>\r\n </svg>\r\n }\r\n @if (brandLabel) {\r\n <span class=\"compsych-hnav__brand-label\" [attr.aria-label]=\"brandLabelAria\" [style.color]=\"brandLabelColor\">{{ brandLabel }}</span>\r\n }\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Right: actions -->\r\n<div class=\"compsych-hnav__actions\">\r\n @for (btn of actionButtons; track btn.id) {\r\n @if (btn.variant.endsWith('-icon')) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn\" [attr.aria-label]=\"btn.label ?? btn.id\" (click)=\"action.emit(btn.id)\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"iconSvg(btn.icon!)\" aria-hidden=\"true\"></span>\r\n </button>\r\n } @else {\r\n <compsych-button [variant]=\"btn.variant\" size=\"medium\" [label]=\"btn.label ?? ''\" (click)=\"action.emit(btn.id)\"></compsych-button>\r\n }\r\n }\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-16);height:4rem;padding:0 var(--spacing-padding-sys-padding-24);background:var(--surface-surface-container-sys-surface-container-lowest);border-bottom:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);box-sizing:border-box;font-family:var(--label-medium-sys-font-family);container-type:inline-size}.compsych-hnav__left{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);min-width:0;flex:1 1 auto}.compsych-hnav__brand{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);padding:0;border:0;background:transparent;color:var(--surface-surface-sys-on-surface);cursor:pointer;min-width:0}.compsych-hnav__brand:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.25rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__logo{display:block;height:1.5rem;width:auto;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__brand-label{border-left:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-fixed);padding-left:var(--spacing-padding-sys-padding-6);margin-top:var(--spacing-padding-sys-padding-4);line-height:1.5;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);font-weight:var(--label-medium-sys-font-weight-emphasized);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.compsych-hnav__symbol{display:inline-flex;align-items:center;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__symbol svg{display:block;height:1.5rem;width:auto}.compsych-hnav__breadcrumb{min-width:0;overflow:hidden}.compsych-hnav__breadcrumb ol{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__breadcrumb li{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__sep{color:var(--outline-sys-outline-fixed);font-size:var(--label-medium-sys-font-size)}.compsych-hnav__crumb{padding:0;border:0;background:transparent;font-family:inherit;font-size:var(--label-medium-sys-font-size);font-weight:500;color:var(--surface-surface-sys-on-surface-variant);white-space:nowrap;cursor:pointer}.compsych-hnav__crumb:hover{color:var(--surface-surface-sys-on-surface)}.compsych-hnav__crumb:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__crumb--current{color:var(--surface-surface-sys-on-surface);overflow:hidden;text-overflow:ellipsis;cursor:default}.compsych-hnav__actions{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);flex-shrink:0}.compsych-hnav__icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;box-sizing:border-box;padding:0;border:0;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface-variant);cursor:pointer;flex-shrink:0;transition:background-color .12s ease-out,color .12s ease-out}.compsych-hnav__icon-btn:hover{background:var(--surface-surface-container-sys-surface-container-high);color:var(--surface-surface-sys-on-surface)}.compsych-hnav__icon-btn:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem}.compsych-hnav__icon{display:flex;align-items:center;justify-content:center}@container (max-width: 40rem){.compsych-hnav__breadcrumb{display:none}}@media(max-width:40rem){:host{height:3.5rem;padding:0 var(--spacing-padding-sys-padding-16);gap:var(--spacing-padding-sys-padding-8)}.compsych-hnav__logo{height:1.25rem}.compsych-hnav__symbol svg{height:1.25rem;width:auto}}\n"] }]
145
+ args: [{ selector: 'compsych-header-nav', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent], host: { role: 'banner' }, template: "<!-- Left: menu toggle + brand / breadcrumb -->\r\n<div class=\"compsych-hnav__left\">\r\n @if (showMenuToggle) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn\"\r\n [attr.aria-label]=\"sidebarOpen ? 'Close menu' : 'Open menu'\"\r\n [attr.aria-expanded]=\"sidebarOpen\"\r\n (click)=\"action.emit('menu-toggle')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"menuIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n\r\n @if (isSubPage) {\r\n <span class=\"compsych-hnav__symbol\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 25.73 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n <nav class=\"compsych-hnav__breadcrumb\" aria-label=\"Breadcrumb\">\r\n <ol role=\"list\">\r\n @for (crumb of breadcrumbs; track crumb.id; let last = $last) {\r\n <li>\r\n <span class=\"compsych-hnav__sep\" aria-hidden=\"true\">/</span>\r\n @if (last) {\r\n <span class=\"compsych-hnav__crumb compsych-hnav__crumb--current\" aria-current=\"page\">{{ crumb.label }}</span>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__crumb\" (click)=\"action.emit(crumb.id)\">{{ crumb.label }}</button>\r\n }\r\n </li>\r\n }\r\n </ol>\r\n </nav>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__brand\" [attr.aria-label]=\"brandLabelAria\" (click)=\"action.emit('logo')\">\r\n @if (clientLogoUrl) {\r\n <img [src]=\"clientLogoUrl\" class=\"compsych-hnav__logo\" [attr.aria-label]=\"brandLabelAria\" alt=\"\">\r\n } @else {\r\n <svg class=\"compsych-hnav__logo\" role=\"img\" [attr.aria-label]=\"brandLabelAria\" viewBox=\"0 0 118 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n <path d=\"M100.224 10.1401C99.6034 10.1778 99.2832 10.4202 98.9648 11.1655L95.2646 20.0396C94.401 22.0893 93.2696 23.0217 92.0479 23.1187C90.1758 23.2669 89.8026 22.2909 90.001 21.8384C90.1891 21.4101 90.7857 21.432 91.376 21.688C92.9483 22.3923 94.1901 21.1819 94.7578 19.9478L95.0771 19.1646L91.7148 11.1675C91.3769 10.4225 91.0572 10.1795 90.457 10.1431V9.88135H94.4385V10.1431C93.5556 10.1807 93.1605 10.5339 93.4238 11.1489L95.8848 17.2085L98.4014 11.1694C98.6648 10.5356 98.3066 10.1804 97.4805 10.144V9.87939H100.224V10.1401ZM42.1875 6.48486C44.4823 6.48486 46.2325 7.53169 46.7402 9.23096L46.7695 9.32764C46.9127 9.82287 46.5881 10.3309 46.0771 10.4155C45.6244 10.4908 45.1893 10.2032 45.0869 9.75928V9.75439C44.6901 8.07409 43.4871 6.99187 41.9629 6.9917C39.5355 6.9917 37.8613 9.25128 37.8613 12.5366C37.8615 15.8216 39.8557 18.1185 42.6963 18.1187C44.6906 18.1187 46.1534 17.0358 46.7363 15.355L47.042 15.4116C46.4028 17.9504 44.5009 19.519 41.9619 19.519L41.9609 19.5181L41.9619 19.5171L41.6426 19.5093C38.3673 19.3473 36.0548 16.7007 36.0547 13.3003C36.0547 9.34151 38.4247 6.48504 42.1875 6.48486ZM52.25 9.60107C54.8819 9.60107 56.543 11.5448 56.543 14.3667C56.543 17.4128 54.7326 19.5063 52.082 19.5063C49.4316 19.5063 47.7891 17.5624 47.7891 14.7593C47.7891 11.7132 49.6182 9.60114 52.25 9.60107ZM103.946 9.6167C105.862 9.61671 107.065 10.8474 107.252 11.8726C107.256 11.8884 107.455 12.641 106.806 12.8394C106.402 12.9623 105.897 12.7605 105.769 12.2085C105.556 11.2968 104.979 10.1392 103.702 10.1392C102.124 10.1392 101.054 11.7431 101.054 13.8667C101.054 16.4016 102.35 18.1538 104.436 18.1538C105.544 18.1537 106.615 17.576 107.29 16.3833L107.516 16.439C107.027 18.3032 105.675 19.4956 103.759 19.4956V19.4976C101.166 19.4974 99.457 17.3907 99.457 14.6685C99.4572 11.9463 101.166 9.6167 103.946 9.6167ZM86.9658 9.60693C88.5252 9.60693 90.0049 10.2854 90.3486 11.4526C90.4274 11.7209 90.4283 12.2344 90.0801 12.4097C89.7292 12.5859 89.3006 12.3929 89.1406 12.0493C88.6399 10.9763 88.1187 10.1296 86.749 10.1294C85.6223 10.1294 84.9748 10.7634 84.9746 11.6772C84.9746 12.8172 86.1343 13.2135 87.3945 13.6431C88.8752 14.1476 90.4945 14.6992 90.5352 16.562C90.5733 18.2954 88.971 19.4887 86.96 19.4888L86.959 19.4878V19.4858C85.3417 19.4872 83.9282 19.0132 83.3555 17.9028C83.1887 17.5793 83.2679 17.1326 83.5967 16.9761C83.9951 16.7863 84.3966 17.1152 84.6123 17.5005C85.1159 18.4011 86.1587 18.9632 87.0879 18.9634C88.2717 18.9634 89.2381 18.2926 89.2383 17.2681C89.2201 15.9311 87.9619 15.5017 86.6465 15.0532C85.2106 14.5636 83.7073 14.0505 83.6777 12.3091C83.6595 10.7051 84.9748 9.60708 86.9658 9.60693ZM110.52 11.6938C111.509 10.3857 112.498 9.60107 113.805 9.60107C115.447 9.60115 116.399 10.6471 116.399 12.4595V17.8608C116.399 18.6829 116.959 18.8511 117.631 18.9819V19.2437H113.618V18.9819C114.29 18.8511 114.85 18.6828 114.85 17.8608V12.5532C114.85 11.3947 114.197 10.6842 113.133 10.6841C112.218 10.6841 111.453 11.0956 110.52 12.1606V17.8608C110.52 18.6829 111.079 18.8511 111.751 18.9819V19.2437H107.72V18.9819C108.41 18.8511 108.97 18.6829 108.97 17.8608V8.04932C108.97 7.41406 108.671 7.11501 107.999 7.07764H107.552V6.81592L110.258 6.05029H110.52V11.6938ZM78.2471 6.76709L78.249 6.76807C81.1606 6.76807 83.1533 7.86945 83.1533 10.2554C83.1531 12.641 81.1615 13.7222 78.249 13.7222H77.0264V13.4331C80.258 13.4331 81.3154 11.9881 81.3105 10.2554C81.3055 8.52254 80.1832 7.29064 78.043 7.29053H76.3525L76.3506 17.562C76.3506 18.6802 76.8959 18.8865 78.0215 18.9604V19.2212H68.7891V18.9604C69.4654 18.8304 70.0283 18.6616 70.0283 17.8413V12.5474C70.0282 11.391 69.3706 10.6831 68.2998 10.6831C67.3412 10.6831 66.5705 11.1121 65.6133 12.231V17.8423C65.6133 18.6635 66.177 18.8314 66.8535 18.9614V19.2231H62.8145V18.9614C63.491 18.8314 64.0547 18.6627 64.0547 17.8423V12.5483C64.0545 11.3921 63.3963 10.6841 62.3271 10.6841C61.4441 10.6841 60.711 11.0579 59.8291 12.0083V17.8442C59.8293 18.6649 60.3921 18.8324 61.0684 18.9624V19.2241H57.0098V18.9624C57.7046 18.8316 58.2684 18.6643 58.2686 17.8442V11.5991C58.2686 10.9653 57.9682 10.6659 57.292 10.6099H56.8418V10.3481L59.5654 9.5835H59.8291V11.522C60.7869 10.31 61.7449 9.60208 63.0029 9.60205C64.4503 9.60205 65.3706 10.4033 65.5762 11.8198C66.6086 10.4401 67.6239 9.60208 68.9766 9.60205C70.629 9.60205 71.5879 10.6464 71.5879 12.4546V17.8423L71.5859 17.8403C71.5859 18.3871 71.8364 18.6442 72.2041 18.7935C72.5694 18.9413 73.0559 18.9637 73.4463 18.9058C74.2358 18.788 74.6386 18.4873 74.6387 17.561V8.40674C74.6386 7.32569 74.094 7.10187 72.9482 7.02686V6.76514H78.2461L78.2471 6.76709ZM51.9512 10.1245C50.4208 10.1247 49.4503 11.7317 49.4502 14.0112C49.4502 16.1043 50.2529 18.9829 52.3994 18.9829C53.9487 18.9829 54.9004 17.3567 54.9004 15.0581C54.9004 13.0024 54.0791 10.1245 51.9512 10.1245Z\" fill=\"currentColor\"/>\r\n </svg>\r\n }\r\n @if (brandLabel) {\r\n <span class=\"compsych-hnav__brand-label\" [attr.aria-label]=\"brandLabelAria\" [style.color]=\"brandLabelColor\">{{ brandLabel }}</span>\r\n }\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Right: actions -->\r\n<div class=\"compsych-hnav__actions\">\r\n @if (isLoggedOut) {\r\n @if (showLanguage) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Language\" (click)=\"action.emit('language')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"globeIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showHelp) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Help\" (click)=\"action.emit('help')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"helpIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (actionButtons.length) {\r\n <div class=\"compsych-hnav__action-btns\">\r\n @for (btn of actionButtons; track btn.id) {\r\n <compsych-button [variant]=\"btn.variant ?? 'filled'\" size=\"medium\" [label]=\"btn.label\" (click)=\"action.emit(btn.id)\"></compsych-button>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (showSearch) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Search\" (click)=\"action.emit('search')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"searchIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showCalendarChecked) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Calendar\" (click)=\"action.emit('calendar-checked')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"calendarCheckedIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showNotifications) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn compsych-hnav__overflow-aux\"\r\n [attr.aria-label]=\"notificationAriaLabel\"\r\n (click)=\"action.emit('notifications')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"bellIconSvg\" aria-hidden=\"true\"></span>\r\n @if (notificationCount > 0) {\r\n <span class=\"compsych-hnav__badge\" aria-hidden=\"true\">{{ badgeText }}</span>\r\n }\r\n </button>\r\n }\r\n @if (showDocuments) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn compsych-hnav__overflow-aux\"\r\n aria-label=\"Documents\"\r\n (click)=\"action.emit('documents')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"fileTextIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showLanguage) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Language\" (click)=\"action.emit('language')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"globeIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (actionButtons.length) {\r\n <div class=\"compsych-hnav__action-btns\">\r\n @for (btn of actionButtons; track btn.id) {\r\n <compsych-button\r\n [variant]=\"btn.variant ?? 'filled'\"\r\n size=\"medium\"\r\n [label]=\"btn.label\"\r\n (click)=\"action.emit(btn.id)\"\r\n ></compsych-button>\r\n }\r\n </div>\r\n }\r\n @if (showAvatar) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__avatar compsych-hnav__overflow-core\"\r\n [attr.aria-label]=\"avatarInitials ? 'Account: ' + avatarInitials : 'Account'\"\r\n (click)=\"action.emit('avatar')\"\r\n >\r\n @if (avatarInitials) {\r\n {{ avatarInitials }}\r\n } @else {\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"userIconSvg\" aria-hidden=\"true\"></span>\r\n }\r\n </button>\r\n }\r\n @if (showLogout) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn\" aria-label=\"Logout\" (click)=\"action.emit('logout')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"logOutIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n }\r\n</div>\r\n", styles: [":host{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-16);height:4rem;padding:0 var(--spacing-padding-sys-padding-24);background:var(--surface-surface-container-sys-surface-container-lowest);border-bottom:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);box-sizing:border-box;font-family:var(--label-medium-sys-font-family);container-type:inline-size}.compsych-hnav__left{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);min-width:0;flex:1 1 auto}.compsych-hnav__brand{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);padding:0;border:0;background:transparent;color:var(--surface-surface-sys-on-surface);cursor:pointer;min-width:0}.compsych-hnav__brand:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.25rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__logo{display:block;height:1.5rem;width:auto;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__brand-label{border-left:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-fixed);padding-left:var(--spacing-padding-sys-padding-6);margin-top:var(--spacing-padding-sys-padding-6);line-height:1.5;font-family:var(--label-medium-sys-font-family);font-size:var(--label-medium-sys-font-size);font-weight:var(--label-medium-sys-font-weight-emphasized);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.compsych-hnav__symbol{display:inline-flex;align-items:center;color:var(--accent-primary-sys-primary-container);flex-shrink:0}.compsych-hnav__symbol svg{display:block;height:1.5rem;width:auto}.compsych-hnav__breadcrumb{min-width:0;overflow:hidden}.compsych-hnav__breadcrumb ol{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__breadcrumb li{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);min-width:0}.compsych-hnav__sep{color:var(--outline-sys-outline-fixed);font-size:var(--label-medium-sys-font-size)}.compsych-hnav__crumb{padding:0;border:0;background:transparent;font-family:inherit;font-size:var(--label-medium-sys-font-size);font-weight:500;color:var(--surface-surface-sys-on-surface-variant);white-space:nowrap;cursor:pointer}.compsych-hnav__crumb:hover{color:var(--surface-surface-sys-on-surface)}.compsych-hnav__crumb:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem;border-radius:var(--border-radius-sys-radius-xs)}.compsych-hnav__crumb--current{color:var(--surface-surface-sys-on-surface);overflow:hidden;text-overflow:ellipsis;cursor:default}.compsych-hnav__actions{display:inline-flex;align-items:center;gap:var(--spacing-padding-sys-padding-8);flex-shrink:0}.compsych-hnav__icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;box-sizing:border-box;padding:0;border:0;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface-variant);cursor:pointer;flex-shrink:0;transition:background-color .12s ease-out,color .12s ease-out}.compsych-hnav__icon-btn:hover{background:var(--surface-surface-container-sys-surface-container-high);color:var(--surface-surface-sys-on-surface)}.compsych-hnav__icon-btn:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem}.compsych-hnav__icon{display:flex;align-items:center;justify-content:center}.compsych-hnav__badge{position:absolute;top:.125rem;right:.125rem;min-width:1rem;height:1rem;padding:0 .25rem;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sys-radius-full);background:var(--accent-primary-sys-primary);color:var(--accent-primary-sys-on-primary);font-size:.625rem;line-height:1;font-weight:600;box-shadow:0 0 0 .125rem var(--surface-surface-container-sys-surface-container-lowest)}.compsych-hnav__avatar{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;box-sizing:border-box;padding:0;border:0;border-radius:var(--border-radius-sys-radius-full);background:var(--add-on-primary-fixed-sys-primary-fixed-dim);color:var(--add-on-primary-fixed-sys-on-primary-fixed);font-size:var(--label-small-sys-font-size);font-weight:600;letter-spacing:.02em;cursor:pointer;flex-shrink:0}.compsych-hnav__avatar:hover{filter:brightness(.97)}.compsych-hnav__avatar:focus-visible{outline:var(--border-width-sys-stroke-thick) solid var(--add-on-primary-fixed-sys-on-primary-fixed-variant);outline-offset:.125rem}.compsych-hnav__action-btns{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-8)}@container (max-width: 45rem){.compsych-hnav__action-btns{display:none}}@container (max-width: 40rem){.compsych-hnav__breadcrumb{display:none}}@container (max-width: 30rem){.compsych-hnav__overflow-aux{display:none}}@container (max-width: 25rem){.compsych-hnav__overflow-core{display:none}}@media(max-width:40rem){:host{height:3.5rem;padding:0 var(--spacing-padding-sys-padding-16);gap:var(--spacing-padding-sys-padding-8)}.compsych-hnav__logo{height:1.25rem}.compsych-hnav__symbol svg{height:1.25rem;width:auto}}\n"] }]
86
146
  }], ctorParameters: () => [{ type: i1.DomSanitizer }], propDecorators: { level: [{
87
147
  type: Input
88
148
  }], sidebarOpen: [{
89
149
  type: Input
150
+ }], showMenuToggle: [{
151
+ type: Input
90
152
  }], brandLabelAria: [{
91
153
  type: Input
92
154
  }], brandLabel: [{
@@ -97,6 +159,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
97
159
  type: Input
98
160
  }], breadcrumbs: [{
99
161
  type: Input
162
+ }], notificationCount: [{
163
+ type: Input
164
+ }], avatarInitials: [{
165
+ type: Input
166
+ }], showSearch: [{
167
+ type: Input
168
+ }], showCalendarChecked: [{
169
+ type: Input
170
+ }], showNotifications: [{
171
+ type: Input
172
+ }], showDocuments: [{
173
+ type: Input
174
+ }], showAvatar: [{
175
+ type: Input
176
+ }], showLanguage: [{
177
+ type: Input
178
+ }], showHelp: [{
179
+ type: Input
180
+ }], showLogout: [{
181
+ type: Input
100
182
  }], actionButtons: [{
101
183
  type: Input
102
184
  }], action: [{
@@ -1 +1 @@
1
- {"version":3,"file":"header-nav.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/header-nav/header-nav.ts","../../../../../../packages/angular/src/lib/header-nav/header-nav.html"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,YAAY,EACZ,KAAK,EACL,MAAM,GACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAiB,MAAM,kBAAkB,CAAC;;;AAsBlE;;;;;;;;;;GAUG;AAUH,MAAM,OAAO,kBAAkB;IA+CA;IA9C7B;;;;;OAKG;IACM,KAAK,GAAmB,MAAM,CAAC;IACxC,0EAA0E;IACjE,WAAW,GAAG,KAAK,CAAC;IAC7B,oFAAoF;IAC3E,cAAc,GAAG,UAAU,CAAC;IACrC,uFAAuF;IAC9E,UAAU,GAAG,EAAE,CAAC;IACzB,oHAAoH;IAC3G,eAAe,CAAU;IAClC;;;;OAIG;IACM,aAAa,CAAU;IAChC;;;;;OAKG;IACM,WAAW,GAAgB,EAAE,CAAC;IACvC;;;;;OAKG;IACM,aAAa,GAAgB,EAAE,CAAC;IAEzC;;;;;;;OAOG;IACgB,MAAM,GAAG,IAAI,YAAY,EAAU,CAAC;IAEvD,YAA6B,SAAuB;QAAvB,cAAS,GAAT,SAAS,CAAc;IAAG,CAAC;IAExD,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC;IACnC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,IAAY;QAClB,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;wGAhEU,kBAAkB;4FAAlB,kBAAkB,8YCnD/B,u5RA6DA,o8HDfY,eAAe;;4FAKd,kBAAkB;kBAT9B,SAAS;+BACE,qBAAqB,cACnB,IAAI,mBACC,uBAAuB,CAAC,MAAM,WACtC,CAAC,eAAe,CAAC,QAGpB,EAAE,IAAI,EAAE,QAAQ,EAAE;;sBASvB,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAML,KAAK;;sBAOL,KAAK;;sBAOL,KAAK;;sBAUL,MAAM","sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n EventEmitter,\r\n Input,\r\n Output,\r\n} from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\r\nimport { ButtonComponent, ButtonVariant } from '../button/button';\r\n\r\nexport type HeaderNavLevel = 'main' | 'sub-page' | 'not-logged';\r\n\r\n/**\r\n * A navigation item used for breadcrumbs, labeled buttons, and icon buttons.\r\n * - Breadcrumb: provide `id`, `label`, and any `variant` (variant is unused during breadcrumb rendering).\r\n * - Icon button: provide `id`, an icon `variant` (e.g. `'filled-icon'`), `icon` (Lucide name), and optionally `label` (used as aria-label).\r\n * - Labeled button: provide `id`, a non-icon `variant`, and `label`.\r\n */\r\nexport interface NavAction {\r\n /** Stable identifier emitted by the `action` output when this item is clicked. */\r\n id: string;\r\n /** Text displayed in the breadcrumb trail, on the button, or as aria-label for icon buttons. */\r\n label?: string;\r\n /** Lucide icon name. Required when `variant` is an icon variant (e.g. `'filled-icon'`). */\r\n icon?: string;\r\n /** Button style. Icon variants (e.g. `'filled-icon'`) render an icon button; all others render a labeled button. */\r\n variant: ButtonVariant;\r\n}\r\n\r\n\r\n/**\r\n * Header Navigation — top app bar from the ComPsych Design System.\r\n *\r\n * Three layout levels controlled by `level`:\r\n * - `'main'` — menu toggle, brand logo + wordmark, action buttons.\r\n * - `'sub-page'` — menu toggle, logo mark + breadcrumb trail, action buttons.\r\n * - `'not-logged'` — menu toggle, brand, action buttons.\r\n *\r\n * Icon and labeled buttons in the right action area are configured via `actionButtons`.\r\n * All interactive elements emit a string id via the `action` output.\r\n */\r\n@Component({\r\n selector: 'compsych-header-nav',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [ButtonComponent],\r\n templateUrl: './header-nav.html',\r\n styleUrl: './header-nav.css',\r\n host: { role: 'banner' },\r\n})\r\nexport class HeaderNavComponent {\r\n /**\r\n * Layout of the header left region.\r\n * - `'main'` — logo + brand label.\r\n * - `'sub-page'` — symbol mark + breadcrumb trail.\r\n * - `'not-logged'` — logo + brand label.\r\n */\r\n @Input() level: HeaderNavLevel = 'main';\r\n /** Whether the paired sidebar is open — toggles the menu icon (☰ ↔ ✕). */\r\n @Input() sidebarOpen = false;\r\n /** Accessible label for the brand area (logo + wordmark) used by screen readers. */\r\n @Input() brandLabelAria = 'ComPsych';\r\n /** Brand wordmark text rendered next to the logo on `main` and `not-logged` levels. */\r\n @Input() brandLabel = '';\r\n /** Optional hex color (e.g. `'#ff0000'`) applied to the brand label text. Overrides the default inherited color. */\r\n @Input() brandLabelColor?: string;\r\n /**\r\n * URL of a client logo image. When provided, replaces the ComPsych SVG logo\r\n * with an `<img>` at the same position. The image receives `brandLabelAria`\r\n * as its accessible label.\r\n */\r\n @Input() clientLogoUrl?: string;\r\n /**\r\n * Ordered breadcrumb trail rendered at `'sub-page'` level.\r\n * Each item requires `id` and `label`. The last item is the current page\r\n * (non-interactive). All preceding items are buttons that emit their `id`\r\n * via the `action` output when clicked.\r\n */\r\n @Input() breadcrumbs: NavAction[] = [];\r\n /**\r\n * Buttons rendered in the right action area.\r\n * - When `variant` ends in `'-icon'`, renders an icon button using `icon` as the Lucide name; `label` is used as aria-label.\r\n * - Otherwise, renders a labeled `<compsych-button>` using `label` and `variant`.\r\n * Clicking any button emits its `id` via the `action` output.\r\n */\r\n @Input() actionButtons: NavAction[] = [];\r\n\r\n /**\r\n * Emitted as a string whenever any interactive element is activated.\r\n * Fixed values for built-in controls:\r\n * - `'menu-toggle'` — hamburger / close button\r\n * - `'logo'` — brand / logo button\r\n *\r\n * For `breadcrumbs` and `actionButtons` items, the item's `NavAction.id` is emitted.\r\n */\r\n @Output() readonly action = new EventEmitter<string>();\r\n\r\n constructor(private readonly sanitizer: DomSanitizer) {}\r\n\r\n get isSubPage(): boolean {\r\n return this.level === 'sub-page';\r\n }\r\n\r\n get menuIconSvg(): SafeHtml {\r\n return this.iconSvg(this.sidebarOpen ? 'x' : 'menu');\r\n }\r\n\r\n /**\r\n * Returns a trusted SVG for the given Lucide icon name, sized at 20 × 20.\r\n * Used in the template for dynamic icon buttons via `actionButtons`.\r\n */\r\n iconSvg(name: string): SafeHtml {\r\n const svg = (LUCIDE_ICONS[name] ?? '').replace('<svg ', '<svg width=\"20\" height=\"20\" ');\r\n return this.sanitizer.bypassSecurityTrustHtml(svg);\r\n }\r\n}\r\n","<!-- Left: menu toggle + brand / breadcrumb -->\r\n<div class=\"compsych-hnav__left\">\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn\"\r\n [attr.aria-label]=\"sidebarOpen ? 'Close menu' : 'Open menu'\"\r\n [attr.aria-expanded]=\"sidebarOpen\"\r\n (click)=\"action.emit('menu-toggle')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"menuIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n\r\n @if (isSubPage) {\r\n <span class=\"compsych-hnav__symbol\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 25.73 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n <nav class=\"compsych-hnav__breadcrumb\" aria-label=\"Breadcrumb\">\r\n <ol role=\"list\">\r\n @for (crumb of breadcrumbs; track crumb.id; let last = $last) {\r\n <li>\r\n <span class=\"compsych-hnav__sep\" aria-hidden=\"true\">/</span>\r\n @if (last) {\r\n <span class=\"compsych-hnav__crumb compsych-hnav__crumb--current\" aria-current=\"page\">{{ crumb.label }}</span>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__crumb\" (click)=\"action.emit(crumb.id)\">{{ crumb.label }}</button>\r\n }\r\n </li>\r\n }\r\n </ol>\r\n </nav>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__brand\" [attr.aria-label]=\"brandLabelAria\" (click)=\"action.emit('logo')\">\r\n @if (clientLogoUrl) {\r\n <img [src]=\"clientLogoUrl\" class=\"compsych-hnav__logo\" [attr.aria-label]=\"brandLabelAria\" alt=\"\">\r\n } @else {\r\n <svg class=\"compsych-hnav__logo\" role=\"img\" [attr.aria-label]=\"brandLabelAria\" viewBox=\"0 0 118 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n <path d=\"M100.224 10.1401C99.6034 10.1778 99.2832 10.4202 98.9648 11.1655L95.2646 20.0396C94.401 22.0893 93.2696 23.0217 92.0479 23.1187C90.1758 23.2669 89.8026 22.2909 90.001 21.8384C90.1891 21.4101 90.7857 21.432 91.376 21.688C92.9483 22.3923 94.1901 21.1819 94.7578 19.9478L95.0771 19.1646L91.7148 11.1675C91.3769 10.4225 91.0572 10.1795 90.457 10.1431V9.88135H94.4385V10.1431C93.5556 10.1807 93.1605 10.5339 93.4238 11.1489L95.8848 17.2085L98.4014 11.1694C98.6648 10.5356 98.3066 10.1804 97.4805 10.144V9.87939H100.224V10.1401ZM42.1875 6.48486C44.4823 6.48486 46.2325 7.53169 46.7402 9.23096L46.7695 9.32764C46.9127 9.82287 46.5881 10.3309 46.0771 10.4155C45.6244 10.4908 45.1893 10.2032 45.0869 9.75928V9.75439C44.6901 8.07409 43.4871 6.99187 41.9629 6.9917C39.5355 6.9917 37.8613 9.25128 37.8613 12.5366C37.8615 15.8216 39.8557 18.1185 42.6963 18.1187C44.6906 18.1187 46.1534 17.0358 46.7363 15.355L47.042 15.4116C46.4028 17.9504 44.5009 19.519 41.9619 19.519L41.9609 19.5181L41.9619 19.5171L41.6426 19.5093C38.3673 19.3473 36.0548 16.7007 36.0547 13.3003C36.0547 9.34151 38.4247 6.48504 42.1875 6.48486ZM52.25 9.60107C54.8819 9.60107 56.543 11.5448 56.543 14.3667C56.543 17.4128 54.7326 19.5063 52.082 19.5063C49.4316 19.5063 47.7891 17.5624 47.7891 14.7593C47.7891 11.7132 49.6182 9.60114 52.25 9.60107ZM103.946 9.6167C105.862 9.61671 107.065 10.8474 107.252 11.8726C107.256 11.8884 107.455 12.641 106.806 12.8394C106.402 12.9623 105.897 12.7605 105.769 12.2085C105.556 11.2968 104.979 10.1392 103.702 10.1392C102.124 10.1392 101.054 11.7431 101.054 13.8667C101.054 16.4016 102.35 18.1538 104.436 18.1538C105.544 18.1537 106.615 17.576 107.29 16.3833L107.516 16.439C107.027 18.3032 105.675 19.4956 103.759 19.4956V19.4976C101.166 19.4974 99.457 17.3907 99.457 14.6685C99.4572 11.9463 101.166 9.6167 103.946 9.6167ZM86.9658 9.60693C88.5252 9.60693 90.0049 10.2854 90.3486 11.4526C90.4274 11.7209 90.4283 12.2344 90.0801 12.4097C89.7292 12.5859 89.3006 12.3929 89.1406 12.0493C88.6399 10.9763 88.1187 10.1296 86.749 10.1294C85.6223 10.1294 84.9748 10.7634 84.9746 11.6772C84.9746 12.8172 86.1343 13.2135 87.3945 13.6431C88.8752 14.1476 90.4945 14.6992 90.5352 16.562C90.5733 18.2954 88.971 19.4887 86.96 19.4888L86.959 19.4878V19.4858C85.3417 19.4872 83.9282 19.0132 83.3555 17.9028C83.1887 17.5793 83.2679 17.1326 83.5967 16.9761C83.9951 16.7863 84.3966 17.1152 84.6123 17.5005C85.1159 18.4011 86.1587 18.9632 87.0879 18.9634C88.2717 18.9634 89.2381 18.2926 89.2383 17.2681C89.2201 15.9311 87.9619 15.5017 86.6465 15.0532C85.2106 14.5636 83.7073 14.0505 83.6777 12.3091C83.6595 10.7051 84.9748 9.60708 86.9658 9.60693ZM110.52 11.6938C111.509 10.3857 112.498 9.60107 113.805 9.60107C115.447 9.60115 116.399 10.6471 116.399 12.4595V17.8608C116.399 18.6829 116.959 18.8511 117.631 18.9819V19.2437H113.618V18.9819C114.29 18.8511 114.85 18.6828 114.85 17.8608V12.5532C114.85 11.3947 114.197 10.6842 113.133 10.6841C112.218 10.6841 111.453 11.0956 110.52 12.1606V17.8608C110.52 18.6829 111.079 18.8511 111.751 18.9819V19.2437H107.72V18.9819C108.41 18.8511 108.97 18.6829 108.97 17.8608V8.04932C108.97 7.41406 108.671 7.11501 107.999 7.07764H107.552V6.81592L110.258 6.05029H110.52V11.6938ZM78.2471 6.76709L78.249 6.76807C81.1606 6.76807 83.1533 7.86945 83.1533 10.2554C83.1531 12.641 81.1615 13.7222 78.249 13.7222H77.0264V13.4331C80.258 13.4331 81.3154 11.9881 81.3105 10.2554C81.3055 8.52254 80.1832 7.29064 78.043 7.29053H76.3525L76.3506 17.562C76.3506 18.6802 76.8959 18.8865 78.0215 18.9604V19.2212H68.7891V18.9604C69.4654 18.8304 70.0283 18.6616 70.0283 17.8413V12.5474C70.0282 11.391 69.3706 10.6831 68.2998 10.6831C67.3412 10.6831 66.5705 11.1121 65.6133 12.231V17.8423C65.6133 18.6635 66.177 18.8314 66.8535 18.9614V19.2231H62.8145V18.9614C63.491 18.8314 64.0547 18.6627 64.0547 17.8423V12.5483C64.0545 11.3921 63.3963 10.6841 62.3271 10.6841C61.4441 10.6841 60.711 11.0579 59.8291 12.0083V17.8442C59.8293 18.6649 60.3921 18.8324 61.0684 18.9624V19.2241H57.0098V18.9624C57.7046 18.8316 58.2684 18.6643 58.2686 17.8442V11.5991C58.2686 10.9653 57.9682 10.6659 57.292 10.6099H56.8418V10.3481L59.5654 9.5835H59.8291V11.522C60.7869 10.31 61.7449 9.60208 63.0029 9.60205C64.4503 9.60205 65.3706 10.4033 65.5762 11.8198C66.6086 10.4401 67.6239 9.60208 68.9766 9.60205C70.629 9.60205 71.5879 10.6464 71.5879 12.4546V17.8423L71.5859 17.8403C71.5859 18.3871 71.8364 18.6442 72.2041 18.7935C72.5694 18.9413 73.0559 18.9637 73.4463 18.9058C74.2358 18.788 74.6386 18.4873 74.6387 17.561V8.40674C74.6386 7.32569 74.094 7.10187 72.9482 7.02686V6.76514H78.2461L78.2471 6.76709ZM51.9512 10.1245C50.4208 10.1247 49.4503 11.7317 49.4502 14.0112C49.4502 16.1043 50.2529 18.9829 52.3994 18.9829C53.9487 18.9829 54.9004 17.3567 54.9004 15.0581C54.9004 13.0024 54.0791 10.1245 51.9512 10.1245Z\" fill=\"currentColor\"/>\r\n </svg>\r\n }\r\n @if (brandLabel) {\r\n <span class=\"compsych-hnav__brand-label\" [attr.aria-label]=\"brandLabelAria\" [style.color]=\"brandLabelColor\">{{ brandLabel }}</span>\r\n }\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Right: actions -->\r\n<div class=\"compsych-hnav__actions\">\r\n @for (btn of actionButtons; track btn.id) {\r\n @if (btn.variant.endsWith('-icon')) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn\" [attr.aria-label]=\"btn.label ?? btn.id\" (click)=\"action.emit(btn.id)\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"iconSvg(btn.icon!)\" aria-hidden=\"true\"></span>\r\n </button>\r\n } @else {\r\n <compsych-button [variant]=\"btn.variant\" size=\"medium\" [label]=\"btn.label ?? ''\" (click)=\"action.emit(btn.id)\"></compsych-button>\r\n }\r\n }\r\n</div>\r\n"]}
1
+ {"version":3,"file":"header-nav.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/header-nav/header-nav.ts","../../../../../../packages/angular/src/lib/header-nav/header-nav.html"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,YAAY,EACZ,KAAK,EACL,MAAM,GACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAiB,MAAM,kBAAkB,CAAC;;;AAmBlE;;;;;;;;;;;GAWG;AAUH,MAAM,OAAO,kBAAkB;IAqFA;IApF7B;;;;;OAKG;IACM,KAAK,GAAmB,MAAM,CAAC;IACxC,0EAA0E;IACjE,WAAW,GAAG,KAAK,CAAC;IAC7B,qDAAqD;IAC5C,cAAc,GAAG,IAAI,CAAC;IAC/B,oFAAoF;IAC3E,cAAc,GAAG,UAAU,CAAC;IACrC,uFAAuF;IAC9E,UAAU,GAAG,EAAE,CAAC;IACzB,oHAAoH;IAC3G,eAAe,CAAU;IAClC;;;;OAIG;IACM,aAAa,CAAU;IAChC;;;;;OAKG;IACM,WAAW,GAAgB,EAAE,CAAC;IACvC,wDAAwD;IAC/C,iBAAiB,GAAG,CAAC,CAAC;IAC/B,8CAA8C;IACrC,cAAc,GAAG,IAAI,CAAC;IAC/B,sDAAsD;IAC7C,UAAU,GAAG,IAAI,CAAC;IAC3B,8DAA8D;IACrD,mBAAmB,GAAG,IAAI,CAAC;IACpC,6DAA6D;IACpD,iBAAiB,GAAG,IAAI,CAAC;IAClC,yDAAyD;IAChD,aAAa,GAAG,IAAI,CAAC;IAC9B,iDAAiD;IACxC,UAAU,GAAG,IAAI,CAAC;IAC3B,6EAA6E;IACpE,YAAY,GAAG,IAAI,CAAC;IAC7B,oDAAoD;IAC3C,QAAQ,GAAG,IAAI,CAAC;IACzB,8DAA8D;IACrD,UAAU,GAAG,KAAK,CAAC;IAC5B;;;;OAIG;IACM,aAAa,GAAgB,EAAE,CAAC;IAEzC;;;;;;;;;;;;;;;OAeG;IACgB,MAAM,GAAG,IAAI,YAAY,EAAU,CAAC;IAE9C,aAAa,CAAW;IACxB,sBAAsB,CAAW;IACjC,WAAW,CAAW;IACtB,eAAe,CAAW;IAC1B,YAAY,CAAW;IACvB,WAAW,CAAW;IACtB,aAAa,CAAW;IACxB,WAAW,CAAW;IAE/B,YAA6B,SAAuB;QAAvB,cAAS,GAAT,SAAS,CAAc;QAClD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;QACjE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC;QAC5D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,KAAK,KAAK,YAAY,CAAC;IACrC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC;IACnC,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3E,CAAC;IAED,IAAI,qBAAqB;QACvB,OAAO,IAAI,CAAC,iBAAiB,GAAG,CAAC;YAC/B,CAAC,CAAC,kBAAkB,IAAI,CAAC,iBAAiB,SAAS;YACnD,CAAC,CAAC,eAAe,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACK,WAAW,CAAC,IAAY;QAC9B,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;wGAhIU,kBAAkB;4FAAlB,kBAAkB,gvBCjD/B,08YA+IA,60KDnGY,eAAe;;4FAKd,kBAAkB;kBAT9B,SAAS;+BACE,qBAAqB,cACnB,IAAI,mBACC,uBAAuB,CAAC,MAAM,WACtC,CAAC,eAAe,CAAC,QAGpB,EAAE,IAAI,EAAE,QAAQ,EAAE;;sBASvB,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAML,KAAK;;sBAOL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAEL,KAAK;;sBAML,KAAK;;sBAkBL,MAAM","sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n EventEmitter,\r\n Input,\r\n Output,\r\n} from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\r\nimport { ButtonComponent, ButtonVariant } from '../button/button';\r\n\r\nexport type HeaderNavLevel = 'main' | 'sub-page' | 'not-logged';\r\n\r\n/**\r\n * A navigation item used for both breadcrumbs and action buttons.\r\n * - Breadcrumb: provide `id` and `label`.\r\n * - Action button: provide `id`, `label`, and optionally `variant`.\r\n */\r\nexport interface NavAction {\r\n /** Stable identifier emitted by the `action` output when this item is clicked. */\r\n id: string;\r\n /** Text displayed in the breadcrumb trail or on the action button. */\r\n label: string;\r\n /** Button style for action buttons. Defaults to `'filled'` when omitted. Not used for breadcrumbs. */\r\n variant?: ButtonVariant;\r\n}\r\n\r\n\r\n/**\r\n * Header Navigation — top app bar from the ComPsych Design System.\r\n *\r\n * Three layout levels controlled by `level`:\r\n * - `'main'` — menu toggle, brand logo + wordmark, logged-in action cluster.\r\n * - `'sub-page'` — menu toggle, logo mark + breadcrumb trail, logged-in action cluster.\r\n * - `'not-logged'` — menu toggle, brand, public action cluster (language, help, CTA buttons).\r\n *\r\n * All interactive elements emit a string id via the `action` output.\r\n * For breadcrumbs and action buttons the emitted value is the `NavAction.id`.\r\n * For built-in icon buttons a fixed string is emitted (see `action` docs).\r\n */\r\n@Component({\r\n selector: 'compsych-header-nav',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [ButtonComponent],\r\n templateUrl: './header-nav.html',\r\n styleUrl: './header-nav.css',\r\n host: { role: 'banner' },\r\n})\r\nexport class HeaderNavComponent {\r\n /**\r\n * Layout and feature set of the header.\r\n * - `'main'` — logo + brand label, logged-in action cluster (search, notifications, documents, language, avatar, logout).\r\n * - `'sub-page'` — symbol mark + breadcrumb trail, same logged-in action cluster.\r\n * - `'not-logged'` — logo + brand label, public action cluster (language, help, action buttons).\r\n */\r\n @Input() level: HeaderNavLevel = 'main';\r\n /** Whether the paired sidebar is open — toggles the menu icon (☰ ↔ ✕). */\r\n @Input() sidebarOpen = false;\r\n /** Show the hamburger / close menu toggle button. */\r\n @Input() showMenuToggle = true;\r\n /** Accessible label for the brand area (logo + wordmark) used by screen readers. */\r\n @Input() brandLabelAria = 'ComPsych';\r\n /** Brand wordmark text rendered next to the logo on `main` and `not-logged` levels. */\r\n @Input() brandLabel = '';\r\n /** Optional hex color (e.g. `'#ff0000'`) applied to the brand label text. Overrides the default inherited color. */\r\n @Input() brandLabelColor?: string;\r\n /**\r\n * URL of a client logo image. When provided, replaces the ComPsych SVG logo\r\n * with an `<img>` at the same position. The image receives `brandLabelAria`\r\n * as its accessible label.\r\n */\r\n @Input() clientLogoUrl?: string;\r\n /**\r\n * Ordered breadcrumb trail rendered at `'sub-page'` level.\r\n * Each item requires `id` and `label`. The last item is the current page\r\n * (non-interactive). All preceding items are buttons that emit their `id`\r\n * via the `action` output when clicked.\r\n */\r\n @Input() breadcrumbs: NavAction[] = [];\r\n /** Notification badge count. Badge is hidden when 0. */\r\n @Input() notificationCount = 0;\r\n /** Avatar initials for the logged-in user. */\r\n @Input() avatarInitials = 'CP';\r\n /** Show the search icon button (logged-in levels). */\r\n @Input() showSearch = true;\r\n /** Show the calendar-check icon button (logged-in levels). */\r\n @Input() showCalendarChecked = true;\r\n /** Show the notifications icon button (logged-in levels). */\r\n @Input() showNotifications = true;\r\n /** Show the documents icon button (logged-in levels). */\r\n @Input() showDocuments = true;\r\n /** Show the avatar button (logged-in levels). */\r\n @Input() showAvatar = true;\r\n /** Show the language icon button (main, sub-page, and not-logged levels). */\r\n @Input() showLanguage = true;\r\n /** Show the help icon button (not-logged level). */\r\n @Input() showHelp = true;\r\n /** Show the logout icon button (main and sub-page levels). */\r\n @Input() showLogout = false;\r\n /**\r\n * Additional configurable buttons rendered in the actions area.\r\n * Each entry requires `id` and `label`; `variant` defaults to `'filled'`.\r\n * Clicking any button emits its `id` via the `action` output.\r\n */\r\n @Input() actionButtons: NavAction[] = [];\r\n\r\n /**\r\n * Emitted as a string whenever any interactive element is activated.\r\n * Fixed values for built-in controls:\r\n * - `'menu-toggle'` — hamburger / close button\r\n * - `'logo'` — brand / logo button\r\n * - `'search'` — search icon button\r\n * - `'calendar-checked'` — calendar-check icon button\r\n * - `'notifications'` — notifications icon button\r\n * - `'documents'` — documents icon button\r\n * - `'language'` — language icon button\r\n * - `'help'` — help icon button\r\n * - `'avatar'` — avatar button\r\n * - `'logout'` — logout icon button\r\n *\r\n * For `breadcrumbs` and `actionButtons` items, the item's `NavAction.id` is emitted.\r\n */\r\n @Output() readonly action = new EventEmitter<string>();\r\n\r\n readonly searchIconSvg: SafeHtml;\r\n readonly calendarCheckedIconSvg: SafeHtml;\r\n readonly bellIconSvg: SafeHtml;\r\n readonly fileTextIconSvg: SafeHtml;\r\n readonly globeIconSvg: SafeHtml;\r\n readonly helpIconSvg: SafeHtml;\r\n readonly logOutIconSvg: SafeHtml;\r\n readonly userIconSvg: SafeHtml;\r\n\r\n constructor(private readonly sanitizer: DomSanitizer) {\r\n this.searchIconSvg = this.trustedIcon('search');\r\n this.calendarCheckedIconSvg = this.trustedIcon('calendar-check');\r\n this.bellIconSvg = this.trustedIcon('bell');\r\n this.fileTextIconSvg = this.trustedIcon('file-text');\r\n this.globeIconSvg = this.trustedIcon('globe');\r\n this.helpIconSvg = this.trustedIcon('circle-question-mark');\r\n this.logOutIconSvg = this.trustedIcon('log-out');\r\n this.userIconSvg = this.trustedIcon('user');\r\n }\r\n\r\n get isLoggedOut(): boolean {\r\n return this.level === 'not-logged';\r\n }\r\n\r\n get isSubPage(): boolean {\r\n return this.level === 'sub-page';\r\n }\r\n\r\n get menuIconSvg(): SafeHtml {\r\n return this.trustedIcon(this.sidebarOpen ? 'x' : 'menu');\r\n }\r\n\r\n get badgeText(): string {\r\n return this.notificationCount > 99 ? '99+' : `${this.notificationCount}`;\r\n }\r\n\r\n get notificationAriaLabel(): string {\r\n return this.notificationCount > 0\r\n ? `Notifications, ${this.notificationCount} unread`\r\n : 'Notifications';\r\n }\r\n\r\n /**\r\n * Looks up a Lucide icon by name and injects explicit width/height attributes\r\n * (20 × 20) so the SVG renders at the correct size when injected via [innerHTML].\r\n * Angular's CSS encapsulation does not add _ngcontent attributes to dynamically\r\n * injected content, so CSS descendant selectors targeting `svg` would not apply —\r\n * explicit SVG attributes are the reliable solution.\r\n */\r\n private trustedIcon(name: string): SafeHtml {\r\n const svg = (LUCIDE_ICONS[name] ?? '').replace('<svg ', '<svg width=\"20\" height=\"20\" ');\r\n return this.sanitizer.bypassSecurityTrustHtml(svg);\r\n }\r\n}\r\n","<!-- Left: menu toggle + brand / breadcrumb -->\r\n<div class=\"compsych-hnav__left\">\r\n @if (showMenuToggle) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn\"\r\n [attr.aria-label]=\"sidebarOpen ? 'Close menu' : 'Open menu'\"\r\n [attr.aria-expanded]=\"sidebarOpen\"\r\n (click)=\"action.emit('menu-toggle')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"menuIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n\r\n @if (isSubPage) {\r\n <span class=\"compsych-hnav__symbol\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 25.73 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n </svg>\r\n </span>\r\n <nav class=\"compsych-hnav__breadcrumb\" aria-label=\"Breadcrumb\">\r\n <ol role=\"list\">\r\n @for (crumb of breadcrumbs; track crumb.id; let last = $last) {\r\n <li>\r\n <span class=\"compsych-hnav__sep\" aria-hidden=\"true\">/</span>\r\n @if (last) {\r\n <span class=\"compsych-hnav__crumb compsych-hnav__crumb--current\" aria-current=\"page\">{{ crumb.label }}</span>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__crumb\" (click)=\"action.emit(crumb.id)\">{{ crumb.label }}</button>\r\n }\r\n </li>\r\n }\r\n </ol>\r\n </nav>\r\n } @else {\r\n <button type=\"button\" class=\"compsych-hnav__brand\" [attr.aria-label]=\"brandLabelAria\" (click)=\"action.emit('logo')\">\r\n @if (clientLogoUrl) {\r\n <img [src]=\"clientLogoUrl\" class=\"compsych-hnav__logo\" [attr.aria-label]=\"brandLabelAria\" alt=\"\">\r\n } @else {\r\n <svg class=\"compsych-hnav__logo\" role=\"img\" [attr.aria-label]=\"brandLabelAria\" viewBox=\"0 0 118 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12.8653 14.1245C16.8469 14.1245 20.3525 16.2028 22.3536 19.3315H3.37704C5.31567 16.3005 8.6659 14.2552 12.4933 14.1304L12.8653 14.1245ZM12.8653 7.84521C18.6037 7.84521 23.2716 12.5137 23.2716 18.2515C23.2716 18.4109 23.267 18.5699 23.2599 18.728C21.0624 15.3064 17.223 13.0347 12.8643 13.0347C8.50575 13.0347 4.66828 15.3048 2.47079 18.7251C2.46367 18.5683 2.46005 18.4102 2.46005 18.2515C2.46005 12.5132 7.1278 7.84543 12.8653 7.84521ZM12.8653 1.56689C19.4758 1.56689 24.8543 6.94473 24.8546 13.5552C24.8546 14.8765 24.6389 16.1496 24.2423 17.3394C23.7763 11.4707 18.8512 6.83838 12.8653 6.83838C6.87959 6.83857 1.95592 11.4715 1.48935 17.3394C1.09275 16.1496 0.877045 14.8765 0.877045 13.5552C0.877289 6.94485 6.25504 1.56709 12.8653 1.56689Z\" fill=\"currentColor\"/>\r\n <path d=\"M100.224 10.1401C99.6034 10.1778 99.2832 10.4202 98.9648 11.1655L95.2646 20.0396C94.401 22.0893 93.2696 23.0217 92.0479 23.1187C90.1758 23.2669 89.8026 22.2909 90.001 21.8384C90.1891 21.4101 90.7857 21.432 91.376 21.688C92.9483 22.3923 94.1901 21.1819 94.7578 19.9478L95.0771 19.1646L91.7148 11.1675C91.3769 10.4225 91.0572 10.1795 90.457 10.1431V9.88135H94.4385V10.1431C93.5556 10.1807 93.1605 10.5339 93.4238 11.1489L95.8848 17.2085L98.4014 11.1694C98.6648 10.5356 98.3066 10.1804 97.4805 10.144V9.87939H100.224V10.1401ZM42.1875 6.48486C44.4823 6.48486 46.2325 7.53169 46.7402 9.23096L46.7695 9.32764C46.9127 9.82287 46.5881 10.3309 46.0771 10.4155C45.6244 10.4908 45.1893 10.2032 45.0869 9.75928V9.75439C44.6901 8.07409 43.4871 6.99187 41.9629 6.9917C39.5355 6.9917 37.8613 9.25128 37.8613 12.5366C37.8615 15.8216 39.8557 18.1185 42.6963 18.1187C44.6906 18.1187 46.1534 17.0358 46.7363 15.355L47.042 15.4116C46.4028 17.9504 44.5009 19.519 41.9619 19.519L41.9609 19.5181L41.9619 19.5171L41.6426 19.5093C38.3673 19.3473 36.0548 16.7007 36.0547 13.3003C36.0547 9.34151 38.4247 6.48504 42.1875 6.48486ZM52.25 9.60107C54.8819 9.60107 56.543 11.5448 56.543 14.3667C56.543 17.4128 54.7326 19.5063 52.082 19.5063C49.4316 19.5063 47.7891 17.5624 47.7891 14.7593C47.7891 11.7132 49.6182 9.60114 52.25 9.60107ZM103.946 9.6167C105.862 9.61671 107.065 10.8474 107.252 11.8726C107.256 11.8884 107.455 12.641 106.806 12.8394C106.402 12.9623 105.897 12.7605 105.769 12.2085C105.556 11.2968 104.979 10.1392 103.702 10.1392C102.124 10.1392 101.054 11.7431 101.054 13.8667C101.054 16.4016 102.35 18.1538 104.436 18.1538C105.544 18.1537 106.615 17.576 107.29 16.3833L107.516 16.439C107.027 18.3032 105.675 19.4956 103.759 19.4956V19.4976C101.166 19.4974 99.457 17.3907 99.457 14.6685C99.4572 11.9463 101.166 9.6167 103.946 9.6167ZM86.9658 9.60693C88.5252 9.60693 90.0049 10.2854 90.3486 11.4526C90.4274 11.7209 90.4283 12.2344 90.0801 12.4097C89.7292 12.5859 89.3006 12.3929 89.1406 12.0493C88.6399 10.9763 88.1187 10.1296 86.749 10.1294C85.6223 10.1294 84.9748 10.7634 84.9746 11.6772C84.9746 12.8172 86.1343 13.2135 87.3945 13.6431C88.8752 14.1476 90.4945 14.6992 90.5352 16.562C90.5733 18.2954 88.971 19.4887 86.96 19.4888L86.959 19.4878V19.4858C85.3417 19.4872 83.9282 19.0132 83.3555 17.9028C83.1887 17.5793 83.2679 17.1326 83.5967 16.9761C83.9951 16.7863 84.3966 17.1152 84.6123 17.5005C85.1159 18.4011 86.1587 18.9632 87.0879 18.9634C88.2717 18.9634 89.2381 18.2926 89.2383 17.2681C89.2201 15.9311 87.9619 15.5017 86.6465 15.0532C85.2106 14.5636 83.7073 14.0505 83.6777 12.3091C83.6595 10.7051 84.9748 9.60708 86.9658 9.60693ZM110.52 11.6938C111.509 10.3857 112.498 9.60107 113.805 9.60107C115.447 9.60115 116.399 10.6471 116.399 12.4595V17.8608C116.399 18.6829 116.959 18.8511 117.631 18.9819V19.2437H113.618V18.9819C114.29 18.8511 114.85 18.6828 114.85 17.8608V12.5532C114.85 11.3947 114.197 10.6842 113.133 10.6841C112.218 10.6841 111.453 11.0956 110.52 12.1606V17.8608C110.52 18.6829 111.079 18.8511 111.751 18.9819V19.2437H107.72V18.9819C108.41 18.8511 108.97 18.6829 108.97 17.8608V8.04932C108.97 7.41406 108.671 7.11501 107.999 7.07764H107.552V6.81592L110.258 6.05029H110.52V11.6938ZM78.2471 6.76709L78.249 6.76807C81.1606 6.76807 83.1533 7.86945 83.1533 10.2554C83.1531 12.641 81.1615 13.7222 78.249 13.7222H77.0264V13.4331C80.258 13.4331 81.3154 11.9881 81.3105 10.2554C81.3055 8.52254 80.1832 7.29064 78.043 7.29053H76.3525L76.3506 17.562C76.3506 18.6802 76.8959 18.8865 78.0215 18.9604V19.2212H68.7891V18.9604C69.4654 18.8304 70.0283 18.6616 70.0283 17.8413V12.5474C70.0282 11.391 69.3706 10.6831 68.2998 10.6831C67.3412 10.6831 66.5705 11.1121 65.6133 12.231V17.8423C65.6133 18.6635 66.177 18.8314 66.8535 18.9614V19.2231H62.8145V18.9614C63.491 18.8314 64.0547 18.6627 64.0547 17.8423V12.5483C64.0545 11.3921 63.3963 10.6841 62.3271 10.6841C61.4441 10.6841 60.711 11.0579 59.8291 12.0083V17.8442C59.8293 18.6649 60.3921 18.8324 61.0684 18.9624V19.2241H57.0098V18.9624C57.7046 18.8316 58.2684 18.6643 58.2686 17.8442V11.5991C58.2686 10.9653 57.9682 10.6659 57.292 10.6099H56.8418V10.3481L59.5654 9.5835H59.8291V11.522C60.7869 10.31 61.7449 9.60208 63.0029 9.60205C64.4503 9.60205 65.3706 10.4033 65.5762 11.8198C66.6086 10.4401 67.6239 9.60208 68.9766 9.60205C70.629 9.60205 71.5879 10.6464 71.5879 12.4546V17.8423L71.5859 17.8403C71.5859 18.3871 71.8364 18.6442 72.2041 18.7935C72.5694 18.9413 73.0559 18.9637 73.4463 18.9058C74.2358 18.788 74.6386 18.4873 74.6387 17.561V8.40674C74.6386 7.32569 74.094 7.10187 72.9482 7.02686V6.76514H78.2461L78.2471 6.76709ZM51.9512 10.1245C50.4208 10.1247 49.4503 11.7317 49.4502 14.0112C49.4502 16.1043 50.2529 18.9829 52.3994 18.9829C53.9487 18.9829 54.9004 17.3567 54.9004 15.0581C54.9004 13.0024 54.0791 10.1245 51.9512 10.1245Z\" fill=\"currentColor\"/>\r\n </svg>\r\n }\r\n @if (brandLabel) {\r\n <span class=\"compsych-hnav__brand-label\" [attr.aria-label]=\"brandLabelAria\" [style.color]=\"brandLabelColor\">{{ brandLabel }}</span>\r\n }\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Right: actions -->\r\n<div class=\"compsych-hnav__actions\">\r\n @if (isLoggedOut) {\r\n @if (showLanguage) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Language\" (click)=\"action.emit('language')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"globeIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showHelp) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Help\" (click)=\"action.emit('help')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"helpIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (actionButtons.length) {\r\n <div class=\"compsych-hnav__action-btns\">\r\n @for (btn of actionButtons; track btn.id) {\r\n <compsych-button [variant]=\"btn.variant ?? 'filled'\" size=\"medium\" [label]=\"btn.label\" (click)=\"action.emit(btn.id)\"></compsych-button>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (showSearch) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Search\" (click)=\"action.emit('search')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"searchIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showCalendarChecked) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Calendar\" (click)=\"action.emit('calendar-checked')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"calendarCheckedIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showNotifications) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn compsych-hnav__overflow-aux\"\r\n [attr.aria-label]=\"notificationAriaLabel\"\r\n (click)=\"action.emit('notifications')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"bellIconSvg\" aria-hidden=\"true\"></span>\r\n @if (notificationCount > 0) {\r\n <span class=\"compsych-hnav__badge\" aria-hidden=\"true\">{{ badgeText }}</span>\r\n }\r\n </button>\r\n }\r\n @if (showDocuments) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__icon-btn compsych-hnav__overflow-aux\"\r\n aria-label=\"Documents\"\r\n (click)=\"action.emit('documents')\"\r\n >\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"fileTextIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (showLanguage) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn compsych-hnav__overflow-core\" aria-label=\"Language\" (click)=\"action.emit('language')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"globeIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n @if (actionButtons.length) {\r\n <div class=\"compsych-hnav__action-btns\">\r\n @for (btn of actionButtons; track btn.id) {\r\n <compsych-button\r\n [variant]=\"btn.variant ?? 'filled'\"\r\n size=\"medium\"\r\n [label]=\"btn.label\"\r\n (click)=\"action.emit(btn.id)\"\r\n ></compsych-button>\r\n }\r\n </div>\r\n }\r\n @if (showAvatar) {\r\n <button\r\n type=\"button\"\r\n class=\"compsych-hnav__avatar compsych-hnav__overflow-core\"\r\n [attr.aria-label]=\"avatarInitials ? 'Account: ' + avatarInitials : 'Account'\"\r\n (click)=\"action.emit('avatar')\"\r\n >\r\n @if (avatarInitials) {\r\n {{ avatarInitials }}\r\n } @else {\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"userIconSvg\" aria-hidden=\"true\"></span>\r\n }\r\n </button>\r\n }\r\n @if (showLogout) {\r\n <button type=\"button\" class=\"compsych-hnav__icon-btn\" aria-label=\"Logout\" (click)=\"action.emit('logout')\">\r\n <span class=\"compsych-hnav__icon\" [innerHTML]=\"logOutIconSvg\" aria-hidden=\"true\"></span>\r\n </button>\r\n }\r\n }\r\n</div>\r\n"]}
@@ -95,10 +95,10 @@ export class SidebarComponent {
95
95
  return this.sanitizer.bypassSecurityTrustHtml(svg);
96
96
  }
97
97
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SidebarComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
98
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SidebarComponent, isStandalone: true, selector: "compsych-sidebar", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, footerItems: { classPropertyName: "footerItems", publicName: "footerItems", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeId: "activeIdChange", itemClick: "itemClick" }, host: { attributes: { "role": "navigation", "aria-label": "Sidebar" } }, ngImport: i0, template: "<div class=\"cs-sb__scroll\">\n <ul class=\"cs-sb__list\">\n @for (item of items(); track item.id) {\n @if (item.dividerBefore) {\n <li class=\"cs-sb__divider\" aria-hidden=\"true\"></li>\n }\n <li class=\"cs-sb__item\">\n <button\n type=\"button\"\n class=\"cs-sb__row\"\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\n [disabled]=\"item.disabled || null\"\n [attr.aria-current]=\"!item.nonRoute && isActive(item.id) ? 'page' : null\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"onItemClick(item)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ item.label }}</span>\n @if (item.children?.length) {\n <span\n class=\"cs-sb__chevron\"\n [class.cs-sb__chevron--open]=\"isExpanded(item.id)\"\n [innerHTML]=\"iconSvg('chevron-down', 18)\"\n aria-hidden=\"true\"\n ></span>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <ul class=\"cs-sb__sublist\">\n @for (child of item.children; track child.id) {\n <li>\n <button\n type=\"button\"\n class=\"cs-sb__row cs-sb__row--sub\"\n [class.cs-sb__row--active]=\"isActive(child.id)\"\n [disabled]=\"child.disabled || null\"\n [attr.aria-current]=\"isActive(child.id) ? 'page' : null\"\n (click)=\"onItemClick(child)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(child.icon, 20, isActive(child.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ child.label }}</span>\n </button>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n</div>\n\n<div class=\"cs-sb__footer\">\n <ul class=\"cs-sb__list\">\n @for (item of footerItems(); track item.id) {\n <li class=\"cs-sb__item\">\n <button\n type=\"button\"\n class=\"cs-sb__row\"\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\n [disabled]=\"item.disabled || null\"\n (click)=\"onItemClick(item)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ item.label }}</span>\n </button>\n </li>\n }\n </ul>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:16.5rem;height:100%;box-sizing:border-box;padding:var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-12);background:var(--surface-surface-container-sys-surface-container-lowest);border-right:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant);font-family:var(--body-small-sys-font-family)}.cs-sb__scroll{flex:1 1 auto;min-height:0;overflow-y:auto;margin-right:calc(var(--spacing-padding-sys-padding-12) * -1);padding-right:var(--spacing-padding-sys-padding-12);scrollbar-width:thin;scrollbar-color:var(--surface-surface-container-sys-surface-container-highest) transparent}.cs-sb__scroll::-webkit-scrollbar{width:var(--sys-size-xxs)}.cs-sb__scroll::-webkit-scrollbar-track{background:transparent}.cs-sb__scroll::-webkit-scrollbar-thumb{background-color:var(--surface-surface-container-sys-surface-container-highest);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thick) solid transparent;background-clip:padding-box;min-height:var(--sys-size-lg)}.cs-sb__scroll::-webkit-scrollbar-thumb:hover{background-color:var(--outline-sys-outline-fixed)}.cs-sb__footer{flex-shrink:0;padding-top:var(--spacing-padding-sys-padding-8);border-top:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);margin-top:var(--spacing-padding-sys-padding-8)}.cs-sb__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cs-sb__divider{height:var(--border-width-sys-stroke-thin);background:var(--outline-sys-outline);margin:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-12)}.cs-sb__item{display:flex;flex-direction:column}.cs-sb__row{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);width:100%;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-16);border:var(--border-width-sys-stroke-thick) solid transparent;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface);font:inherit;font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);font-weight:var(--body-small-sys-font-weight);text-align:left;cursor:pointer;transition:background-color .12s ease-out,color .12s ease-out}.cs-sb__row:hover{background:var(--surface-surface-container-sys-surface-container-low)}.cs-sb__row:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);background:var(--surface-surface-container-sys-surface-container-lowest)}.cs-sb__row:disabled{color:var(--surface-surface-sys-on-surface-variant);opacity:.64;cursor:not-allowed}.cs-sb__row--active,.cs-sb__row--active:hover{background:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);font-weight:var(--body-small-sys-font-weight-emphasized)}.cs-sb__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant)}.cs-sb__row--active .cs-sb__icon{color:var(--surface-surface-sys-on-surface)}.cs-sb__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cs-sb__chevron{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);transition:transform .15s ease-out}.cs-sb__chevron--open{transform:rotate(180deg)}.cs-sb__sublist{list-style:none;margin:var(--spacing-padding-sys-padding-4) 0 0;padding:0 0 0 var(--spacing-padding-sys-padding-24);display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
98
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SidebarComponent, isStandalone: true, selector: "compsych-sidebar", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, footerItems: { classPropertyName: "footerItems", publicName: "footerItems", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeId: "activeIdChange", itemClick: "itemClick" }, host: { attributes: { "role": "navigation", "aria-label": "Sidebar" } }, ngImport: i0, template: "<div class=\"cs-sb__scroll\">\r\n <ul class=\"cs-sb__list\">\r\n @for (item of items(); track item.id) {\r\n @if (item.dividerBefore) {\r\n <li class=\"cs-sb__divider\" aria-hidden=\"true\"></li>\r\n }\r\n <li class=\"cs-sb__item\">\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row\"\r\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\r\n [disabled]=\"item.disabled || null\"\r\n [attr.aria-current]=\"!item.nonRoute && isActive(item.id) ? 'page' : null\"\r\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ item.label }}</span>\r\n @if (item.children?.length) {\r\n <span\r\n class=\"cs-sb__chevron\"\r\n [class.cs-sb__chevron--open]=\"isExpanded(item.id)\"\r\n [innerHTML]=\"iconSvg('chevron-down', 18)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n </button>\r\n\r\n @if (item.children?.length && isExpanded(item.id)) {\r\n <ul class=\"cs-sb__sublist\">\r\n @for (child of item.children; track child.id) {\r\n <li>\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row cs-sb__row--sub\"\r\n [class.cs-sb__row--active]=\"isActive(child.id)\"\r\n [disabled]=\"child.disabled || null\"\r\n [attr.aria-current]=\"isActive(child.id) ? 'page' : null\"\r\n (click)=\"onItemClick(child)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(child.icon, 20, isActive(child.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ child.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n\r\n<div class=\"cs-sb__footer\">\r\n <ul class=\"cs-sb__list\">\r\n @for (item of footerItems(); track item.id) {\r\n <li class=\"cs-sb__item\">\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row\"\r\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\r\n [disabled]=\"item.disabled || null\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ item.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;width:16.5rem;height:100%;box-sizing:border-box;padding:var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-12);background:var(--surface-surface-container-sys-surface-container-lowest);border-right:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant);font-family:var(--body-small-sys-font-family)}.cs-sb__scroll{flex:1 1 auto;min-height:0;overflow-y:auto;margin-right:calc(var(--spacing-padding-sys-padding-12) * -1);padding-right:var(--spacing-padding-sys-padding-12);scrollbar-width:thin;scrollbar-color:var(--surface-surface-container-sys-surface-container-highest) transparent}.cs-sb__scroll::-webkit-scrollbar{width:var(--sys-size-xxs)}.cs-sb__scroll::-webkit-scrollbar-track{background:transparent}.cs-sb__scroll::-webkit-scrollbar-thumb{background-color:var(--surface-surface-container-sys-surface-container-highest);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thick) solid transparent;background-clip:padding-box;min-height:var(--sys-size-lg)}.cs-sb__scroll::-webkit-scrollbar-thumb:hover{background-color:var(--outline-sys-outline-fixed)}.cs-sb__footer{flex-shrink:0;padding-top:var(--spacing-padding-sys-padding-8);border-top:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);margin-top:var(--spacing-padding-sys-padding-8)}.cs-sb__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cs-sb__divider{height:var(--border-width-sys-stroke-thin);background:var(--outline-sys-outline);margin:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-12)}.cs-sb__item{display:flex;flex-direction:column}.cs-sb__row{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);width:100%;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-16);border:var(--border-width-sys-stroke-thick) solid transparent;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface);font:inherit;font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);font-weight:var(--body-small-sys-font-weight);text-align:left;cursor:pointer;transition:background-color .12s ease-out,color .12s ease-out}.cs-sb__row:hover{background:var(--surface-surface-container-sys-surface-container-low)}.cs-sb__row:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);background:var(--surface-surface-container-sys-surface-container-lowest)}.cs-sb__row:disabled{color:var(--surface-surface-sys-on-surface-variant);opacity:.64;cursor:not-allowed}.cs-sb__row--active,.cs-sb__row--active:hover{background:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);font-weight:var(--body-small-sys-font-weight-emphasized)}.cs-sb__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant)}.cs-sb__row--active .cs-sb__icon{color:var(--surface-surface-sys-on-surface)}.cs-sb__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cs-sb__chevron{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);transition:transform .15s ease-out}.cs-sb__chevron--open{transform:rotate(180deg)}.cs-sb__sublist{list-style:none;margin:var(--spacing-padding-sys-padding-4) 0 0;padding:0 0 0 var(--spacing-padding-sys-padding-24);display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
99
99
  }
100
100
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SidebarComponent, decorators: [{
101
101
  type: Component,
102
- args: [{ selector: 'compsych-sidebar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], host: { role: 'navigation', 'aria-label': 'Sidebar' }, template: "<div class=\"cs-sb__scroll\">\n <ul class=\"cs-sb__list\">\n @for (item of items(); track item.id) {\n @if (item.dividerBefore) {\n <li class=\"cs-sb__divider\" aria-hidden=\"true\"></li>\n }\n <li class=\"cs-sb__item\">\n <button\n type=\"button\"\n class=\"cs-sb__row\"\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\n [disabled]=\"item.disabled || null\"\n [attr.aria-current]=\"!item.nonRoute && isActive(item.id) ? 'page' : null\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"onItemClick(item)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ item.label }}</span>\n @if (item.children?.length) {\n <span\n class=\"cs-sb__chevron\"\n [class.cs-sb__chevron--open]=\"isExpanded(item.id)\"\n [innerHTML]=\"iconSvg('chevron-down', 18)\"\n aria-hidden=\"true\"\n ></span>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <ul class=\"cs-sb__sublist\">\n @for (child of item.children; track child.id) {\n <li>\n <button\n type=\"button\"\n class=\"cs-sb__row cs-sb__row--sub\"\n [class.cs-sb__row--active]=\"isActive(child.id)\"\n [disabled]=\"child.disabled || null\"\n [attr.aria-current]=\"isActive(child.id) ? 'page' : null\"\n (click)=\"onItemClick(child)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(child.icon, 20, isActive(child.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ child.label }}</span>\n </button>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n</div>\n\n<div class=\"cs-sb__footer\">\n <ul class=\"cs-sb__list\">\n @for (item of footerItems(); track item.id) {\n <li class=\"cs-sb__item\">\n <button\n type=\"button\"\n class=\"cs-sb__row\"\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\n [disabled]=\"item.disabled || null\"\n (click)=\"onItemClick(item)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ item.label }}</span>\n </button>\n </li>\n }\n </ul>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:16.5rem;height:100%;box-sizing:border-box;padding:var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-12);background:var(--surface-surface-container-sys-surface-container-lowest);border-right:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant);font-family:var(--body-small-sys-font-family)}.cs-sb__scroll{flex:1 1 auto;min-height:0;overflow-y:auto;margin-right:calc(var(--spacing-padding-sys-padding-12) * -1);padding-right:var(--spacing-padding-sys-padding-12);scrollbar-width:thin;scrollbar-color:var(--surface-surface-container-sys-surface-container-highest) transparent}.cs-sb__scroll::-webkit-scrollbar{width:var(--sys-size-xxs)}.cs-sb__scroll::-webkit-scrollbar-track{background:transparent}.cs-sb__scroll::-webkit-scrollbar-thumb{background-color:var(--surface-surface-container-sys-surface-container-highest);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thick) solid transparent;background-clip:padding-box;min-height:var(--sys-size-lg)}.cs-sb__scroll::-webkit-scrollbar-thumb:hover{background-color:var(--outline-sys-outline-fixed)}.cs-sb__footer{flex-shrink:0;padding-top:var(--spacing-padding-sys-padding-8);border-top:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);margin-top:var(--spacing-padding-sys-padding-8)}.cs-sb__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cs-sb__divider{height:var(--border-width-sys-stroke-thin);background:var(--outline-sys-outline);margin:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-12)}.cs-sb__item{display:flex;flex-direction:column}.cs-sb__row{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);width:100%;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-16);border:var(--border-width-sys-stroke-thick) solid transparent;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface);font:inherit;font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);font-weight:var(--body-small-sys-font-weight);text-align:left;cursor:pointer;transition:background-color .12s ease-out,color .12s ease-out}.cs-sb__row:hover{background:var(--surface-surface-container-sys-surface-container-low)}.cs-sb__row:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);background:var(--surface-surface-container-sys-surface-container-lowest)}.cs-sb__row:disabled{color:var(--surface-surface-sys-on-surface-variant);opacity:.64;cursor:not-allowed}.cs-sb__row--active,.cs-sb__row--active:hover{background:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);font-weight:var(--body-small-sys-font-weight-emphasized)}.cs-sb__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant)}.cs-sb__row--active .cs-sb__icon{color:var(--surface-surface-sys-on-surface)}.cs-sb__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cs-sb__chevron{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);transition:transform .15s ease-out}.cs-sb__chevron--open{transform:rotate(180deg)}.cs-sb__sublist{list-style:none;margin:var(--spacing-padding-sys-padding-4) 0 0;padding:0 0 0 var(--spacing-padding-sys-padding-24);display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}\n"] }]
102
+ args: [{ selector: 'compsych-sidebar', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], host: { role: 'navigation', 'aria-label': 'Sidebar' }, template: "<div class=\"cs-sb__scroll\">\r\n <ul class=\"cs-sb__list\">\r\n @for (item of items(); track item.id) {\r\n @if (item.dividerBefore) {\r\n <li class=\"cs-sb__divider\" aria-hidden=\"true\"></li>\r\n }\r\n <li class=\"cs-sb__item\">\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row\"\r\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\r\n [disabled]=\"item.disabled || null\"\r\n [attr.aria-current]=\"!item.nonRoute && isActive(item.id) ? 'page' : null\"\r\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ item.label }}</span>\r\n @if (item.children?.length) {\r\n <span\r\n class=\"cs-sb__chevron\"\r\n [class.cs-sb__chevron--open]=\"isExpanded(item.id)\"\r\n [innerHTML]=\"iconSvg('chevron-down', 18)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n </button>\r\n\r\n @if (item.children?.length && isExpanded(item.id)) {\r\n <ul class=\"cs-sb__sublist\">\r\n @for (child of item.children; track child.id) {\r\n <li>\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row cs-sb__row--sub\"\r\n [class.cs-sb__row--active]=\"isActive(child.id)\"\r\n [disabled]=\"child.disabled || null\"\r\n [attr.aria-current]=\"isActive(child.id) ? 'page' : null\"\r\n (click)=\"onItemClick(child)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(child.icon, 20, isActive(child.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ child.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n\r\n<div class=\"cs-sb__footer\">\r\n <ul class=\"cs-sb__list\">\r\n @for (item of footerItems(); track item.id) {\r\n <li class=\"cs-sb__item\">\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row\"\r\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\r\n [disabled]=\"item.disabled || null\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ item.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;width:16.5rem;height:100%;box-sizing:border-box;padding:var(--spacing-padding-sys-padding-16) var(--spacing-padding-sys-padding-12);background:var(--surface-surface-container-sys-surface-container-lowest);border-right:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline-variant);font-family:var(--body-small-sys-font-family)}.cs-sb__scroll{flex:1 1 auto;min-height:0;overflow-y:auto;margin-right:calc(var(--spacing-padding-sys-padding-12) * -1);padding-right:var(--spacing-padding-sys-padding-12);scrollbar-width:thin;scrollbar-color:var(--surface-surface-container-sys-surface-container-highest) transparent}.cs-sb__scroll::-webkit-scrollbar{width:var(--sys-size-xxs)}.cs-sb__scroll::-webkit-scrollbar-track{background:transparent}.cs-sb__scroll::-webkit-scrollbar-thumb{background-color:var(--surface-surface-container-sys-surface-container-highest);border-radius:var(--border-radius-sys-radius-full);border:var(--border-width-sys-stroke-thick) solid transparent;background-clip:padding-box;min-height:var(--sys-size-lg)}.cs-sb__scroll::-webkit-scrollbar-thumb:hover{background-color:var(--outline-sys-outline-fixed)}.cs-sb__footer{flex-shrink:0;padding-top:var(--spacing-padding-sys-padding-8);border-top:var(--border-width-sys-stroke-thin) solid var(--outline-sys-outline);margin-top:var(--spacing-padding-sys-padding-8)}.cs-sb__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}.cs-sb__divider{height:var(--border-width-sys-stroke-thin);background:var(--outline-sys-outline);margin:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-12)}.cs-sb__item{display:flex;flex-direction:column}.cs-sb__row{display:flex;align-items:center;gap:var(--spacing-padding-sys-padding-12);width:100%;padding:var(--spacing-padding-sys-padding-8) var(--spacing-padding-sys-padding-16);border:var(--border-width-sys-stroke-thick) solid transparent;border-radius:var(--border-radius-sys-radius-full);background:transparent;color:var(--surface-surface-sys-on-surface);font:inherit;font-family:var(--body-small-sys-font-family);font-size:var(--body-small-sys-font-size);font-weight:var(--body-small-sys-font-weight);text-align:left;cursor:pointer;transition:background-color .12s ease-out,color .12s ease-out}.cs-sb__row:hover{background:var(--surface-surface-container-sys-surface-container-low)}.cs-sb__row:focus-visible{outline:none;border-color:var(--add-on-primary-fixed-sys-on-primary-fixed-variant);background:var(--surface-surface-container-sys-surface-container-lowest)}.cs-sb__row:disabled{color:var(--surface-surface-sys-on-surface-variant);opacity:.64;cursor:not-allowed}.cs-sb__row--active,.cs-sb__row--active:hover{background:var(--surface-surface-container-sys-surface-container);color:var(--surface-surface-sys-on-surface);font-weight:var(--body-small-sys-font-weight-emphasized)}.cs-sb__icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant)}.cs-sb__row--active .cs-sb__icon{color:var(--surface-surface-sys-on-surface)}.cs-sb__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cs-sb__chevron{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--surface-surface-sys-on-surface-variant);transition:transform .15s ease-out}.cs-sb__chevron--open{transform:rotate(180deg)}.cs-sb__sublist{list-style:none;margin:var(--spacing-padding-sys-padding-4) 0 0;padding:0 0 0 var(--spacing-padding-sys-padding-24);display:flex;flex-direction:column;gap:var(--spacing-padding-sys-padding-4)}\n"] }]
103
103
  }], ctorParameters: () => [{ type: i1.DomSanitizer }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], footerItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerItems", required: false }] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: false }] }, { type: i0.Output, args: ["activeIdChange"] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
104
104
  //# sourceMappingURL=sidebar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/sidebar/sidebar.ts","../../../../../../packages/angular/src/lib/sidebar/sidebar.html"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n model,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\n\nexport interface SidebarItem {\n /** Stable identifier used by `activeId` and emitted by `itemClick`. */\n id: string;\n /** Text label displayed next to the icon. */\n label: string;\n /** Lucide icon name (kebab-case), e.g. `'house'` or `'folder'`. */\n icon: string;\n /** Child items — renders this item as an expandable group with a chevron toggle. Child items cannot have their own children. */\n children?: SidebarItem[];\n /** When true, renders a horizontal divider above this item in the list. */\n dividerBefore?: boolean;\n /** When true, the item is non-interactive — it cannot be clicked and receives no hover or active styling. */\n disabled?: boolean;\n /**\n * When true, clicking the item emits `itemClick` but does not highlight it\n * as active or update `activeId`. Use for action items (e.g. logout)\n * that are not navigation destinations.\n */\n nonRoute?: boolean;\n}\n\n/** Default content from the Figma (node 260:4700). */\nconst DEFAULT_ITEMS: SidebarItem[] = [\n { id: 'home', label: 'Home', icon: 'house' },\n { id: 'connect', label: 'Connect Me', icon: 'message-circle', dividerBefore: true },\n { id: 'guide', label: 'Guide Me', icon: 'compass' },\n { id: 'assess', label: 'Assess Me', icon: 'binoculars' },\n {\n id: 'resources',\n label: 'Resource Library',\n icon: 'folder',\n dividerBefore: true,\n children: [\n { id: 'wellness', label: 'Wellness', icon: 'leaf' },\n { id: 'relationships', label: 'Relationships', icon: 'users' },\n { id: 'work', label: 'Work & Education', icon: 'briefcase' },\n { id: 'financial', label: 'Financial', icon: 'landmark' },\n { id: 'legal', label: 'Legal', icon: 'scale' },\n { id: 'lifestyle', label: 'Lifestyle', icon: 'smile' },\n { id: 'home-auto', label: 'Home & Auto', icon: 'car' },\n { id: 'abroad', label: 'Working Abroad', icon: 'plane' },\n ],\n },\n];\n\nconst DEFAULT_FOOTER: SidebarItem[] = [\n { id: 'location', label: 'Location & Language', icon: 'globe' },\n { id: 'logout', label: 'Logout', icon: 'log-out' },\n];\n\n/**\n * Sidebar — vertical app navigation from the ComPsych Design System.\n *\n * Figma: Core Components — base 260:4700, parts 213:1585.\n *\n * Icon + label items with default / hover / selected / focus / disabled states,\n * section dividers, expandable groups (chevron), and a pinned footer\n * (location & language, logout). Data-driven via `items` / `footerItems`,\n * defaulting to the design's content. All values are sys tokens.\n */\n@Component({\n selector: 'compsych-sidebar',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [],\n templateUrl: './sidebar.html',\n styleUrl: './sidebar.css',\n host: { role: 'navigation', 'aria-label': 'Sidebar' },\n})\nexport class SidebarComponent {\n /** Navigation items rendered in the scrollable main area. Defaults to the standard ComPsych nav set. */\n readonly items = input<SidebarItem[]>(DEFAULT_ITEMS);\n /** Items pinned to the bottom of the sidebar, outside the scroll region. Intended for utility actions such as language selection and logout. */\n readonly footerItems = input<SidebarItem[]>(DEFAULT_FOOTER);\n /** Currently active item id — supports two-way binding via `[(activeId)]`. Updated on click for route items; unchanged for `nonRoute` items. */\n readonly activeId = model<string>('home');\n /**\n * Emitted with the item's `id` whenever a non-disabled, non-group item is clicked.\n * Fires for both route items and `nonRoute` items.\n * Group items (those with `children`) do not emit — they only toggle their expanded state.\n */\n readonly itemClick = output<string>();\n\n private readonly expanded = signal<Set<string>>(new Set());\n\n constructor(private readonly sanitizer: DomSanitizer) {}\n\n isExpanded(id: string): boolean {\n return this.expanded().has(id);\n }\n\n isActive(id: string): boolean {\n return this.activeId() === id;\n }\n\n onItemClick(item: SidebarItem): void {\n if (item.disabled) return;\n if (item.children?.length) {\n this.expanded.update((s) => {\n const next = new Set(s);\n next.has(item.id) ? next.delete(item.id) : next.add(item.id);\n return next;\n });\n return;\n }\n if (item.nonRoute) {\n this.itemClick.emit(item.id);\n return;\n }\n this.activeId.set(item.id);\n }\n\n /**\n * Looks up a Lucide icon by name and injects explicit width/height attributes\n * so the SVG renders at the correct size when injected via [innerHTML].\n * Angular's CSS encapsulation does not add _ngcontent attributes to dynamically\n * injected content, so explicit SVG attributes are the reliable solution.\n */\n iconSvg(name: string, size = 20, strokeWidth = 1.5): SafeHtml {\n let svg = LUCIDE_ICONS[name] ?? '';\n svg = svg.replace('<svg ', `<svg width=\"${size}\" height=\"${size}\" `);\n if (strokeWidth !== 1.5) {\n svg = svg.replace('stroke-width=\"1.5\"', `stroke-width=\"${strokeWidth}\"`);\n }\n return this.sanitizer.bypassSecurityTrustHtml(svg);\n }\n}\n","<div class=\"cs-sb__scroll\">\n <ul class=\"cs-sb__list\">\n @for (item of items(); track item.id) {\n @if (item.dividerBefore) {\n <li class=\"cs-sb__divider\" aria-hidden=\"true\"></li>\n }\n <li class=\"cs-sb__item\">\n <button\n type=\"button\"\n class=\"cs-sb__row\"\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\n [disabled]=\"item.disabled || null\"\n [attr.aria-current]=\"!item.nonRoute && isActive(item.id) ? 'page' : null\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"onItemClick(item)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ item.label }}</span>\n @if (item.children?.length) {\n <span\n class=\"cs-sb__chevron\"\n [class.cs-sb__chevron--open]=\"isExpanded(item.id)\"\n [innerHTML]=\"iconSvg('chevron-down', 18)\"\n aria-hidden=\"true\"\n ></span>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <ul class=\"cs-sb__sublist\">\n @for (child of item.children; track child.id) {\n <li>\n <button\n type=\"button\"\n class=\"cs-sb__row cs-sb__row--sub\"\n [class.cs-sb__row--active]=\"isActive(child.id)\"\n [disabled]=\"child.disabled || null\"\n [attr.aria-current]=\"isActive(child.id) ? 'page' : null\"\n (click)=\"onItemClick(child)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(child.icon, 20, isActive(child.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ child.label }}</span>\n </button>\n </li>\n }\n </ul>\n }\n </li>\n }\n </ul>\n</div>\n\n<div class=\"cs-sb__footer\">\n <ul class=\"cs-sb__list\">\n @for (item of footerItems(); track item.id) {\n <li class=\"cs-sb__item\">\n <button\n type=\"button\"\n class=\"cs-sb__row\"\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\n [disabled]=\"item.disabled || null\"\n (click)=\"onItemClick(item)\"\n >\n <span\n class=\"cs-sb__icon\"\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"cs-sb__label\">{{ item.label }}</span>\n </button>\n </li>\n }\n </ul>\n</div>\n"]}
1
+ {"version":3,"file":"sidebar.js","sourceRoot":"","sources":["../../../../../../packages/angular/src/lib/sidebar/sidebar.ts","../../../../../../packages/angular/src/lib/sidebar/sidebar.html"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,KAAK,EACL,KAAK,EACL,MAAM,EACN,MAAM,GACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,8DAA8D,CAAC;;;AAuB5F,sDAAsD;AACtD,MAAM,aAAa,GAAkB;IACnC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;IAC5C,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE,aAAa,EAAE,IAAI,EAAE;IACnF,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;IACnD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE;IACxD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,QAAQ;QACd,aAAa,EAAE,IAAI;QACnB,QAAQ,EAAE;YACR,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;YACnD,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE;YAC9D,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,EAAE;YAC5D,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE;YACzD,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE;YAC9C,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE;YACtD,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE;YACtD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE;SACzD;KACF;CACF,CAAC;AAEF,MAAM,cAAc,GAAkB;IACpC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,OAAO,EAAE;IAC/D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;CACnD,CAAC;AAEF;;;;;;;;;GASG;AAUH,MAAM,OAAO,gBAAgB;IAgBE;IAf7B,wGAAwG;IAC/F,KAAK,GAAG,KAAK,CAAgB,aAAa,4EAAC,CAAC;IACrD,gJAAgJ;IACvI,WAAW,GAAG,KAAK,CAAgB,cAAc,kFAAC,CAAC;IAC5D,gJAAgJ;IACvI,QAAQ,GAAG,KAAK,CAAS,MAAM,+EAAC,CAAC;IAC1C;;;;OAIG;IACM,SAAS,GAAG,MAAM,EAAU,CAAC;IAErB,QAAQ,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,+EAAC,CAAC;IAE3D,YAA6B,SAAuB;QAAvB,cAAS,GAAT,SAAS,CAAc;IAAG,CAAC;IAExD,UAAU,CAAC,EAAU;QACnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,QAAQ,CAAC,EAAU;QACjB,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChC,CAAC;IAED,WAAW,CAAC,IAAiB;QAC3B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBACzB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;gBACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAY,EAAE,IAAI,GAAG,EAAE,EAAE,WAAW,GAAG,GAAG;QAChD,IAAI,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,IAAI,aAAa,IAAI,IAAI,CAAC,CAAC;QACrE,IAAI,WAAW,KAAK,GAAG,EAAE,CAAC;YACxB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,iBAAiB,WAAW,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;wGAxDU,gBAAgB;4FAAhB,gBAAgB,qmBChF7B,wlGAkFA;;4FDFa,gBAAgB;kBAT5B,SAAS;+BACE,kBAAkB,cAChB,IAAI,mBACC,uBAAuB,CAAC,MAAM,WACtC,EAAE,QAGL,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE","sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n model,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { LUCIDE_ICONS } from '@compsych-ui-components/shared/assets/lucide-icons.generated';\r\n\r\nexport interface SidebarItem {\r\n /** Stable identifier used by `activeId` and emitted by `itemClick`. */\r\n id: string;\r\n /** Text label displayed next to the icon. */\r\n label: string;\r\n /** Lucide icon name (kebab-case), e.g. `'house'` or `'folder'`. */\r\n icon: string;\r\n /** Child items — renders this item as an expandable group with a chevron toggle. Child items cannot have their own children. */\r\n children?: SidebarItem[];\r\n /** When true, renders a horizontal divider above this item in the list. */\r\n dividerBefore?: boolean;\r\n /** When true, the item is non-interactive — it cannot be clicked and receives no hover or active styling. */\r\n disabled?: boolean;\r\n /**\r\n * When true, clicking the item emits `itemClick` but does not highlight it\r\n * as active or update `activeId`. Use for action items (e.g. logout)\r\n * that are not navigation destinations.\r\n */\r\n nonRoute?: boolean;\r\n}\r\n\r\n/** Default content from the Figma (node 260:4700). */\r\nconst DEFAULT_ITEMS: SidebarItem[] = [\r\n { id: 'home', label: 'Home', icon: 'house' },\r\n { id: 'connect', label: 'Connect Me', icon: 'message-circle', dividerBefore: true },\r\n { id: 'guide', label: 'Guide Me', icon: 'compass' },\r\n { id: 'assess', label: 'Assess Me', icon: 'binoculars' },\r\n {\r\n id: 'resources',\r\n label: 'Resource Library',\r\n icon: 'folder',\r\n dividerBefore: true,\r\n children: [\r\n { id: 'wellness', label: 'Wellness', icon: 'leaf' },\r\n { id: 'relationships', label: 'Relationships', icon: 'users' },\r\n { id: 'work', label: 'Work & Education', icon: 'briefcase' },\r\n { id: 'financial', label: 'Financial', icon: 'landmark' },\r\n { id: 'legal', label: 'Legal', icon: 'scale' },\r\n { id: 'lifestyle', label: 'Lifestyle', icon: 'smile' },\r\n { id: 'home-auto', label: 'Home & Auto', icon: 'car' },\r\n { id: 'abroad', label: 'Working Abroad', icon: 'plane' },\r\n ],\r\n },\r\n];\r\n\r\nconst DEFAULT_FOOTER: SidebarItem[] = [\r\n { id: 'location', label: 'Location & Language', icon: 'globe' },\r\n { id: 'logout', label: 'Logout', icon: 'log-out' },\r\n];\r\n\r\n/**\r\n * Sidebar — vertical app navigation from the ComPsych Design System.\r\n *\r\n * Figma: Core Components — base 260:4700, parts 213:1585.\r\n *\r\n * Icon + label items with default / hover / selected / focus / disabled states,\r\n * section dividers, expandable groups (chevron), and a pinned footer\r\n * (location & language, logout). Data-driven via `items` / `footerItems`,\r\n * defaulting to the design's content. All values are sys tokens.\r\n */\r\n@Component({\r\n selector: 'compsych-sidebar',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n imports: [],\r\n templateUrl: './sidebar.html',\r\n styleUrl: './sidebar.css',\r\n host: { role: 'navigation', 'aria-label': 'Sidebar' },\r\n})\r\nexport class SidebarComponent {\r\n /** Navigation items rendered in the scrollable main area. Defaults to the standard ComPsych nav set. */\r\n readonly items = input<SidebarItem[]>(DEFAULT_ITEMS);\r\n /** Items pinned to the bottom of the sidebar, outside the scroll region. Intended for utility actions such as language selection and logout. */\r\n readonly footerItems = input<SidebarItem[]>(DEFAULT_FOOTER);\r\n /** Currently active item id — supports two-way binding via `[(activeId)]`. Updated on click for route items; unchanged for `nonRoute` items. */\r\n readonly activeId = model<string>('home');\r\n /**\r\n * Emitted with the item's `id` whenever a non-disabled, non-group item is clicked.\r\n * Fires for both route items and `nonRoute` items.\r\n * Group items (those with `children`) do not emit — they only toggle their expanded state.\r\n */\r\n readonly itemClick = output<string>();\r\n\r\n private readonly expanded = signal<Set<string>>(new Set());\r\n\r\n constructor(private readonly sanitizer: DomSanitizer) {}\r\n\r\n isExpanded(id: string): boolean {\r\n return this.expanded().has(id);\r\n }\r\n\r\n isActive(id: string): boolean {\r\n return this.activeId() === id;\r\n }\r\n\r\n onItemClick(item: SidebarItem): void {\r\n if (item.disabled) return;\r\n if (item.children?.length) {\r\n this.expanded.update((s) => {\r\n const next = new Set(s);\r\n next.has(item.id) ? next.delete(item.id) : next.add(item.id);\r\n return next;\r\n });\r\n return;\r\n }\r\n if (item.nonRoute) {\r\n this.itemClick.emit(item.id);\r\n return;\r\n }\r\n this.activeId.set(item.id);\r\n }\r\n\r\n /**\r\n * Looks up a Lucide icon by name and injects explicit width/height attributes\r\n * so the SVG renders at the correct size when injected via [innerHTML].\r\n * Angular's CSS encapsulation does not add _ngcontent attributes to dynamically\r\n * injected content, so explicit SVG attributes are the reliable solution.\r\n */\r\n iconSvg(name: string, size = 20, strokeWidth = 1.5): SafeHtml {\r\n let svg = LUCIDE_ICONS[name] ?? '';\r\n svg = svg.replace('<svg ', `<svg width=\"${size}\" height=\"${size}\" `);\r\n if (strokeWidth !== 1.5) {\r\n svg = svg.replace('stroke-width=\"1.5\"', `stroke-width=\"${strokeWidth}\"`);\r\n }\r\n return this.sanitizer.bypassSecurityTrustHtml(svg);\r\n }\r\n}\r\n","<div class=\"cs-sb__scroll\">\r\n <ul class=\"cs-sb__list\">\r\n @for (item of items(); track item.id) {\r\n @if (item.dividerBefore) {\r\n <li class=\"cs-sb__divider\" aria-hidden=\"true\"></li>\r\n }\r\n <li class=\"cs-sb__item\">\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row\"\r\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\r\n [disabled]=\"item.disabled || null\"\r\n [attr.aria-current]=\"!item.nonRoute && isActive(item.id) ? 'page' : null\"\r\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ item.label }}</span>\r\n @if (item.children?.length) {\r\n <span\r\n class=\"cs-sb__chevron\"\r\n [class.cs-sb__chevron--open]=\"isExpanded(item.id)\"\r\n [innerHTML]=\"iconSvg('chevron-down', 18)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n }\r\n </button>\r\n\r\n @if (item.children?.length && isExpanded(item.id)) {\r\n <ul class=\"cs-sb__sublist\">\r\n @for (child of item.children; track child.id) {\r\n <li>\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row cs-sb__row--sub\"\r\n [class.cs-sb__row--active]=\"isActive(child.id)\"\r\n [disabled]=\"child.disabled || null\"\r\n [attr.aria-current]=\"isActive(child.id) ? 'page' : null\"\r\n (click)=\"onItemClick(child)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(child.icon, 20, isActive(child.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ child.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n\r\n<div class=\"cs-sb__footer\">\r\n <ul class=\"cs-sb__list\">\r\n @for (item of footerItems(); track item.id) {\r\n <li class=\"cs-sb__item\">\r\n <button\r\n type=\"button\"\r\n class=\"cs-sb__row\"\r\n [class.cs-sb__row--active]=\"!item.nonRoute && isActive(item.id)\"\r\n [disabled]=\"item.disabled || null\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <span\r\n class=\"cs-sb__icon\"\r\n [innerHTML]=\"iconSvg(item.icon, 20, !item.nonRoute && isActive(item.id) ? 2 : 1.5)\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n <span class=\"cs-sb__label\">{{ item.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n"]}
@@ -2,8 +2,8 @@ import { AfterViewInit, OnDestroy } from '@angular/core';
2
2
  import { FocusOrigin } from '@angular/cdk/a11y';
3
3
  import { BooleanInput } from '@angular/cdk/coercion';
4
4
  import * as i0 from "@angular/core";
5
- /** Visual style of a `compsych-button`. Controls color, border, and elevation. Icon variants (e.g. `'filled-icon'`) are used by `NavAction` to render icon buttons in the header nav and are not handled by the button component itself. */
6
- export type ButtonVariant = 'filled' | 'tonal' | 'outlined' | 'elevated' | 'text' | 'danger' | 'danger-outlined' | 'filled-icon' | 'tonal-icon' | 'outlined-icon' | 'elevated-icon' | 'text-icon' | 'danger-icon' | 'danger-outlined-icon';
5
+ /** Visual style of a `compsych-button`. Controls color, border, and elevation. */
6
+ export type ButtonVariant = 'filled' | 'tonal' | 'outlined' | 'elevated' | 'text' | 'danger' | 'danger-outlined';
7
7
  export declare class ButtonComponent implements AfterViewInit, OnDestroy {
8
8
  private readonly focusMonitor;
9
9
  private readonly elementRef;
@@ -4,43 +4,43 @@ import { ButtonVariant } from '../button/button';
4
4
  import * as i0 from "@angular/core";
5
5
  export type HeaderNavLevel = 'main' | 'sub-page' | 'not-logged';
6
6
  /**
7
- * A navigation item used for breadcrumbs, labeled buttons, and icon buttons.
8
- * - Breadcrumb: provide `id`, `label`, and any `variant` (variant is unused during breadcrumb rendering).
9
- * - Icon button: provide `id`, an icon `variant` (e.g. `'filled-icon'`), `icon` (Lucide name), and optionally `label` (used as aria-label).
10
- * - Labeled button: provide `id`, a non-icon `variant`, and `label`.
7
+ * A navigation item used for both breadcrumbs and action buttons.
8
+ * - Breadcrumb: provide `id` and `label`.
9
+ * - Action button: provide `id`, `label`, and optionally `variant`.
11
10
  */
12
11
  export interface NavAction {
13
12
  /** Stable identifier emitted by the `action` output when this item is clicked. */
14
13
  id: string;
15
- /** Text displayed in the breadcrumb trail, on the button, or as aria-label for icon buttons. */
16
- label?: string;
17
- /** Lucide icon name. Required when `variant` is an icon variant (e.g. `'filled-icon'`). */
18
- icon?: string;
19
- /** Button style. Icon variants (e.g. `'filled-icon'`) render an icon button; all others render a labeled button. */
20
- variant: ButtonVariant;
14
+ /** Text displayed in the breadcrumb trail or on the action button. */
15
+ label: string;
16
+ /** Button style for action buttons. Defaults to `'filled'` when omitted. Not used for breadcrumbs. */
17
+ variant?: ButtonVariant;
21
18
  }
22
19
  /**
23
20
  * Header Navigation — top app bar from the ComPsych Design System.
24
21
  *
25
22
  * Three layout levels controlled by `level`:
26
- * - `'main'` — menu toggle, brand logo + wordmark, action buttons.
27
- * - `'sub-page'` — menu toggle, logo mark + breadcrumb trail, action buttons.
28
- * - `'not-logged'` — menu toggle, brand, action buttons.
23
+ * - `'main'` — menu toggle, brand logo + wordmark, logged-in action cluster.
24
+ * - `'sub-page'` — menu toggle, logo mark + breadcrumb trail, logged-in action cluster.
25
+ * - `'not-logged'` — menu toggle, brand, public action cluster (language, help, CTA buttons).
29
26
  *
30
- * Icon and labeled buttons in the right action area are configured via `actionButtons`.
31
27
  * All interactive elements emit a string id via the `action` output.
28
+ * For breadcrumbs and action buttons the emitted value is the `NavAction.id`.
29
+ * For built-in icon buttons a fixed string is emitted (see `action` docs).
32
30
  */
33
31
  export declare class HeaderNavComponent {
34
32
  private readonly sanitizer;
35
33
  /**
36
- * Layout of the header left region.
37
- * - `'main'` — logo + brand label.
38
- * - `'sub-page'` — symbol mark + breadcrumb trail.
39
- * - `'not-logged'` — logo + brand label.
34
+ * Layout and feature set of the header.
35
+ * - `'main'` — logo + brand label, logged-in action cluster (search, notifications, documents, language, avatar, logout).
36
+ * - `'sub-page'` — symbol mark + breadcrumb trail, same logged-in action cluster.
37
+ * - `'not-logged'` — logo + brand label, public action cluster (language, help, action buttons).
40
38
  */
41
39
  level: HeaderNavLevel;
42
40
  /** Whether the paired sidebar is open — toggles the menu icon (☰ ↔ ✕). */
43
41
  sidebarOpen: boolean;
42
+ /** Show the hamburger / close menu toggle button. */
43
+ showMenuToggle: boolean;
44
44
  /** Accessible label for the brand area (logo + wordmark) used by screen readers. */
45
45
  brandLabelAria: string;
46
46
  /** Brand wordmark text rendered next to the logo on `main` and `not-logged` levels. */
@@ -60,10 +60,29 @@ export declare class HeaderNavComponent {
60
60
  * via the `action` output when clicked.
61
61
  */
62
62
  breadcrumbs: NavAction[];
63
+ /** Notification badge count. Badge is hidden when 0. */
64
+ notificationCount: number;
65
+ /** Avatar initials for the logged-in user. */
66
+ avatarInitials: string;
67
+ /** Show the search icon button (logged-in levels). */
68
+ showSearch: boolean;
69
+ /** Show the calendar-check icon button (logged-in levels). */
70
+ showCalendarChecked: boolean;
71
+ /** Show the notifications icon button (logged-in levels). */
72
+ showNotifications: boolean;
73
+ /** Show the documents icon button (logged-in levels). */
74
+ showDocuments: boolean;
75
+ /** Show the avatar button (logged-in levels). */
76
+ showAvatar: boolean;
77
+ /** Show the language icon button (main, sub-page, and not-logged levels). */
78
+ showLanguage: boolean;
79
+ /** Show the help icon button (not-logged level). */
80
+ showHelp: boolean;
81
+ /** Show the logout icon button (main and sub-page levels). */
82
+ showLogout: boolean;
63
83
  /**
64
- * Buttons rendered in the right action area.
65
- * - When `variant` ends in `'-icon'`, renders an icon button using `icon` as the Lucide name; `label` is used as aria-label.
66
- * - Otherwise, renders a labeled `<compsych-button>` using `label` and `variant`.
84
+ * Additional configurable buttons rendered in the actions area.
85
+ * Each entry requires `id` and `label`; `variant` defaults to `'filled'`.
67
86
  * Clicking any button emits its `id` via the `action` output.
68
87
  */
69
88
  actionButtons: NavAction[];
@@ -72,18 +91,40 @@ export declare class HeaderNavComponent {
72
91
  * Fixed values for built-in controls:
73
92
  * - `'menu-toggle'` — hamburger / close button
74
93
  * - `'logo'` — brand / logo button
94
+ * - `'search'` — search icon button
95
+ * - `'calendar-checked'` — calendar-check icon button
96
+ * - `'notifications'` — notifications icon button
97
+ * - `'documents'` — documents icon button
98
+ * - `'language'` — language icon button
99
+ * - `'help'` — help icon button
100
+ * - `'avatar'` — avatar button
101
+ * - `'logout'` — logout icon button
75
102
  *
76
103
  * For `breadcrumbs` and `actionButtons` items, the item's `NavAction.id` is emitted.
77
104
  */
78
105
  readonly action: EventEmitter<string>;
106
+ readonly searchIconSvg: SafeHtml;
107
+ readonly calendarCheckedIconSvg: SafeHtml;
108
+ readonly bellIconSvg: SafeHtml;
109
+ readonly fileTextIconSvg: SafeHtml;
110
+ readonly globeIconSvg: SafeHtml;
111
+ readonly helpIconSvg: SafeHtml;
112
+ readonly logOutIconSvg: SafeHtml;
113
+ readonly userIconSvg: SafeHtml;
79
114
  constructor(sanitizer: DomSanitizer);
115
+ get isLoggedOut(): boolean;
80
116
  get isSubPage(): boolean;
81
117
  get menuIconSvg(): SafeHtml;
118
+ get badgeText(): string;
119
+ get notificationAriaLabel(): string;
82
120
  /**
83
- * Returns a trusted SVG for the given Lucide icon name, sized at 20 × 20.
84
- * Used in the template for dynamic icon buttons via `actionButtons`.
121
+ * Looks up a Lucide icon by name and injects explicit width/height attributes
122
+ * (20 × 20) so the SVG renders at the correct size when injected via [innerHTML].
123
+ * Angular's CSS encapsulation does not add _ngcontent attributes to dynamically
124
+ * injected content, so CSS descendant selectors targeting `svg` would not apply —
125
+ * explicit SVG attributes are the reliable solution.
85
126
  */
86
- iconSvg(name: string): SafeHtml;
127
+ private trustedIcon;
87
128
  static ɵfac: i0.ɵɵFactoryDeclaration<HeaderNavComponent, never>;
88
- static ɵcmp: i0.ɵɵComponentDeclaration<HeaderNavComponent, "compsych-header-nav", never, { "level": { "alias": "level"; "required": false; }; "sidebarOpen": { "alias": "sidebarOpen"; "required": false; }; "brandLabelAria": { "alias": "brandLabelAria"; "required": false; }; "brandLabel": { "alias": "brandLabel"; "required": false; }; "brandLabelColor": { "alias": "brandLabelColor"; "required": false; }; "clientLogoUrl": { "alias": "clientLogoUrl"; "required": false; }; "breadcrumbs": { "alias": "breadcrumbs"; "required": false; }; "actionButtons": { "alias": "actionButtons"; "required": false; }; }, { "action": "action"; }, never, never, true, never>;
129
+ static ɵcmp: i0.ɵɵComponentDeclaration<HeaderNavComponent, "compsych-header-nav", never, { "level": { "alias": "level"; "required": false; }; "sidebarOpen": { "alias": "sidebarOpen"; "required": false; }; "showMenuToggle": { "alias": "showMenuToggle"; "required": false; }; "brandLabelAria": { "alias": "brandLabelAria"; "required": false; }; "brandLabel": { "alias": "brandLabel"; "required": false; }; "brandLabelColor": { "alias": "brandLabelColor"; "required": false; }; "clientLogoUrl": { "alias": "clientLogoUrl"; "required": false; }; "breadcrumbs": { "alias": "breadcrumbs"; "required": false; }; "notificationCount": { "alias": "notificationCount"; "required": false; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; }; "showSearch": { "alias": "showSearch"; "required": false; }; "showCalendarChecked": { "alias": "showCalendarChecked"; "required": false; }; "showNotifications": { "alias": "showNotifications"; "required": false; }; "showDocuments": { "alias": "showDocuments"; "required": false; }; "showAvatar": { "alias": "showAvatar"; "required": false; }; "showLanguage": { "alias": "showLanguage"; "required": false; }; "showHelp": { "alias": "showHelp"; "required": false; }; "showLogout": { "alias": "showLogout"; "required": false; }; "actionButtons": { "alias": "actionButtons"; "required": false; }; }, { "action": "action"; }, never, never, true, never>;
89
130
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compsych-ui-components/angular",
3
- "version": "6.0.10",
3
+ "version": "6.1.0",
4
4
  "description": "Angular UI components for compsych",
5
5
  "publishConfig": {
6
6
  "access": "public",