ngx-dev-toolbar 4.2.0 → 4.3.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,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, inject, signal, computed, model, input, ChangeDetectionStrategy, Component, output, viewChild, contentChild, effect, HostListener, DestroyRef, ViewEncapsulation, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, ApplicationRef, EnvironmentInjector, createComponent, TemplateRef, Directive, contentChildren } from '@angular/core';
3
- import { CommonModule, DOCUMENT, NgTemplateOutlet } from '@angular/common';
2
+ import { InjectionToken, Injectable, inject, signal, computed, input, output, ChangeDetectionStrategy, Component, ElementRef, model, viewChild, contentChild, effect, HostListener, DestroyRef, ViewContainerRef, ViewEncapsulation, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, ApplicationRef, EnvironmentInjector, createComponent, TemplateRef, Directive, contentChildren } from '@angular/core';
3
+ import { CommonModule, NgTemplateOutlet, DOCUMENT } from '@angular/common';
4
4
  import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
5
  import { BehaviorSubject, combineLatest, map, firstValueFrom, fromEvent } from 'rxjs';
6
6
  import { filter, throttleTime } from 'rxjs/operators';
7
- import * as i1 from '@angular/forms';
7
+ import * as i1$1 from '@angular/forms';
8
8
  import { FormsModule } from '@angular/forms';
9
9
  import * as i2 from '@angular/cdk/menu';
10
10
  import { CdkMenuModule } from '@angular/cdk/menu';
11
- import * as i1$1 from '@angular/cdk/overlay';
11
+ import * as i1 from '@angular/cdk/overlay';
12
12
  import { OverlayModule, CdkConnectedOverlay } from '@angular/cdk/overlay';
13
13
 
14
14
  /**
@@ -69,6 +69,29 @@ const TOOLBAR_PERMISSIONS = new InjectionToken('TOOLBAR_PERMISSIONS');
69
69
  * ```
70
70
  */
71
71
  const TOOLBAR_APP_FEATURES = new InjectionToken('TOOLBAR_APP_FEATURES');
72
+ /**
73
+ * InjectionToken for registering custom tool components with the toolbar.
74
+ *
75
+ * Custom tools are Angular components that extend the toolbar with app-specific
76
+ * functionality. They are dynamically rendered inside the toolbar at runtime.
77
+ *
78
+ * Use `provideToolbarCustomTools()` to register custom tool components.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // app.config.ts
83
+ * import { provideToolbar, provideToolbarCustomTools } from 'ngx-dev-toolbar';
84
+ * import { MyCustomToolComponent } from './my-custom-tool.component';
85
+ *
86
+ * export const appConfig: ApplicationConfig = {
87
+ * providers: [
88
+ * provideToolbar({ ... }),
89
+ * provideToolbarCustomTools(MyCustomToolComponent),
90
+ * ],
91
+ * };
92
+ * ```
93
+ */
94
+ const TOOLBAR_CUSTOM_TOOLS = new InjectionToken('TOOLBAR_CUSTOM_TOOLS');
72
95
 
73
96
  class ToolbarStorageService {
74
97
  constructor() {
@@ -279,126 +302,80 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
279
302
  }]
280
303
  }], ctorParameters: () => [] });
281
304
 
282
- class ToolbarInputComponent {
283
- constructor() {
284
- this.value = model.required();
285
- this.type = input('text');
286
- this.placeholder = input('');
287
- this.ariaLabel = input('');
288
- this.inputClass = input('input');
289
- }
290
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
291
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.7", type: ToolbarInputComponent, isStandalone: true, selector: "ndt-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, inputClass: { classPropertyName: "inputClass", publicName: "inputClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
292
- <input
293
- [attr.aria-label]="ariaLabel()"
294
- [type]="type()"
295
- [class]="inputClass()"
296
- [ngModel]="value()"
297
- [placeholder]="placeholder()"
298
- (ngModelChange)="value.set($event)"
299
- />
300
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block}.input{width:100%;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:var(--ndt-transition-default);box-sizing:border-box;min-height:28px}.input::placeholder{color:var(--ndt-text-muted)}.input:focus{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.input:disabled{background-color:var(--ndt-bg-secondary);cursor:not-allowed;color:var(--ndt-text-muted)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
301
- }
302
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarInputComponent, decorators: [{
303
- type: Component,
304
- args: [{ selector: 'ndt-input', standalone: true, imports: [FormsModule], template: `
305
- <input
306
- [attr.aria-label]="ariaLabel()"
307
- [type]="type()"
308
- [class]="inputClass()"
309
- [ngModel]="value()"
310
- [placeholder]="placeholder()"
311
- (ngModelChange)="value.set($event)"
312
- />
313
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block}.input{width:100%;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:var(--ndt-transition-default);box-sizing:border-box;min-height:28px}.input::placeholder{color:var(--ndt-text-muted)}.input:focus{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.input:disabled{background-color:var(--ndt-bg-secondary);cursor:not-allowed;color:var(--ndt-text-muted)}\n"] }]
314
- }] });
315
-
316
305
  /**
317
- * Container component for displaying lists of items with consistent scrolling,
318
- * empty states, and layout across all tools.
306
+ * Collapsible group header that wraps a section of list items.
307
+ *
308
+ * Renders a clickable header with the group name + item count + a chevron
309
+ * indicating collapsed/expanded state. Children projected via `<ng-content>`
310
+ * are hidden when collapsed.
319
311
  *
320
312
  * @example
321
313
  * ```html
322
- * <ndt-list
323
- * [hasItems]="items().length > 0"
324
- * [hasResults]="filteredItems().length > 0"
325
- * emptyMessage="No items found"
326
- * noResultsMessage="No items match your filter"
314
+ * <ndt-list-group
315
+ * name="Authentication"
316
+ * [count]="3"
317
+ * [collapsed]="isCollapsed"
318
+ * (collapsedChange)="onToggle($event)"
327
319
  * >
328
- * @for (item of filteredItems(); track item.id) {
329
- * <ndt-list-item ... />
330
- * }
331
- * </ndt-list>
320
+ * <ndt-list-item ... />
321
+ * </ndt-list-group>
332
322
  * ```
333
323
  */
334
- class ToolbarListComponent {
324
+ class ToolbarListGroupComponent {
335
325
  constructor() {
336
- /**
337
- * Whether the list has any items at all (before filtering).
338
- * When false, shows the emptyMessage.
339
- */
340
- this.hasItems = input(true);
341
- /**
342
- * Whether the list has any results after filtering.
343
- * When false (but hasItems is true), shows the noResultsMessage.
344
- */
345
- this.hasResults = input(true);
346
- /**
347
- * Message to display when there are no items at all.
348
- * @example "No feature flags found"
349
- */
350
- this.emptyMessage = input('No items found');
351
- /**
352
- * Optional hint text to display below the empty message.
353
- * @example "Call setAvailableOptions() to configure features"
354
- */
355
- this.emptyHint = input(undefined);
356
- /**
357
- * Message to display when items exist but none match the current filter.
358
- * @example "No flags match your filter"
359
- */
360
- this.noResultsMessage = input('No results match your filter');
326
+ /** Display name of the group, shown in the header. */
327
+ this.name = input.required();
328
+ /** Number of items in the group, shown next to the name. */
329
+ this.count = input.required();
330
+ /** Whether the group is currently collapsed. */
331
+ this.collapsed = input(false);
332
+ /** Emits the new collapsed value when the user clicks the header. */
333
+ this.collapsedChange = output();
334
+ this.ariaLabel = computed(() => `${this.collapsed() ? 'Expand' : 'Collapse'} ${this.name()} group, ${this.count()} items`);
361
335
  }
362
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
363
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarListComponent, isStandalone: true, selector: "ndt-list", inputs: { hasItems: { classPropertyName: "hasItems", publicName: "hasItems", isSignal: true, isRequired: false, transformFunction: null }, hasResults: { classPropertyName: "hasResults", publicName: "hasResults", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyHint: { classPropertyName: "emptyHint", publicName: "emptyHint", isSignal: true, isRequired: false, transformFunction: null }, noResultsMessage: { classPropertyName: "noResultsMessage", publicName: "noResultsMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
364
- @if (!hasItems()) {
365
- <div class="empty-state">
366
- <p>{{ emptyMessage() }}</p>
367
- @if (emptyHint()) {
368
- <p class="hint">{{ emptyHint() }}</p>
369
- }
370
- </div>
371
- } @else if (!hasResults()) {
372
- <div class="empty-state">
373
- <p>{{ noResultsMessage() }}</p>
374
- </div>
375
- } @else {
376
- <div class="list-container">
336
+ toggle() {
337
+ this.collapsedChange.emit(!this.collapsed());
338
+ }
339
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
340
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarListGroupComponent, isStandalone: true, selector: "ndt-list-group", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: true, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsedChange: "collapsedChange" }, ngImport: i0, template: `
341
+ <button
342
+ type="button"
343
+ class="header"
344
+ [attr.aria-expanded]="!collapsed()"
345
+ [attr.aria-label]="ariaLabel()"
346
+ (click)="toggle()"
347
+ >
348
+ <span class="chevron" [class.chevron--expanded]="!collapsed()" aria-hidden="true"></span>
349
+ <span class="name">{{ name() }}</span>
350
+ <span class="count" aria-hidden="true">{{ count() }}</span>
351
+ </button>
352
+ @if (!collapsed()) {
353
+ <div class="content">
377
354
  <ng-content />
378
355
  </div>
379
356
  }
380
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:flex;flex-direction:column;flex:1;min-height:0}.empty-state{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:var(--ndt-background-secondary);color:var(--ndt-text-muted)}.empty-state p{margin:0}.empty-state .hint{font-size:var(--ndt-font-size-xs)}.list-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;max-height:100%;overflow-y:auto;overflow-x:hidden;position:relative;scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.list-container::-webkit-scrollbar{width:8px;height:8px}.list-container::-webkit-scrollbar-track{background:transparent}.list-container::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.list-container::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
357
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex-shrink:0}.header{display:flex;align-items:center;gap:var(--ndt-spacing-xs);width:100%;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);background:transparent;border:none;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-secondary);font-family:inherit;font-size:var(--ndt-font-size-xs);font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;text-align:left;transition:background-color .16s ease-out,color .16s ease-out}.header:hover{background:var(--ndt-background-secondary);color:var(--ndt-text-primary)}.header:focus-visible{outline:2px solid var(--ndt-accent, var(--ndt-text-primary));outline-offset:2px}.chevron{flex:0 0 auto;display:inline-block;width:0;height:0;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:5px solid currentColor;transition:transform .18s cubic-bezier(.22,1,.36,1)}.chevron--expanded{transform:rotate(90deg)}@media (prefers-reduced-motion: reduce){.chevron{transition:none}}.name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.count{flex:0 0 auto;font-variant-numeric:tabular-nums;font-weight:500;color:var(--ndt-text-muted)}.content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);margin-top:var(--ndt-spacing-xs)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
381
358
  }
382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListComponent, decorators: [{
359
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListGroupComponent, decorators: [{
383
360
  type: Component,
384
- args: [{ selector: 'ndt-list', standalone: true, imports: [CommonModule], template: `
385
- @if (!hasItems()) {
386
- <div class="empty-state">
387
- <p>{{ emptyMessage() }}</p>
388
- @if (emptyHint()) {
389
- <p class="hint">{{ emptyHint() }}</p>
390
- }
391
- </div>
392
- } @else if (!hasResults()) {
393
- <div class="empty-state">
394
- <p>{{ noResultsMessage() }}</p>
395
- </div>
396
- } @else {
397
- <div class="list-container">
361
+ args: [{ selector: 'ndt-list-group', standalone: true, template: `
362
+ <button
363
+ type="button"
364
+ class="header"
365
+ [attr.aria-expanded]="!collapsed()"
366
+ [attr.aria-label]="ariaLabel()"
367
+ (click)="toggle()"
368
+ >
369
+ <span class="chevron" [class.chevron--expanded]="!collapsed()" aria-hidden="true"></span>
370
+ <span class="name">{{ name() }}</span>
371
+ <span class="count" aria-hidden="true">{{ count() }}</span>
372
+ </button>
373
+ @if (!collapsed()) {
374
+ <div class="content">
398
375
  <ng-content />
399
376
  </div>
400
377
  }
401
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:flex;flex-direction:column;flex:1;min-height:0}.empty-state{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:var(--ndt-background-secondary);color:var(--ndt-text-muted)}.empty-state p{margin:0}.empty-state .hint{font-size:var(--ndt-font-size-xs)}.list-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;max-height:100%;overflow-y:auto;overflow-x:hidden;position:relative;scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.list-container::-webkit-scrollbar{width:8px;height:8px}.list-container::-webkit-scrollbar-track{background:transparent}.list-container::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.list-container::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}\n"] }]
378
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex-shrink:0}.header{display:flex;align-items:center;gap:var(--ndt-spacing-xs);width:100%;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);background:transparent;border:none;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-secondary);font-family:inherit;font-size:var(--ndt-font-size-xs);font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;text-align:left;transition:background-color .16s ease-out,color .16s ease-out}.header:hover{background:var(--ndt-background-secondary);color:var(--ndt-text-primary)}.header:focus-visible{outline:2px solid var(--ndt-accent, var(--ndt-text-primary));outline-offset:2px}.chevron{flex:0 0 auto;display:inline-block;width:0;height:0;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:5px solid currentColor;transition:transform .18s cubic-bezier(.22,1,.36,1)}.chevron--expanded{transform:rotate(90deg)}@media (prefers-reduced-motion: reduce){.chevron{transition:none}}.name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.count{flex:0 0 auto;font-variant-numeric:tabular-nums;font-weight:500;color:var(--ndt-text-muted)}.content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);margin-top:var(--ndt-spacing-xs)}\n"] }]
402
379
  }] });
403
380
 
404
381
  class AngularIconComponent {
@@ -2050,7 +2027,7 @@ class ToolbarIconButtonComponent {
2050
2027
  }
2051
2028
  <ng-content />
2052
2029
  </button>
2053
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-flex}.icon-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:0;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;opacity:.6;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out,border-color .15s ease-out;line-height:0;flex-shrink:0;position:relative}.icon-button--sm{width:22px;height:22px}.icon-button--sm ::ng-deep svg{width:12px;height:12px;display:block}.icon-button--md{width:28px;height:28px}.icon-button--md ::ng-deep svg{width:16px;height:16px;display:block}.icon-button--outlined{border:1px solid var(--ndt-border-primary)}.icon-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}.tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:3px 8px;border-radius:var(--ndt-border-radius-small);font-size:10px;font-weight:500;line-height:normal;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease-out;z-index:9999;box-shadow:var(--ndt-shadow-tooltip)}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--ndt-tooltip-bg)}\n"], dependencies: [{ kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2030
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-flex}.icon-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:0;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;opacity:.6;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out,border-color .15s ease-out;line-height:0;flex-shrink:0;position:relative}.icon-button--sm{width:22px;height:22px}.icon-button--sm ::ng-deep svg{width:12px;height:12px;display:block}.icon-button--md{width:28px;height:28px}.icon-button--md ::ng-deep svg{width:16px;height:16px;display:block}.icon-button--outlined{border:1px solid var(--ndt-border-primary)}.icon-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}.tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:3px 8px;border-radius:var(--ndt-border-radius-small);font-size:10px;font-weight:500;line-height:normal;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease-out;z-index:9999;box-shadow:var(--ndt-shadow-tooltip)}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--ndt-tooltip-bg)}\n"], dependencies: [{ kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2054
2031
  }
2055
2032
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarIconButtonComponent, decorators: [{
2056
2033
  type: Component,
@@ -2074,7 +2051,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2074
2051
  }
2075
2052
  <ng-content />
2076
2053
  </button>
2077
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-flex}.icon-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:0;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;opacity:.6;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out,border-color .15s ease-out;line-height:0;flex-shrink:0;position:relative}.icon-button--sm{width:22px;height:22px}.icon-button--sm ::ng-deep svg{width:12px;height:12px;display:block}.icon-button--md{width:28px;height:28px}.icon-button--md ::ng-deep svg{width:16px;height:16px;display:block}.icon-button--outlined{border:1px solid var(--ndt-border-primary)}.icon-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}.tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:3px 8px;border-radius:var(--ndt-border-radius-small);font-size:10px;font-weight:500;line-height:normal;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease-out;z-index:9999;box-shadow:var(--ndt-shadow-tooltip)}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--ndt-tooltip-bg)}\n"] }]
2054
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-flex}.icon-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:0;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;opacity:.6;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out,border-color .15s ease-out;line-height:0;flex-shrink:0;position:relative}.icon-button--sm{width:22px;height:22px}.icon-button--sm ::ng-deep svg{width:12px;height:12px;display:block}.icon-button--md{width:28px;height:28px}.icon-button--md ::ng-deep svg{width:16px;height:16px;display:block}.icon-button--outlined{border:1px solid var(--ndt-border-primary)}.icon-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}.tooltip{position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:3px 8px;border-radius:var(--ndt-border-radius-small);font-size:10px;font-weight:500;line-height:normal;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease-out;z-index:9999;box-shadow:var(--ndt-shadow-tooltip)}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--ndt-tooltip-bg)}\n"] }]
2078
2055
  }] });
2079
2056
 
2080
2057
  /**
@@ -2130,6 +2107,11 @@ class ToolbarListItemComponent {
2130
2107
  * Whether this item is pinned to the top of the list
2131
2108
  */
2132
2109
  this.isPinned = input(false);
2110
+ /**
2111
+ * Optional identifier that can be copied to clipboard (e.g., flag ID).
2112
+ * When provided, renders a copy button in the action row.
2113
+ */
2114
+ this.copyableId = input(undefined);
2133
2115
  /**
2134
2116
  * Emits when the user clicks the pin/unpin button
2135
2117
  */
@@ -2141,54 +2123,75 @@ class ToolbarListItemComponent {
2141
2123
  this.pinIcon = computed(() => 'pin');
2142
2124
  this.pinAriaLabel = computed(() => this.isPinned() ? 'Unpin item' : 'Pin item');
2143
2125
  /**
2144
- * Value to display in the dot indicator.
2145
- * For forced items: shows originalValue
2146
- * For non-forced items: shows currentValue
2147
- */
2148
- this.displayValue = computed(() => {
2149
- const originalValue = this.originalValue();
2150
- return this.isForced() && originalValue !== undefined
2151
- ? originalValue
2152
- : this.currentValue();
2153
- });
2154
- /**
2155
- * Tooltip text explaining the indicator state
2126
+ * Tooltip text explaining the current state, with override context when forced
2156
2127
  */
2157
2128
  this.tooltipText = computed(() => {
2158
- const value = this.displayValue();
2159
- const state = value ? 'enabled' : 'disabled';
2129
+ const current = this.currentValue() ? 'enabled' : 'disabled';
2160
2130
  if (this.isForced() && this.originalValue() !== undefined) {
2161
- return `Originally: ${state}`;
2131
+ const original = this.originalValue() ? 'enabled' : 'disabled';
2132
+ return `Currently ${current} (originally ${original})`;
2162
2133
  }
2163
- return `Current state: ${state}`;
2134
+ return `Currently ${current}`;
2164
2135
  });
2136
+ this.statusAriaLabel = computed(() => {
2137
+ const current = this.currentValue() ? 'enabled' : 'disabled';
2138
+ return this.isForced() ? `${current}, forced` : current;
2139
+ });
2140
+ this.copyState = signal('idle');
2141
+ this.copyAriaLabel = computed(() => {
2142
+ const id = this.copyableId();
2143
+ return id ? `Copy ID "${id}" to clipboard` : 'Copy ID';
2144
+ });
2145
+ }
2146
+ async copyId(event) {
2147
+ event.stopPropagation();
2148
+ const id = this.copyableId();
2149
+ if (!id)
2150
+ return;
2151
+ try {
2152
+ await navigator.clipboard.writeText(id);
2153
+ this.copyState.set('copied');
2154
+ setTimeout(() => this.copyState.set('idle'), 1500);
2155
+ }
2156
+ catch {
2157
+ this.copyState.set('idle');
2158
+ }
2165
2159
  }
2166
2160
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2167
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarListItemComponent, isStandalone: true, selector: "ndt-list-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, isForced: { classPropertyName: "isForced", publicName: "isForced", isSignal: true, isRequired: false, transformFunction: null }, currentValue: { classPropertyName: "currentValue", publicName: "currentValue", isSignal: true, isRequired: true, transformFunction: null }, originalValue: { classPropertyName: "originalValue", publicName: "originalValue", isSignal: true, isRequired: false, transformFunction: null }, showApply: { classPropertyName: "showApply", publicName: "showApply", isSignal: true, isRequired: false, transformFunction: null }, applyState: { classPropertyName: "applyState", publicName: "applyState", isSignal: true, isRequired: false, transformFunction: null }, isPinned: { classPropertyName: "isPinned", publicName: "isPinned", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pinToggle: "pinToggle", applyToSource: "applyToSource" }, ngImport: i0, template: `
2161
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarListItemComponent, isStandalone: true, selector: "ndt-list-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, isForced: { classPropertyName: "isForced", publicName: "isForced", isSignal: true, isRequired: false, transformFunction: null }, currentValue: { classPropertyName: "currentValue", publicName: "currentValue", isSignal: true, isRequired: true, transformFunction: null }, originalValue: { classPropertyName: "originalValue", publicName: "originalValue", isSignal: true, isRequired: false, transformFunction: null }, showApply: { classPropertyName: "showApply", publicName: "showApply", isSignal: true, isRequired: false, transformFunction: null }, applyState: { classPropertyName: "applyState", publicName: "applyState", isSignal: true, isRequired: false, transformFunction: null }, isPinned: { classPropertyName: "isPinned", publicName: "isPinned", isSignal: true, isRequired: false, transformFunction: null }, copyableId: { classPropertyName: "copyableId", publicName: "copyableId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pinToggle: "pinToggle", applyToSource: "applyToSource" }, ngImport: i0, template: `
2168
2162
  <div class="list-item" [class.list-item--forced]="isForced()">
2169
- <ndt-icon-button
2170
- [icon]="pinIcon()"
2171
- [ariaLabel]="pinAriaLabel()"
2172
- variant="ghost"
2173
- class="pin-button"
2174
- [class.pin-button--pinned]="isPinned()"
2175
- (click)="pinToggle.emit(); $event.stopPropagation()"
2176
- />
2163
+ <span
2164
+ class="dot-indicator"
2165
+ [class.dot-indicator--on]="currentValue()"
2166
+ [class.dot-indicator--off]="!currentValue()"
2167
+ [class.dot-indicator--forced]="isForced()"
2168
+ [title]="tooltipText()"
2169
+ [attr.aria-label]="statusAriaLabel()"
2170
+ role="img"
2171
+ ></span>
2177
2172
  <div class="info">
2178
2173
  <h3>{{ title() }}</h3>
2179
2174
  @if (description()) {
2180
- <div class="description-wrapper">
2181
- <span
2182
- class="dot-indicator"
2183
- [class.dot-indicator--on]="displayValue()"
2184
- [class.dot-indicator--off]="!displayValue()"
2185
- [title]="tooltipText()"
2186
- ></span>
2187
- <p>{{ description() }}</p>
2188
- </div>
2175
+ <p>{{ description() }}</p>
2189
2176
  }
2190
2177
  </div>
2191
2178
  <div class="actions">
2179
+ @if (copyableId()) {
2180
+ <button
2181
+ type="button"
2182
+ class="copy-button"
2183
+ [class.copy-button--copied]="copyState() === 'copied'"
2184
+ [attr.aria-label]="copyAriaLabel()"
2185
+ [title]="copyState() === 'copied' ? 'Copied!' : 'Copy ID'"
2186
+ (click)="copyId($event)"
2187
+ >
2188
+ @if (copyState() === 'copied') {
2189
+ <span aria-hidden="true">✓</span>
2190
+ } @else {
2191
+ <span aria-hidden="true" class="copy-icon">⧉</span>
2192
+ }
2193
+ </button>
2194
+ }
2192
2195
  @if (showApply() && isForced()) {
2193
2196
  <ndt-icon-button
2194
2197
  [icon]="applyState() === 'idle' ? 'export' : undefined"
@@ -2205,46 +2208,63 @@ class ToolbarListItemComponent {
2205
2208
  <span class="apply-spinner"></span>
2206
2209
  }
2207
2210
  @case ('success') {
2208
- <span class="apply-icon">✓</span>
2211
+ <span class="apply-icon" aria-hidden="true">✓</span>
2209
2212
  }
2210
2213
  @case ('error') {
2211
- <span class="apply-icon">✕</span>
2214
+ <span class="apply-icon" aria-hidden="true">✕</span>
2212
2215
  }
2213
2216
  }
2214
2217
  </ndt-icon-button>
2215
2218
  }
2216
2219
  <ng-content />
2220
+ <ndt-icon-button
2221
+ [icon]="pinIcon()"
2222
+ [ariaLabel]="pinAriaLabel()"
2223
+ variant="ghost"
2224
+ class="pin-button"
2225
+ [class.pin-button--pinned]="isPinned()"
2226
+ (click)="pinToggle.emit(); $event.stopPropagation()"
2227
+ />
2217
2228
  </div>
2218
2229
  </div>
2219
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.list-item{display:flex;flex-direction:row;gap:var(--ndt-spacing-sm);background:var(--ndt-background-secondary);padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);transition:background-color .2s ease;position:relative;z-index:1;flex-shrink:0;overflow:visible}.list-item.list-item--forced{background:#3b82f60d}.list-item .info{flex:1 1 auto;min-width:0}.list-item .info h3{margin:0;font-size:var(--ndt-font-size-xs);font-weight:500;color:var(--ndt-text-primary)}.list-item .info .description-wrapper{display:flex;align-items:flex-start;gap:4px;margin-top:1px}.list-item .info .dot-indicator{display:inline-block;width:6px;height:6px;border-radius:50%;flex-shrink:0;cursor:help;transition:all .2s ease;margin-top:5px}.list-item .info .dot-indicator.dot-indicator--on{background:#22c55e;box-shadow:0 0 0 2px #22c55e33}.list-item .info .dot-indicator.dot-indicator--off{background:#ef4444;box-shadow:0 0 0 2px #ef444433}.list-item .info p{margin:0;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);flex:1;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.list-item .actions{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;overflow:visible}.pin-button{flex-shrink:0;align-self:flex-start;opacity:0;transition:opacity .2s ease}.list-item:hover .pin-button{opacity:.4}.list-item:hover .pin-button:hover{opacity:.7}.pin-button--pinned{opacity:1}.pin-button--pinned ::ng-deep .icon-button{opacity:1;color:var(--ndt-text-primary)}.apply-button--loading ::ng-deep .icon-button{opacity:1;animation:apply-pulse 1s ease-in-out infinite}.apply-button--success ::ng-deep .icon-button{opacity:1;color:#22c55e;border-color:#22c55e4d;background:#22c55e0d}.apply-button--error ::ng-deep .icon-button{opacity:1;color:#ef4444;border-color:#ef44444d;background:#ef44440d}.apply-icon{font-size:10px;line-height:1}.apply-spinner{display:block;width:10px;height:10px;border:1.5px solid var(--ndt-border-primary);border-top-color:var(--ndt-text-primary);border-radius:50%;animation:apply-spin .6s linear infinite}@keyframes apply-pulse{0%,to{opacity:.5}50%{opacity:1}}@keyframes apply-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ToolbarIconButtonComponent, selector: "ndt-icon-button", inputs: ["icon", "tooltip", "ariaLabel", "size", "variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2230
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.list-item{display:flex;flex-direction:row;align-items:flex-start;gap:var(--ndt-spacing-sm);background:var(--ndt-background-secondary);padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);transition:background-color .28s cubic-bezier(.22,1,.36,1);position:relative;z-index:1;flex-shrink:0;overflow:visible}.list-item.list-item--forced{background:rgba(var(--ndt-forced-rgb),.1);box-shadow:inset 0 0 0 1px rgba(var(--ndt-forced-rgb),.25)}.list-item>.dot-indicator{flex:0 0 auto;display:inline-block;width:8px;height:8px;border-radius:50%;cursor:help;transition:background-color .26s cubic-bezier(.22,1,.36,1),border-color .26s cubic-bezier(.22,1,.36,1),box-shadow .26s cubic-bezier(.22,1,.36,1);margin-top:7px;box-sizing:border-box}@media (prefers-reduced-motion: reduce){.list-item,.list-item>.dot-indicator{transition:none}}.list-item>.dot-indicator.dot-indicator--on{background:var(--ndt-success);box-shadow:0 0 0 2px rgba(var(--ndt-success-rgb),.2)}.list-item>.dot-indicator.dot-indicator--off{background:transparent;border:1.5px solid var(--ndt-danger);box-shadow:0 0 0 2px rgba(var(--ndt-danger-rgb),.12)}.list-item .info{flex:1 1 auto;min-width:0}.list-item .info h3{margin:0;font-size:var(--ndt-font-size-sm);font-weight:500;color:var(--ndt-text-primary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-item .info p{margin:1px 0 0;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.list-item .actions{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;overflow:visible}.pin-button{flex:0 0 auto;opacity:0;transition:opacity .2s ease}.pin-button ::ng-deep .icon-button{width:14px;height:14px;padding:0;box-sizing:border-box;background:transparent}.pin-button ::ng-deep .icon-button ::ng-deep svg{width:12px;height:12px}.pin-button ::ng-deep .icon-button:hover{background:transparent;color:var(--ndt-text-primary);opacity:1}.list-item:hover .pin-button,.list-item:focus-within .pin-button{opacity:.5}.list-item:hover .pin-button:hover,.list-item:focus-within .pin-button:focus-visible{opacity:1}.pin-button--pinned{opacity:1}.pin-button--pinned ::ng-deep .icon-button{opacity:1;color:var(--ndt-primary);background:transparent}.copy-button{appearance:none;border:0;background:transparent;color:var(--ndt-text-muted);width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;border-radius:var(--ndt-border-radius-small);cursor:pointer;font-size:12px;line-height:1;opacity:0;transition:opacity .2s ease,color .15s ease,background-color .15s ease}.copy-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.copy-button:focus-visible{opacity:1;outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.copy-button .copy-icon{font-family:ui-monospace,monospace}.list-item:hover .copy-button,.list-item:focus-within .copy-button{opacity:.6}.list-item:hover .copy-button:hover{opacity:1}.copy-button--copied{opacity:1!important;color:var(--ndt-success)}.apply-button--loading ::ng-deep .icon-button{opacity:1;animation:apply-pulse 1s ease-in-out infinite}.apply-button--success ::ng-deep .icon-button{opacity:1;color:var(--ndt-success);border-color:rgba(var(--ndt-success-rgb),.3);background:rgba(var(--ndt-success-rgb),.05)}.apply-button--error ::ng-deep .icon-button{opacity:1;color:var(--ndt-danger);border-color:rgba(var(--ndt-danger-rgb),.3);background:rgba(var(--ndt-danger-rgb),.05)}.apply-icon{font-size:10px;line-height:1}.apply-spinner{display:block;width:10px;height:10px;border:1.5px solid var(--ndt-border-primary);border-top-color:var(--ndt-text-primary);border-radius:50%;animation:apply-spin .6s linear infinite}@keyframes apply-pulse{0%,to{opacity:.5}50%{opacity:1}}@keyframes apply-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ToolbarIconButtonComponent, selector: "ndt-icon-button", inputs: ["icon", "tooltip", "ariaLabel", "size", "variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2220
2231
  }
2221
2232
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListItemComponent, decorators: [{
2222
2233
  type: Component,
2223
- args: [{ selector: 'ndt-list-item', standalone: true, imports: [CommonModule, ToolbarIconComponent, ToolbarIconButtonComponent], template: `
2234
+ args: [{ selector: 'ndt-list-item', standalone: true, imports: [CommonModule, ToolbarIconButtonComponent], template: `
2224
2235
  <div class="list-item" [class.list-item--forced]="isForced()">
2225
- <ndt-icon-button
2226
- [icon]="pinIcon()"
2227
- [ariaLabel]="pinAriaLabel()"
2228
- variant="ghost"
2229
- class="pin-button"
2230
- [class.pin-button--pinned]="isPinned()"
2231
- (click)="pinToggle.emit(); $event.stopPropagation()"
2232
- />
2236
+ <span
2237
+ class="dot-indicator"
2238
+ [class.dot-indicator--on]="currentValue()"
2239
+ [class.dot-indicator--off]="!currentValue()"
2240
+ [class.dot-indicator--forced]="isForced()"
2241
+ [title]="tooltipText()"
2242
+ [attr.aria-label]="statusAriaLabel()"
2243
+ role="img"
2244
+ ></span>
2233
2245
  <div class="info">
2234
2246
  <h3>{{ title() }}</h3>
2235
2247
  @if (description()) {
2236
- <div class="description-wrapper">
2237
- <span
2238
- class="dot-indicator"
2239
- [class.dot-indicator--on]="displayValue()"
2240
- [class.dot-indicator--off]="!displayValue()"
2241
- [title]="tooltipText()"
2242
- ></span>
2243
- <p>{{ description() }}</p>
2244
- </div>
2248
+ <p>{{ description() }}</p>
2245
2249
  }
2246
2250
  </div>
2247
2251
  <div class="actions">
2252
+ @if (copyableId()) {
2253
+ <button
2254
+ type="button"
2255
+ class="copy-button"
2256
+ [class.copy-button--copied]="copyState() === 'copied'"
2257
+ [attr.aria-label]="copyAriaLabel()"
2258
+ [title]="copyState() === 'copied' ? 'Copied!' : 'Copy ID'"
2259
+ (click)="copyId($event)"
2260
+ >
2261
+ @if (copyState() === 'copied') {
2262
+ <span aria-hidden="true">✓</span>
2263
+ } @else {
2264
+ <span aria-hidden="true" class="copy-icon">⧉</span>
2265
+ }
2266
+ </button>
2267
+ }
2248
2268
  @if (showApply() && isForced()) {
2249
2269
  <ndt-icon-button
2250
2270
  [icon]="applyState() === 'idle' ? 'export' : undefined"
@@ -2261,22 +2281,119 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2261
2281
  <span class="apply-spinner"></span>
2262
2282
  }
2263
2283
  @case ('success') {
2264
- <span class="apply-icon">✓</span>
2284
+ <span class="apply-icon" aria-hidden="true">✓</span>
2265
2285
  }
2266
2286
  @case ('error') {
2267
- <span class="apply-icon">✕</span>
2287
+ <span class="apply-icon" aria-hidden="true">✕</span>
2268
2288
  }
2269
2289
  }
2270
2290
  </ndt-icon-button>
2271
2291
  }
2272
2292
  <ng-content />
2293
+ <ndt-icon-button
2294
+ [icon]="pinIcon()"
2295
+ [ariaLabel]="pinAriaLabel()"
2296
+ variant="ghost"
2297
+ class="pin-button"
2298
+ [class.pin-button--pinned]="isPinned()"
2299
+ (click)="pinToggle.emit(); $event.stopPropagation()"
2300
+ />
2273
2301
  </div>
2274
2302
  </div>
2275
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.list-item{display:flex;flex-direction:row;gap:var(--ndt-spacing-sm);background:var(--ndt-background-secondary);padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);transition:background-color .2s ease;position:relative;z-index:1;flex-shrink:0;overflow:visible}.list-item.list-item--forced{background:#3b82f60d}.list-item .info{flex:1 1 auto;min-width:0}.list-item .info h3{margin:0;font-size:var(--ndt-font-size-xs);font-weight:500;color:var(--ndt-text-primary)}.list-item .info .description-wrapper{display:flex;align-items:flex-start;gap:4px;margin-top:1px}.list-item .info .dot-indicator{display:inline-block;width:6px;height:6px;border-radius:50%;flex-shrink:0;cursor:help;transition:all .2s ease;margin-top:5px}.list-item .info .dot-indicator.dot-indicator--on{background:#22c55e;box-shadow:0 0 0 2px #22c55e33}.list-item .info .dot-indicator.dot-indicator--off{background:#ef4444;box-shadow:0 0 0 2px #ef444433}.list-item .info p{margin:0;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);flex:1;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.list-item .actions{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;overflow:visible}.pin-button{flex-shrink:0;align-self:flex-start;opacity:0;transition:opacity .2s ease}.list-item:hover .pin-button{opacity:.4}.list-item:hover .pin-button:hover{opacity:.7}.pin-button--pinned{opacity:1}.pin-button--pinned ::ng-deep .icon-button{opacity:1;color:var(--ndt-text-primary)}.apply-button--loading ::ng-deep .icon-button{opacity:1;animation:apply-pulse 1s ease-in-out infinite}.apply-button--success ::ng-deep .icon-button{opacity:1;color:#22c55e;border-color:#22c55e4d;background:#22c55e0d}.apply-button--error ::ng-deep .icon-button{opacity:1;color:#ef4444;border-color:#ef44444d;background:#ef44440d}.apply-icon{font-size:10px;line-height:1}.apply-spinner{display:block;width:10px;height:10px;border:1.5px solid var(--ndt-border-primary);border-top-color:var(--ndt-text-primary);border-radius:50%;animation:apply-spin .6s linear infinite}@keyframes apply-pulse{0%,to{opacity:.5}50%{opacity:1}}@keyframes apply-spin{to{transform:rotate(360deg)}}\n"] }]
2303
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.list-item{display:flex;flex-direction:row;align-items:flex-start;gap:var(--ndt-spacing-sm);background:var(--ndt-background-secondary);padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);transition:background-color .28s cubic-bezier(.22,1,.36,1);position:relative;z-index:1;flex-shrink:0;overflow:visible}.list-item.list-item--forced{background:rgba(var(--ndt-forced-rgb),.1);box-shadow:inset 0 0 0 1px rgba(var(--ndt-forced-rgb),.25)}.list-item>.dot-indicator{flex:0 0 auto;display:inline-block;width:8px;height:8px;border-radius:50%;cursor:help;transition:background-color .26s cubic-bezier(.22,1,.36,1),border-color .26s cubic-bezier(.22,1,.36,1),box-shadow .26s cubic-bezier(.22,1,.36,1);margin-top:7px;box-sizing:border-box}@media (prefers-reduced-motion: reduce){.list-item,.list-item>.dot-indicator{transition:none}}.list-item>.dot-indicator.dot-indicator--on{background:var(--ndt-success);box-shadow:0 0 0 2px rgba(var(--ndt-success-rgb),.2)}.list-item>.dot-indicator.dot-indicator--off{background:transparent;border:1.5px solid var(--ndt-danger);box-shadow:0 0 0 2px rgba(var(--ndt-danger-rgb),.12)}.list-item .info{flex:1 1 auto;min-width:0}.list-item .info h3{margin:0;font-size:var(--ndt-font-size-sm);font-weight:500;color:var(--ndt-text-primary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-item .info p{margin:1px 0 0;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.list-item .actions{flex:0 0 auto;display:flex;align-items:center;justify-content:flex-end;gap:4px;overflow:visible}.pin-button{flex:0 0 auto;opacity:0;transition:opacity .2s ease}.pin-button ::ng-deep .icon-button{width:14px;height:14px;padding:0;box-sizing:border-box;background:transparent}.pin-button ::ng-deep .icon-button ::ng-deep svg{width:12px;height:12px}.pin-button ::ng-deep .icon-button:hover{background:transparent;color:var(--ndt-text-primary);opacity:1}.list-item:hover .pin-button,.list-item:focus-within .pin-button{opacity:.5}.list-item:hover .pin-button:hover,.list-item:focus-within .pin-button:focus-visible{opacity:1}.pin-button--pinned{opacity:1}.pin-button--pinned ::ng-deep .icon-button{opacity:1;color:var(--ndt-primary);background:transparent}.copy-button{appearance:none;border:0;background:transparent;color:var(--ndt-text-muted);width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;border-radius:var(--ndt-border-radius-small);cursor:pointer;font-size:12px;line-height:1;opacity:0;transition:opacity .2s ease,color .15s ease,background-color .15s ease}.copy-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.copy-button:focus-visible{opacity:1;outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.copy-button .copy-icon{font-family:ui-monospace,monospace}.list-item:hover .copy-button,.list-item:focus-within .copy-button{opacity:.6}.list-item:hover .copy-button:hover{opacity:1}.copy-button--copied{opacity:1!important;color:var(--ndt-success)}.apply-button--loading ::ng-deep .icon-button{opacity:1;animation:apply-pulse 1s ease-in-out infinite}.apply-button--success ::ng-deep .icon-button{opacity:1;color:var(--ndt-success);border-color:rgba(var(--ndt-success-rgb),.3);background:rgba(var(--ndt-success-rgb),.05)}.apply-button--error ::ng-deep .icon-button{opacity:1;color:var(--ndt-danger);border-color:rgba(var(--ndt-danger-rgb),.3);background:rgba(var(--ndt-danger-rgb),.05)}.apply-icon{font-size:10px;line-height:1}.apply-spinner{display:block;width:10px;height:10px;border:1.5px solid var(--ndt-border-primary);border-top-color:var(--ndt-text-primary);border-radius:50%;animation:apply-spin .6s linear infinite}@keyframes apply-pulse{0%,to{opacity:.5}50%{opacity:1}}@keyframes apply-spin{to{transform:rotate(360deg)}}\n"] }]
2304
+ }] });
2305
+
2306
+ /**
2307
+ * Container component for displaying lists of items with consistent scrolling,
2308
+ * empty states, and layout across all tools.
2309
+ *
2310
+ * @example
2311
+ * ```html
2312
+ * <ndt-list
2313
+ * [hasItems]="items().length > 0"
2314
+ * [hasResults]="filteredItems().length > 0"
2315
+ * emptyMessage="No items found"
2316
+ * noResultsMessage="No items match your filter"
2317
+ * >
2318
+ * @for (item of filteredItems(); track item.id) {
2319
+ * <ndt-list-item ... />
2320
+ * }
2321
+ * </ndt-list>
2322
+ * ```
2323
+ */
2324
+ class ToolbarListComponent {
2325
+ constructor() {
2326
+ /**
2327
+ * Whether the list has any items at all (before filtering).
2328
+ * When false, shows the emptyMessage.
2329
+ */
2330
+ this.hasItems = input(true);
2331
+ /**
2332
+ * Whether the list has any results after filtering.
2333
+ * When false (but hasItems is true), shows the noResultsMessage.
2334
+ */
2335
+ this.hasResults = input(true);
2336
+ /**
2337
+ * Message to display when there are no items at all.
2338
+ * @example "No feature flags found"
2339
+ */
2340
+ this.emptyMessage = input('No items found');
2341
+ /**
2342
+ * Optional hint text to display below the empty message.
2343
+ * @example "Call setAvailableOptions() to configure features"
2344
+ */
2345
+ this.emptyHint = input(undefined);
2346
+ /**
2347
+ * Message to display when items exist but none match the current filter.
2348
+ * @example "No flags match your filter"
2349
+ */
2350
+ this.noResultsMessage = input('No results match your filter');
2351
+ }
2352
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2353
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarListComponent, isStandalone: true, selector: "ndt-list", inputs: { hasItems: { classPropertyName: "hasItems", publicName: "hasItems", isSignal: true, isRequired: false, transformFunction: null }, hasResults: { classPropertyName: "hasResults", publicName: "hasResults", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyHint: { classPropertyName: "emptyHint", publicName: "emptyHint", isSignal: true, isRequired: false, transformFunction: null }, noResultsMessage: { classPropertyName: "noResultsMessage", publicName: "noResultsMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2354
+ @if (!hasItems()) {
2355
+ <div class="empty-state">
2356
+ <p>{{ emptyMessage() }}</p>
2357
+ @if (emptyHint()) {
2358
+ <p class="hint">{{ emptyHint() }}</p>
2359
+ }
2360
+ </div>
2361
+ } @else if (!hasResults()) {
2362
+ <div class="empty-state">
2363
+ <p>{{ noResultsMessage() }}</p>
2364
+ </div>
2365
+ } @else {
2366
+ <div class="list-container">
2367
+ <ng-content />
2368
+ </div>
2369
+ }
2370
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:flex;flex-direction:column;flex:1;min-height:0}.empty-state{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:var(--ndt-background-secondary);color:var(--ndt-text-muted)}.empty-state p{margin:0}.empty-state .hint{font-size:var(--ndt-font-size-xs)}.list-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;max-height:100%;overflow-y:auto;overflow-x:hidden;position:relative;scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.list-container::-webkit-scrollbar{width:8px;height:8px}.list-container::-webkit-scrollbar-track{background:transparent}.list-container::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.list-container::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2371
+ }
2372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarListComponent, decorators: [{
2373
+ type: Component,
2374
+ args: [{ selector: 'ndt-list', standalone: true, imports: [CommonModule], template: `
2375
+ @if (!hasItems()) {
2376
+ <div class="empty-state">
2377
+ <p>{{ emptyMessage() }}</p>
2378
+ @if (emptyHint()) {
2379
+ <p class="hint">{{ emptyHint() }}</p>
2380
+ }
2381
+ </div>
2382
+ } @else if (!hasResults()) {
2383
+ <div class="empty-state">
2384
+ <p>{{ noResultsMessage() }}</p>
2385
+ </div>
2386
+ } @else {
2387
+ <div class="list-container">
2388
+ <ng-content />
2389
+ </div>
2390
+ }
2391
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:flex;flex-direction:column;flex:1;min-height:0}.empty-state{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:var(--ndt-background-secondary);color:var(--ndt-text-muted)}.empty-state p{margin:0}.empty-state .hint{font-size:var(--ndt-font-size-xs)}.list-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;max-height:100%;overflow-y:auto;overflow-x:hidden;position:relative;scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.list-container::-webkit-scrollbar{width:8px;height:8px}.list-container::-webkit-scrollbar-track{background:transparent}.list-container::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.list-container::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}\n"] }]
2276
2392
  }] });
2277
2393
 
2278
2394
  class ToolbarSelectComponent {
2279
2395
  constructor() {
2396
+ this.elementRef = inject(ElementRef);
2280
2397
  this.devToolbarStateService = inject(ToolbarStateService);
2281
2398
  this.value = model();
2282
2399
  this.options = input.required();
@@ -2289,6 +2406,7 @@ class ToolbarSelectComponent {
2289
2406
  .toString(36)
2290
2407
  .slice(2, 11)}`;
2291
2408
  this.isOpen = signal(false);
2409
+ this.triggerWidth = signal(0);
2292
2410
  this.isPlaceholder = computed(() => {
2293
2411
  const options = this.options();
2294
2412
  return !!options?.length && !options.some((opt) => opt.value === this.value());
@@ -2315,6 +2433,8 @@ class ToolbarSelectComponent {
2315
2433
  ];
2316
2434
  }
2317
2435
  toggle() {
2436
+ const selectEl = this.elementRef.nativeElement.querySelector('.ndt-select');
2437
+ this.triggerWidth.set(selectEl?.offsetWidth ?? 0);
2318
2438
  this.isOpen.update((v) => !v);
2319
2439
  }
2320
2440
  close() {
@@ -2352,6 +2472,7 @@ class ToolbarSelectComponent {
2352
2472
  [cdkConnectedOverlayOrigin]="trigger"
2353
2473
  [cdkConnectedOverlayOpen]="isOpen()"
2354
2474
  [cdkConnectedOverlayPositions]="positions"
2475
+ [cdkConnectedOverlayMinWidth]="triggerWidth()"
2355
2476
  [cdkConnectedOverlayPanelClass]="['ndt-overlay-panel', 'ndt-select-overlay']"
2356
2477
  (overlayOutsideClick)="close()"
2357
2478
  >
@@ -2376,7 +2497,7 @@ class ToolbarSelectComponent {
2376
2497
  }
2377
2498
  </div>
2378
2499
  </ng-template>
2379
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ndt-transition-default);outline:none;min-height:28px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ndt-select:hover{background-color:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 1px 3px #0000001a}.ndt-select:focus-visible{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.small{padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);height:22px}.ndt-select.open{border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.open .select__arrow{transform:rotate(180deg)}.ndt-select.placeholder{color:var(--ndt-text-muted)}.ndt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:4px;min-width:0;display:flex;align-items:center}.ndt-select__arrow{width:12px;height:12px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ndt-select-menu{display:inline-flex;flex-direction:column;min-width:120px;background-color:var(--ndt-bg-primary);padding:var(--ndt-spacing-xs) 0;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ndt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ndt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ndt-select-menu::-webkit-scrollbar-track{background:transparent}.ndt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.ndt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ndt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm) var(--ndt-spacing-xs) var(--ndt-spacing-md);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ndt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.3;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ndt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ndt-primary);background-color:rgba(var(--ndt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ndt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:4px;width:3px;height:calc(100% - 8px);background-color:var(--ndt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f}.select-menu-item:first-child{margin-top:0}.select-menu-item:last-child{margin-bottom:0}.select-overlay{backdrop-filter:blur(8px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: CdkMenuModule }, { kind: "directive", type: i2.CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }, { kind: "directive", type: i2.CdkMenuItem, selector: "[cdkMenuItem]", inputs: ["cdkMenuItemDisabled", "cdkMenuitemTypeaheadLabel"], outputs: ["cdkMenuItemTriggered"], exportAs: ["cdkMenuItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2500
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ndt-transition-default);outline:none;min-height:28px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ndt-select:hover{background-color:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 1px 3px #0000001a}.ndt-select:focus-visible{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.small{padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);height:22px}.ndt-select.open{border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.open .select__arrow{transform:rotate(180deg)}.ndt-select.placeholder{color:var(--ndt-text-muted)}.ndt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:4px;min-width:0;display:flex;align-items:center}.ndt-select__arrow{width:12px;height:12px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ndt-select-menu{display:inline-flex;flex-direction:column;min-width:120px;background-color:var(--ndt-bg-primary);padding:var(--ndt-spacing-xs) 0;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ndt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ndt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ndt-select-menu::-webkit-scrollbar-track{background:transparent}.ndt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.ndt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ndt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm) var(--ndt-spacing-xs) var(--ndt-spacing-md);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ndt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.3;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ndt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ndt-primary);background-color:rgba(var(--ndt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ndt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:4px;width:3px;height:calc(100% - 8px);background-color:var(--ndt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f;box-shadow:inset 0 0 0 2px rgba(var(--ndt-primary-rgb),.5)}.select-menu-item:first-child{margin-top:0}.select-menu-item:last-child{margin-bottom:0}.select-overlay{backdrop-filter:blur(8px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: CdkMenuModule }, { kind: "directive", type: i2.CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }, { kind: "directive", type: i2.CdkMenuItem, selector: "[cdkMenuItem]", inputs: ["cdkMenuItemDisabled", "cdkMenuitemTypeaheadLabel"], outputs: ["cdkMenuItemTriggered"], exportAs: ["cdkMenuItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2380
2501
  }
2381
2502
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarSelectComponent, decorators: [{
2382
2503
  type: Component,
@@ -2407,6 +2528,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2407
2528
  [cdkConnectedOverlayOrigin]="trigger"
2408
2529
  [cdkConnectedOverlayOpen]="isOpen()"
2409
2530
  [cdkConnectedOverlayPositions]="positions"
2531
+ [cdkConnectedOverlayMinWidth]="triggerWidth()"
2410
2532
  [cdkConnectedOverlayPanelClass]="['ndt-overlay-panel', 'ndt-select-overlay']"
2411
2533
  (overlayOutsideClick)="close()"
2412
2534
  >
@@ -2431,20 +2553,203 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2431
2553
  }
2432
2554
  </div>
2433
2555
  </ng-template>
2434
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ndt-transition-default);outline:none;min-height:28px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ndt-select:hover{background-color:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 1px 3px #0000001a}.ndt-select:focus-visible{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.small{padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);height:22px}.ndt-select.open{border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.open .select__arrow{transform:rotate(180deg)}.ndt-select.placeholder{color:var(--ndt-text-muted)}.ndt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:4px;min-width:0;display:flex;align-items:center}.ndt-select__arrow{width:12px;height:12px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ndt-select-menu{display:inline-flex;flex-direction:column;min-width:120px;background-color:var(--ndt-bg-primary);padding:var(--ndt-spacing-xs) 0;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ndt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ndt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ndt-select-menu::-webkit-scrollbar-track{background:transparent}.ndt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.ndt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ndt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm) var(--ndt-spacing-xs) var(--ndt-spacing-md);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ndt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.3;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ndt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ndt-primary);background-color:rgba(var(--ndt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ndt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:4px;width:3px;height:calc(100% - 8px);background-color:var(--ndt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f}.select-menu-item:first-child{margin-top:0}.select-menu-item:last-child{margin-bottom:0}.select-overlay{backdrop-filter:blur(8px)}\n"] }]
2556
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ndt-transition-default);outline:none;min-height:28px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ndt-select:hover{background-color:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 1px 3px #0000001a}.ndt-select:focus-visible{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.small{padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);height:22px}.ndt-select.open{border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2),0 1px 3px #0000001a}.ndt-select.open .select__arrow{transform:rotate(180deg)}.ndt-select.placeholder{color:var(--ndt-text-muted)}.ndt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:4px;min-width:0;display:flex;align-items:center}.ndt-select__arrow{width:12px;height:12px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ndt-select-menu{display:inline-flex;flex-direction:column;min-width:120px;background-color:var(--ndt-bg-primary);padding:var(--ndt-spacing-xs) 0;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ndt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ndt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ndt-select-menu::-webkit-scrollbar-track{background:transparent}.ndt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ndt-border-primary);border-radius:4px;border:2px solid var(--ndt-bg-primary)}.ndt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ndt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ndt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm) var(--ndt-spacing-xs) var(--ndt-spacing-md);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ndt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.3;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ndt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ndt-primary);background-color:rgba(var(--ndt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ndt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:4px;width:3px;height:calc(100% - 8px);background-color:var(--ndt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f;box-shadow:inset 0 0 0 2px rgba(var(--ndt-primary-rgb),.5)}.select-menu-item:first-child{margin-top:0}.select-menu-item:last-child{margin-bottom:0}.select-overlay{backdrop-filter:blur(8px)}\n"] }]
2435
2557
  }] });
2436
2558
 
2437
- class ToolbarToolButtonComponent {
2559
+ class ToolbarInputComponent {
2438
2560
  constructor() {
2439
- // Injects
2440
- this.state = inject(ToolbarStateService);
2441
- // Inputs
2442
- this.toolLabel = input.required();
2443
- this.toolId = input.required();
2444
- this.badge = input();
2445
- this.position = input('bottom');
2446
- // Outputs
2447
- this.open = output();
2561
+ this.value = model.required();
2562
+ this.type = input('text');
2563
+ this.placeholder = input('');
2564
+ this.ariaLabel = input('');
2565
+ this.inputClass = input('input');
2566
+ }
2567
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2568
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.7", type: ToolbarInputComponent, isStandalone: true, selector: "ndt-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, inputClass: { classPropertyName: "inputClass", publicName: "inputClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
2569
+ <input
2570
+ [attr.aria-label]="ariaLabel()"
2571
+ [type]="type()"
2572
+ [class]="inputClass()"
2573
+ [ngModel]="value()"
2574
+ [placeholder]="placeholder()"
2575
+ (ngModelChange)="value.set($event)"
2576
+ />
2577
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block}.input{width:100%;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:var(--ndt-transition-default);box-sizing:border-box;min-height:28px}.input::placeholder{color:var(--ndt-text-muted)}.input:focus-visible{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.input:disabled{background-color:var(--ndt-bg-secondary);cursor:not-allowed;color:var(--ndt-text-muted)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2578
+ }
2579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarInputComponent, decorators: [{
2580
+ type: Component,
2581
+ args: [{ selector: 'ndt-input', standalone: true, imports: [FormsModule], template: `
2582
+ <input
2583
+ [attr.aria-label]="ariaLabel()"
2584
+ [type]="type()"
2585
+ [class]="inputClass()"
2586
+ [ngModel]="value()"
2587
+ [placeholder]="placeholder()"
2588
+ (ngModelChange)="value.set($event)"
2589
+ />
2590
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block}.input{width:100%;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background-color:var(--ndt-bg-primary);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:var(--ndt-transition-default);box-sizing:border-box;min-height:28px}.input::placeholder{color:var(--ndt-text-muted)}.input:focus-visible{outline:none;border-color:var(--ndt-primary);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.input:disabled{background-color:var(--ndt-bg-secondary);cursor:not-allowed;color:var(--ndt-text-muted)}\n"] }]
2591
+ }] });
2592
+
2593
+ class ToolbarToolHeaderComponent {
2594
+ constructor() {
2595
+ this.searchQuery = model('');
2596
+ this.activeFilter = model('');
2597
+ this.searchPlaceholder = input('Search...');
2598
+ this.searchAriaLabel = input('');
2599
+ this.filterOptions = input([]);
2600
+ this.filterAriaLabel = input('Filter items');
2601
+ /**
2602
+ * Value to set when the user clicks an already-active filter chip
2603
+ * (i.e., to "clear" the filter back to a default no-chip state).
2604
+ * Defaults to 'all'.
2605
+ */
2606
+ this.defaultFilter = input('all');
2607
+ }
2608
+ clearSearch() {
2609
+ this.searchQuery.set('');
2610
+ }
2611
+ onFilterClick(value) {
2612
+ // Click an already-active chip to clear it back to the default
2613
+ // (no chip visually selected when activeFilter === defaultFilter).
2614
+ if (this.activeFilter() === value) {
2615
+ this.activeFilter.set(this.defaultFilter());
2616
+ }
2617
+ else {
2618
+ this.activeFilter.set(value);
2619
+ }
2620
+ }
2621
+ onFilterKeydown(event, value) {
2622
+ const options = this.filterOptions();
2623
+ const index = options.findIndex((o) => o.value === value);
2624
+ if (index === -1)
2625
+ return;
2626
+ let nextIndex = index;
2627
+ if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {
2628
+ nextIndex = (index + 1) % options.length;
2629
+ }
2630
+ else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
2631
+ nextIndex = (index - 1 + options.length) % options.length;
2632
+ }
2633
+ else if (event.key === 'Home') {
2634
+ nextIndex = 0;
2635
+ }
2636
+ else if (event.key === 'End') {
2637
+ nextIndex = options.length - 1;
2638
+ }
2639
+ else {
2640
+ return;
2641
+ }
2642
+ event.preventDefault();
2643
+ const next = options[nextIndex];
2644
+ this.activeFilter.set(next.value);
2645
+ const buttons = event.currentTarget.parentElement?.querySelectorAll('.filter-segment');
2646
+ buttons?.[nextIndex]?.focus();
2647
+ }
2648
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarToolHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2649
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarToolHeaderComponent, isStandalone: true, selector: "ndt-tool-header", inputs: { searchQuery: { classPropertyName: "searchQuery", publicName: "searchQuery", isSignal: true, isRequired: false, transformFunction: null }, activeFilter: { classPropertyName: "activeFilter", publicName: "activeFilter", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, searchAriaLabel: { classPropertyName: "searchAriaLabel", publicName: "searchAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, filterOptions: { classPropertyName: "filterOptions", publicName: "filterOptions", isSignal: true, isRequired: false, transformFunction: null }, filterAriaLabel: { classPropertyName: "filterAriaLabel", publicName: "filterAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, defaultFilter: { classPropertyName: "defaultFilter", publicName: "defaultFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchQuery: "searchQueryChange", activeFilter: "activeFilterChange" }, ngImport: i0, template: `
2650
+ <div class="tool-header">
2651
+ <div class="search-wrapper">
2652
+ <ndt-input
2653
+ [(value)]="searchQuery"
2654
+ [placeholder]="searchPlaceholder()"
2655
+ [ariaLabel]="searchAriaLabel() || searchPlaceholder()"
2656
+ />
2657
+ @if (searchQuery()) {
2658
+ <button
2659
+ type="button"
2660
+ class="clear-button"
2661
+ aria-label="Clear search"
2662
+ (click)="clearSearch()"
2663
+ >
2664
+ <span aria-hidden="true">&times;</span>
2665
+ </button>
2666
+ }
2667
+ </div>
2668
+
2669
+ @if (filterOptions().length > 0) {
2670
+ <div
2671
+ class="filter-group"
2672
+ role="radiogroup"
2673
+ [attr.aria-label]="filterAriaLabel()"
2674
+ >
2675
+ @for (opt of filterOptions(); track opt.value) {
2676
+ <button
2677
+ type="button"
2678
+ class="filter-segment"
2679
+ [class.filter-segment--active]="opt.value === activeFilter()"
2680
+ role="radio"
2681
+ [attr.aria-checked]="opt.value === activeFilter()"
2682
+ [attr.aria-label]="opt.ariaLabel || opt.label"
2683
+ (click)="onFilterClick(opt.value)"
2684
+ (keydown)="onFilterKeydown($event, opt.value)"
2685
+ >
2686
+ {{ opt.label }}
2687
+ </button>
2688
+ }
2689
+ </div>
2690
+ }
2691
+ </div>
2692
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block}.tool-header{display:flex;align-items:center;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);flex-shrink:0;flex-wrap:wrap}.search-wrapper{position:relative;flex:1 1 180px;min-width:0;display:flex}.search-wrapper ndt-input{flex:1;min-width:0;display:block}.clear-button{position:absolute;top:50%;right:4px;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:0;background:transparent;color:var(--ndt-text-muted);border-radius:50%;cursor:pointer;transition:background-color .15s ease,color .15s ease}.clear-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.clear-button:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.clear-button span{font-size:14px;line-height:1}.filter-group{display:inline-flex;padding:2px;background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);flex:0 0 auto}.filter-segment{appearance:none;border:0;background:transparent;color:var(--ndt-text-muted);font-family:inherit;font-size:var(--ndt-font-size-xxs);font-weight:500;padding:3px var(--ndt-spacing-sm);border-radius:calc(var(--ndt-border-radius-medium) - 2px);cursor:pointer;transition:background-color .15s ease,color .15s ease;white-space:nowrap}.filter-segment:hover:not(.filter-segment--active){color:var(--ndt-text-primary)}.filter-segment:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.filter-segment--active{background:var(--ndt-background-secondary);color:var(--ndt-text-primary);box-shadow:0 1px 2px #0000000f}\n"], dependencies: [{ kind: "component", type: ToolbarInputComponent, selector: "ndt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2693
+ }
2694
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarToolHeaderComponent, decorators: [{
2695
+ type: Component,
2696
+ args: [{ selector: 'ndt-tool-header', standalone: true, imports: [ToolbarInputComponent], template: `
2697
+ <div class="tool-header">
2698
+ <div class="search-wrapper">
2699
+ <ndt-input
2700
+ [(value)]="searchQuery"
2701
+ [placeholder]="searchPlaceholder()"
2702
+ [ariaLabel]="searchAriaLabel() || searchPlaceholder()"
2703
+ />
2704
+ @if (searchQuery()) {
2705
+ <button
2706
+ type="button"
2707
+ class="clear-button"
2708
+ aria-label="Clear search"
2709
+ (click)="clearSearch()"
2710
+ >
2711
+ <span aria-hidden="true">&times;</span>
2712
+ </button>
2713
+ }
2714
+ </div>
2715
+
2716
+ @if (filterOptions().length > 0) {
2717
+ <div
2718
+ class="filter-group"
2719
+ role="radiogroup"
2720
+ [attr.aria-label]="filterAriaLabel()"
2721
+ >
2722
+ @for (opt of filterOptions(); track opt.value) {
2723
+ <button
2724
+ type="button"
2725
+ class="filter-segment"
2726
+ [class.filter-segment--active]="opt.value === activeFilter()"
2727
+ role="radio"
2728
+ [attr.aria-checked]="opt.value === activeFilter()"
2729
+ [attr.aria-label]="opt.ariaLabel || opt.label"
2730
+ (click)="onFilterClick(opt.value)"
2731
+ (keydown)="onFilterKeydown($event, opt.value)"
2732
+ >
2733
+ {{ opt.label }}
2734
+ </button>
2735
+ }
2736
+ </div>
2737
+ }
2738
+ </div>
2739
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block}.tool-header{display:flex;align-items:center;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);flex-shrink:0;flex-wrap:wrap}.search-wrapper{position:relative;flex:1 1 180px;min-width:0;display:flex}.search-wrapper ndt-input{flex:1;min-width:0;display:block}.clear-button{position:absolute;top:50%;right:4px;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:0;background:transparent;color:var(--ndt-text-muted);border-radius:50%;cursor:pointer;transition:background-color .15s ease,color .15s ease}.clear-button:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.clear-button:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.clear-button span{font-size:14px;line-height:1}.filter-group{display:inline-flex;padding:2px;background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);flex:0 0 auto}.filter-segment{appearance:none;border:0;background:transparent;color:var(--ndt-text-muted);font-family:inherit;font-size:var(--ndt-font-size-xxs);font-weight:500;padding:3px var(--ndt-spacing-sm);border-radius:calc(var(--ndt-border-radius-medium) - 2px);cursor:pointer;transition:background-color .15s ease,color .15s ease;white-space:nowrap}.filter-segment:hover:not(.filter-segment--active){color:var(--ndt-text-primary)}.filter-segment:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.filter-segment--active{background:var(--ndt-background-secondary);color:var(--ndt-text-primary);box-shadow:0 1px 2px #0000000f}\n"] }]
2740
+ }] });
2741
+
2742
+ class ToolbarToolButtonComponent {
2743
+ constructor() {
2744
+ // Injects
2745
+ this.state = inject(ToolbarStateService);
2746
+ // Inputs
2747
+ this.toolLabel = input.required();
2748
+ this.toolId = input.required();
2749
+ this.badge = input();
2750
+ this.position = input('bottom');
2751
+ // Outputs
2752
+ this.open = output();
2448
2753
  // Signals
2449
2754
  this.isActive = computed(() => this.state.activeToolId() === this.toolId());
2450
2755
  this.isToolbarVisible = this.state.isVisible;
@@ -2452,7 +2757,7 @@ class ToolbarToolButtonComponent {
2452
2757
  this.tooltip = computed(() => this.toolLabel());
2453
2758
  this.isTooltipVisible = computed(() => this.tooltip() && !this.isActive() && this.isToolbarVisible());
2454
2759
  // Properties
2455
- this.tooltipState = false;
2760
+ this.tooltipState = signal(false);
2456
2761
  this.hideDelay = 3000;
2457
2762
  }
2458
2763
  // Public methods
@@ -2461,10 +2766,10 @@ class ToolbarToolButtonComponent {
2461
2766
  this.open.emit();
2462
2767
  }
2463
2768
  onMouseEnter() {
2464
- this.tooltipState = true;
2769
+ this.tooltipState.set(true);
2465
2770
  }
2466
2771
  onMouseLeave() {
2467
- this.tooltipState = false;
2772
+ this.tooltipState.set(false);
2468
2773
  }
2469
2774
  onEscape() {
2470
2775
  this.isFocused.set(false);
@@ -2490,7 +2795,7 @@ class ToolbarToolButtonComponent {
2490
2795
  @if (isTooltipVisible()) {
2491
2796
  <span
2492
2797
  class="tooltip"
2493
- [class.tooltip--visible]="tooltipState"
2798
+ [class.tooltip--visible]="tooltipState()"
2494
2799
  >
2495
2800
  {{ tooltip() }}
2496
2801
  </span>
@@ -2500,7 +2805,7 @@ class ToolbarToolButtonComponent {
2500
2805
  <span class="tool-button__badge">{{ badge() }}</span>
2501
2806
  }
2502
2807
  </button>
2503
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool-button{display:flex;justify-content:center;align-items:center;width:30px;height:30px;border:0;background:transparent;color:var(--ndt-text-primary);transition:var(--ndt-transition-default);cursor:pointer;opacity:.5;position:relative;border-radius:var(--ndt-border-radius-medium)}.tool-button--active,.tool-button:hover{background:var(--ndt-hover-bg);opacity:1}.tool-button ::ng-deep svg{width:16px;height:16px;display:block;margin:auto}.tool-button__badge{position:absolute;top:.1875rem;right:.125rem;background:linear-gradient(135deg,#fca5a5,#ef4444);color:#fff;border-radius:50%;width:.6875rem;height:.6875rem;font-size:.4375rem;font-weight:600;display:flex;align-items:center;justify-content:center;padding:0;box-shadow:0 1px 2px #0003;line-height:1}.tooltip{position:absolute;background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:.375rem .625rem;border-radius:var(--ndt-border-radius-medium);font-size:.75rem;font-weight:500;white-space:nowrap;pointer-events:none;z-index:1000;box-shadow:var(--ndt-shadow-tooltip);opacity:0;transition:opacity .15s ease-out}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;border:5px solid transparent}:host(.tooltip-position-bottom) .tooltip{bottom:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-bottom) .tooltip:after{top:100%;left:50%;transform:translate(-50%);border-top-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-top) .tooltip{top:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-top) .tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-bottom-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-left) .tooltip{left:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-left) .tooltip:after{right:100%;top:50%;transform:translateY(-50%);border-right-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-right) .tooltip{right:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-right) .tooltip:after{left:100%;top:50%;transform:translateY(-50%);border-left-color:var(--ndt-tooltip-bg)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2808
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool-button{display:flex;justify-content:center;align-items:center;width:30px;height:30px;border:0;background:transparent;color:var(--ndt-text-primary);transition:var(--ndt-transition-default);cursor:pointer;opacity:.5;position:relative;border-radius:var(--ndt-border-radius-medium)}.tool-button--active,.tool-button:hover{background:var(--ndt-hover-bg);opacity:1}.tool-button ::ng-deep svg{width:16px;height:16px;display:block;margin:auto}.tool-button__badge{position:absolute;top:.1875rem;right:.125rem;background:var(--ndt-danger);color:#fff;border-radius:50%;width:.6875rem;height:.6875rem;font-size:.4375rem;font-weight:600;display:flex;align-items:center;justify-content:center;padding:0;box-shadow:0 1px 2px #0003;line-height:1}.tooltip{position:absolute;background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:.375rem .625rem;border-radius:var(--ndt-border-radius-medium);font-size:.75rem;font-weight:500;white-space:nowrap;pointer-events:none;z-index:1000;box-shadow:var(--ndt-shadow-tooltip);opacity:0;transition:opacity .15s ease-out}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;border:5px solid transparent}:host(.tooltip-position-bottom) .tooltip{bottom:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-bottom) .tooltip:after{top:100%;left:50%;transform:translate(-50%);border-top-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-top) .tooltip{top:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-top) .tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-bottom-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-left) .tooltip{left:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-left) .tooltip:after{right:100%;top:50%;transform:translateY(-50%);border-right-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-right) .tooltip{right:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-right) .tooltip:after{left:100%;top:50%;transform:translateY(-50%);border-left-color:var(--ndt-tooltip-bg)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2504
2809
  }
2505
2810
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarToolButtonComponent, decorators: [{
2506
2811
  type: Component,
@@ -2520,7 +2825,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2520
2825
  @if (isTooltipVisible()) {
2521
2826
  <span
2522
2827
  class="tooltip"
2523
- [class.tooltip--visible]="tooltipState"
2828
+ [class.tooltip--visible]="tooltipState()"
2524
2829
  >
2525
2830
  {{ tooltip() }}
2526
2831
  </span>
@@ -2530,7 +2835,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2530
2835
  <span class="tool-button__badge">{{ badge() }}</span>
2531
2836
  }
2532
2837
  </button>
2533
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool-button{display:flex;justify-content:center;align-items:center;width:30px;height:30px;border:0;background:transparent;color:var(--ndt-text-primary);transition:var(--ndt-transition-default);cursor:pointer;opacity:.5;position:relative;border-radius:var(--ndt-border-radius-medium)}.tool-button--active,.tool-button:hover{background:var(--ndt-hover-bg);opacity:1}.tool-button ::ng-deep svg{width:16px;height:16px;display:block;margin:auto}.tool-button__badge{position:absolute;top:.1875rem;right:.125rem;background:linear-gradient(135deg,#fca5a5,#ef4444);color:#fff;border-radius:50%;width:.6875rem;height:.6875rem;font-size:.4375rem;font-weight:600;display:flex;align-items:center;justify-content:center;padding:0;box-shadow:0 1px 2px #0003;line-height:1}.tooltip{position:absolute;background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:.375rem .625rem;border-radius:var(--ndt-border-radius-medium);font-size:.75rem;font-weight:500;white-space:nowrap;pointer-events:none;z-index:1000;box-shadow:var(--ndt-shadow-tooltip);opacity:0;transition:opacity .15s ease-out}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;border:5px solid transparent}:host(.tooltip-position-bottom) .tooltip{bottom:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-bottom) .tooltip:after{top:100%;left:50%;transform:translate(-50%);border-top-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-top) .tooltip{top:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-top) .tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-bottom-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-left) .tooltip{left:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-left) .tooltip:after{right:100%;top:50%;transform:translateY(-50%);border-right-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-right) .tooltip{right:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-right) .tooltip:after{left:100%;top:50%;transform:translateY(-50%);border-left-color:var(--ndt-tooltip-bg)}\n"] }]
2838
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool-button{display:flex;justify-content:center;align-items:center;width:30px;height:30px;border:0;background:transparent;color:var(--ndt-text-primary);transition:var(--ndt-transition-default);cursor:pointer;opacity:.5;position:relative;border-radius:var(--ndt-border-radius-medium)}.tool-button--active,.tool-button:hover{background:var(--ndt-hover-bg);opacity:1}.tool-button ::ng-deep svg{width:16px;height:16px;display:block;margin:auto}.tool-button__badge{position:absolute;top:.1875rem;right:.125rem;background:var(--ndt-danger);color:#fff;border-radius:50%;width:.6875rem;height:.6875rem;font-size:.4375rem;font-weight:600;display:flex;align-items:center;justify-content:center;padding:0;box-shadow:0 1px 2px #0003;line-height:1}.tooltip{position:absolute;background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-text);padding:.375rem .625rem;border-radius:var(--ndt-border-radius-medium);font-size:.75rem;font-weight:500;white-space:nowrap;pointer-events:none;z-index:1000;box-shadow:var(--ndt-shadow-tooltip);opacity:0;transition:opacity .15s ease-out}.tooltip--visible{opacity:1}.tooltip:after{content:\"\";position:absolute;border:5px solid transparent}:host(.tooltip-position-bottom) .tooltip{bottom:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-bottom) .tooltip:after{top:100%;left:50%;transform:translate(-50%);border-top-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-top) .tooltip{top:calc(100% + 9px);left:50%;transform:translate(-50%)}:host(.tooltip-position-top) .tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-bottom-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-left) .tooltip{left:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-left) .tooltip:after{right:100%;top:50%;transform:translateY(-50%);border-right-color:var(--ndt-tooltip-bg)}:host(.tooltip-position-right) .tooltip{right:calc(100% + 9px);top:50%;transform:translateY(-50%)}:host(.tooltip-position-right) .tooltip:after{left:100%;top:50%;transform:translateY(-50%);border-left-color:var(--ndt-tooltip-bg)}\n"] }]
2534
2839
  }] });
2535
2840
 
2536
2841
  class ToolbarWindowComponent {
@@ -2592,7 +2897,7 @@ class ToolbarWindowComponent {
2592
2897
  <ng-content></ng-content>
2593
2898
  </div>
2594
2899
  </div>
2595
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block;width:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-window{box-sizing:border-box;display:flex;flex-direction:column;position:relative;width:100%;height:100%;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md) var(--ndt-spacing-md) var(--ndt-spacing-xs);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\";color:var(--ndt-text-secondary);z-index:999999999;box-shadow:var(--ndt-shadow-window);contain:layout style}.ndt-header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;position:relative;z-index:10;flex-shrink:0}.ndt-header h1{font-size:var(--ndt-font-size-md);line-height:1.2;margin:0;color:var(--ndt-text-primary)}.ndt-header__title{display:flex;align-items:center;gap:var(--ndt-spacing-sm);flex-wrap:wrap;margin-bottom:var(--ndt-spacing-xs)}.ndt-header__title .beta-tag{font-size:var(--ndt-font-size-xxs, .65rem);background:var(--ndt-purple, #8b5cf6);color:var(--ndt-text-on-primary);padding:2px 6px;border-radius:var(--ndt-border-radius-small);font-weight:600;text-transform:uppercase;letter-spacing:.5px;line-height:1;white-space:nowrap}.ndt-header__description{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);word-wrap:break-word;overflow-wrap:break-word;max-width:100%;line-height:1.4;margin:0}.ndt-header__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-width:0}.ndt-header__controls{display:flex;gap:var(--ndt-spacing-sm);flex-shrink:0;align-items:flex-start}.ndt-content{position:relative;flex:1;overflow:auto;min-height:0}.divider{height:1px;background-color:var(--ndt-border-primary);margin-bottom:var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-sm);flex-shrink:0;position:relative;z-index:5}.control{background:none;border:none;color:var(--ndt-text-secondary);cursor:pointer;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-md);line-height:1;transition:var(--ndt-transition-smooth)}.control:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.control--close:hover{background:var(--ndt-hover-danger)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2900
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block;width:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-window{box-sizing:border-box;display:flex;flex-direction:column;position:relative;width:100%;height:100%;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md) var(--ndt-spacing-md) var(--ndt-spacing-xs);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\";color:var(--ndt-text-secondary);z-index:999999999;box-shadow:var(--ndt-shadow-window);contain:layout style}.ndt-header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;position:relative;z-index:10;flex-shrink:0}.ndt-header h1{font-size:1.25rem;font-weight:700;line-height:1.15;letter-spacing:-.02em;margin:0;color:var(--ndt-text-primary)}.ndt-header__title{display:flex;align-items:center;gap:var(--ndt-spacing-sm);flex-wrap:wrap;margin-bottom:var(--ndt-spacing-xs)}.ndt-header__title .beta-tag{font-size:var(--ndt-font-size-xxs, .65rem);background:var(--ndt-purple, #8b5cf6);color:#fff;padding:2px 6px;border-radius:var(--ndt-border-radius-small);font-weight:600;text-transform:uppercase;letter-spacing:.5px;line-height:1;white-space:nowrap}.ndt-header__description{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);word-wrap:break-word;overflow-wrap:break-word;max-width:100%;line-height:1.4;margin:0}.ndt-header__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-width:0}.ndt-header__controls{display:flex;gap:var(--ndt-spacing-sm);flex-shrink:0;align-items:flex-start}.ndt-content{position:relative;flex:1;overflow:auto;min-height:0}.divider{height:1px;background-color:var(--ndt-border-primary);margin-bottom:var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-sm);flex-shrink:0;position:relative;z-index:5}.control{background:none;border:none;color:var(--ndt-text-secondary);cursor:pointer;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-md);line-height:1;transition:var(--ndt-transition-smooth)}.control:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.control--close:hover{background:var(--ndt-hover-danger)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2596
2901
  }
2597
2902
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarWindowComponent, decorators: [{
2598
2903
  type: Component,
@@ -2636,7 +2941,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2636
2941
  <ng-content></ng-content>
2637
2942
  </div>
2638
2943
  </div>
2639
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block;width:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-window{box-sizing:border-box;display:flex;flex-direction:column;position:relative;width:100%;height:100%;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md) var(--ndt-spacing-md) var(--ndt-spacing-xs);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\";color:var(--ndt-text-secondary);z-index:999999999;box-shadow:var(--ndt-shadow-window);contain:layout style}.ndt-header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;position:relative;z-index:10;flex-shrink:0}.ndt-header h1{font-size:var(--ndt-font-size-md);line-height:1.2;margin:0;color:var(--ndt-text-primary)}.ndt-header__title{display:flex;align-items:center;gap:var(--ndt-spacing-sm);flex-wrap:wrap;margin-bottom:var(--ndt-spacing-xs)}.ndt-header__title .beta-tag{font-size:var(--ndt-font-size-xxs, .65rem);background:var(--ndt-purple, #8b5cf6);color:var(--ndt-text-on-primary);padding:2px 6px;border-radius:var(--ndt-border-radius-small);font-weight:600;text-transform:uppercase;letter-spacing:.5px;line-height:1;white-space:nowrap}.ndt-header__description{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);word-wrap:break-word;overflow-wrap:break-word;max-width:100%;line-height:1.4;margin:0}.ndt-header__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-width:0}.ndt-header__controls{display:flex;gap:var(--ndt-spacing-sm);flex-shrink:0;align-items:flex-start}.ndt-content{position:relative;flex:1;overflow:auto;min-height:0}.divider{height:1px;background-color:var(--ndt-border-primary);margin-bottom:var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-sm);flex-shrink:0;position:relative;z-index:5}.control{background:none;border:none;color:var(--ndt-text-secondary);cursor:pointer;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-md);line-height:1;transition:var(--ndt-transition-smooth)}.control:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.control--close:hover{background:var(--ndt-hover-danger)}\n"] }]
2944
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);display:block;width:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-window{box-sizing:border-box;display:flex;flex-direction:column;position:relative;width:100%;height:100%;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md) var(--ndt-spacing-md) var(--ndt-spacing-xs);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\";color:var(--ndt-text-secondary);z-index:999999999;box-shadow:var(--ndt-shadow-window);contain:layout style}.ndt-header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;position:relative;z-index:10;flex-shrink:0}.ndt-header h1{font-size:1.25rem;font-weight:700;line-height:1.15;letter-spacing:-.02em;margin:0;color:var(--ndt-text-primary)}.ndt-header__title{display:flex;align-items:center;gap:var(--ndt-spacing-sm);flex-wrap:wrap;margin-bottom:var(--ndt-spacing-xs)}.ndt-header__title .beta-tag{font-size:var(--ndt-font-size-xxs, .65rem);background:var(--ndt-purple, #8b5cf6);color:#fff;padding:2px 6px;border-radius:var(--ndt-border-radius-small);font-weight:600;text-transform:uppercase;letter-spacing:.5px;line-height:1;white-space:nowrap}.ndt-header__description{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);word-wrap:break-word;overflow-wrap:break-word;max-width:100%;line-height:1.4;margin:0}.ndt-header__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-width:0}.ndt-header__controls{display:flex;gap:var(--ndt-spacing-sm);flex-shrink:0;align-items:flex-start}.ndt-content{position:relative;flex:1;overflow:auto;min-height:0}.divider{height:1px;background-color:var(--ndt-border-primary);margin-bottom:var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-sm);flex-shrink:0;position:relative;z-index:5}.control{background:none;border:none;color:var(--ndt-text-secondary);cursor:pointer;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-md);line-height:1;transition:var(--ndt-transition-smooth)}.control:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.control--close:hover{background:var(--ndt-hover-danger)}\n"] }]
2640
2945
  }] });
2641
2946
 
2642
2947
  class ToolbarToolComponent {
@@ -2791,7 +3096,7 @@ class ToolbarToolComponent {
2791
3096
  </ng-template>
2792
3097
  }
2793
3098
  </div>
2794
- `, isInline: true, styles: [":host{display:flex;--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool{position:relative}.trigger{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ToolbarWindowComponent, selector: "ndt-window", inputs: ["config"], outputs: ["closed", "maximize", "minimize"] }, { kind: "component", type: ToolbarToolButtonComponent, selector: "ndt-tool-button", inputs: ["toolLabel", "toolId", "badge", "position"], outputs: ["open"] }, { kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3099
+ `, isInline: true, styles: [":host{display:flex;--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool{position:relative}.trigger{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ToolbarWindowComponent, selector: "ndt-window", inputs: ["config"], outputs: ["closed", "maximize", "minimize"] }, { kind: "component", type: ToolbarToolButtonComponent, selector: "ndt-tool-button", inputs: ["toolLabel", "toolId", "badge", "position"], outputs: ["open"] }, { kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2795
3100
  }
2796
3101
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarToolComponent, decorators: [{
2797
3102
  type: Component,
@@ -2838,9 +3143,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
2838
3143
  </ng-template>
2839
3144
  }
2840
3145
  </div>
2841
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool{position:relative}.trigger{cursor:pointer}\n"] }]
3146
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.tool{position:relative}.trigger{cursor:pointer}\n"] }]
2842
3147
  }] });
2843
3148
 
3149
+ /**
3150
+ * Partitions items into pinned + named groups + ungrouped sections, applying
3151
+ * the same alphabetical-name ordering used elsewhere in the toolbar.
3152
+ *
3153
+ * Backward-compatible: if no item has a `group`, `groups` is `[]` and the
3154
+ * result is equivalent to the legacy pinned-first flat list.
3155
+ *
3156
+ * Pure function — no side effects, returns a new object.
3157
+ */
3158
+ function groupItems(items, pinnedIds) {
3159
+ const byName = (a, b) => a.name.localeCompare(b.name);
3160
+ const pinned = [];
3161
+ const grouped = new Map();
3162
+ const ungrouped = [];
3163
+ for (const item of items) {
3164
+ if (pinnedIds.has(item.id)) {
3165
+ pinned.push(item);
3166
+ continue;
3167
+ }
3168
+ if (item.group) {
3169
+ const bucket = grouped.get(item.group);
3170
+ if (bucket) {
3171
+ bucket.push(item);
3172
+ }
3173
+ else {
3174
+ grouped.set(item.group, [item]);
3175
+ }
3176
+ }
3177
+ else {
3178
+ ungrouped.push(item);
3179
+ }
3180
+ }
3181
+ pinned.sort(byName);
3182
+ ungrouped.sort(byName);
3183
+ const groups = [...grouped.entries()]
3184
+ .sort(([a], [b]) => a.localeCompare(b))
3185
+ .map(([name, list]) => ({ name, items: list.sort(byName) }));
3186
+ return { pinned, groups, ungrouped };
3187
+ }
3188
+
2844
3189
  /**
2845
3190
  * Internal service for managing app features state and forced overrides.
2846
3191
  *
@@ -3130,6 +3475,7 @@ class ToolbarAppFeaturesToolComponent {
3130
3475
  this.activeFilter = signal('all');
3131
3476
  this.searchQuery = signal('');
3132
3477
  this.pinnedIds = signal(new Set());
3478
+ this.collapsedGroups = signal(new Set());
3133
3479
  this.features = this.appFeaturesService.features;
3134
3480
  // Computed badge count for forced values
3135
3481
  this.badgeCount = computed(() => {
@@ -3142,7 +3488,7 @@ class ToolbarAppFeaturesToolComponent {
3142
3488
  });
3143
3489
  this.hasNoFeatures = computed(() => this.features().length === 0);
3144
3490
  this.filteredFeatures = computed(() => {
3145
- const filtered = this.features().filter((feature) => {
3491
+ return this.features().filter((feature) => {
3146
3492
  const searchTerm = this.searchQuery().toLowerCase();
3147
3493
  const featureName = feature.name.toLowerCase();
3148
3494
  const featureDescription = feature.description?.toLowerCase() ?? '';
@@ -3155,16 +3501,13 @@ class ToolbarAppFeaturesToolComponent {
3155
3501
  (this.activeFilter() === 'disabled' && !feature.isEnabled);
3156
3502
  return matchesSearch && matchesFilter;
3157
3503
  });
3158
- const pinned = this.pinnedIds();
3159
- // Sort pinned first, then alphabetically within each group
3160
- return filtered.sort((a, b) => {
3161
- const aPinned = pinned.has(a.id);
3162
- const bPinned = pinned.has(b.id);
3163
- if (aPinned !== bPinned)
3164
- return aPinned ? -1 : 1;
3165
- return a.name.localeCompare(b.name);
3166
- });
3167
3504
  });
3505
+ this.groupedFeatures = computed(() => groupItems(this.filteredFeatures(), this.pinnedIds()));
3506
+ this.flatFeatures = computed(() => {
3507
+ const { pinned, ungrouped } = this.groupedFeatures();
3508
+ return [...pinned, ...ungrouped];
3509
+ });
3510
+ this.hasAnyGroups = computed(() => this.groupedFeatures().groups.length > 0);
3168
3511
  this.hasNoFilteredFeatures = computed(() => this.filteredFeatures().length === 0);
3169
3512
  // Other properties
3170
3513
  this.options = {
@@ -3175,7 +3518,6 @@ class ToolbarAppFeaturesToolComponent {
3175
3518
  id: 'ndt-app-features',
3176
3519
  };
3177
3520
  this.filterOptions = [
3178
- { value: 'all', label: 'All Features' },
3179
3521
  { value: 'forced', label: 'Forced' },
3180
3522
  { value: 'enabled', label: 'Enabled' },
3181
3523
  { value: 'disabled', label: 'Disabled' },
@@ -3195,6 +3537,7 @@ class ToolbarAppFeaturesToolComponent {
3195
3537
  filter: this.activeFilter(),
3196
3538
  sortOrder: 'asc',
3197
3539
  pinnedIds: [...this.pinnedIds()],
3540
+ collapsedGroups: [...this.collapsedGroups()],
3198
3541
  };
3199
3542
  this.storageService.set(this.VIEW_STATE_KEY, state);
3200
3543
  });
@@ -3211,6 +3554,9 @@ class ToolbarAppFeaturesToolComponent {
3211
3554
  if (saved.pinnedIds?.length) {
3212
3555
  this.pinnedIds.set(new Set(saved.pinnedIds));
3213
3556
  }
3557
+ if (saved.collapsedGroups?.length) {
3558
+ this.collapsedGroups.set(new Set(saved.collapsedGroups));
3559
+ }
3214
3560
  }
3215
3561
  }
3216
3562
  catch {
@@ -3272,6 +3618,21 @@ class ToolbarAppFeaturesToolComponent {
3272
3618
  return next;
3273
3619
  });
3274
3620
  }
3621
+ isCollapsed(name) {
3622
+ return this.collapsedGroups().has(name);
3623
+ }
3624
+ setCollapsed(name, collapsed) {
3625
+ this.collapsedGroups.update((set) => {
3626
+ const next = new Set(set);
3627
+ if (collapsed) {
3628
+ next.add(name);
3629
+ }
3630
+ else {
3631
+ next.delete(name);
3632
+ }
3633
+ return next;
3634
+ });
3635
+ }
3275
3636
  // Protected methods
3276
3637
  /**
3277
3638
  * Get the dropdown value for a feature's current state.
@@ -3293,21 +3654,15 @@ class ToolbarAppFeaturesToolComponent {
3293
3654
  [badge]="badgeCount()"
3294
3655
  >
3295
3656
  <div class="container">
3296
- <div class="tool-header">
3297
- <ndt-input
3298
- [value]="searchQuery()"
3299
- (valueChange)="onSearchChange($event)"
3300
- placeholder="Search features..."
3301
- />
3302
- <div class="filter-wrapper">
3303
- <ndt-select
3304
- [value]="activeFilter()"
3305
- [options]="filterOptions"
3306
- [size]="'medium'"
3307
- (valueChange)="onFilterChange($event)"
3308
- />
3309
- </div>
3310
- </div>
3657
+ <ndt-tool-header
3658
+ [(searchQuery)]="searchQuery"
3659
+ [activeFilter]="activeFilter()"
3660
+ (activeFilterChange)="onFilterChange($event)"
3661
+ searchPlaceholder="Search features by name or description"
3662
+ searchAriaLabel="Search app features"
3663
+ filterAriaLabel="Filter app features by state"
3664
+ [filterOptions]="filterOptions"
3665
+ />
3311
3666
 
3312
3667
  <ndt-list
3313
3668
  [hasItems]="!hasNoFeatures()"
@@ -3316,41 +3671,107 @@ class ToolbarAppFeaturesToolComponent {
3316
3671
  [emptyHint]="'Call setAvailableOptions() to configure features'"
3317
3672
  noResultsMessage="No features match your filter"
3318
3673
  >
3319
- @for (feature of filteredFeatures(); track feature.id) {
3320
- <ndt-list-item
3321
- [title]="feature.name"
3322
- [description]="feature.description"
3323
- [isForced]="feature.isForced"
3324
- [currentValue]="feature.isEnabled"
3325
- [originalValue]="feature.originalValue"
3326
- [isPinned]="pinnedIds().has(feature.id)"
3327
- (pinToggle)="togglePin(feature.id)"
3328
- [showApply]="hasApplyCallback()"
3329
- [applyState]="getApplyState(feature.id)"
3330
- (applyToSource)="onApplyToSource(feature.id, feature.isEnabled)"
3331
- >
3332
- <ndt-select
3333
- [value]="getFeatureValue(feature)"
3334
- [options]="featureValueOptions"
3335
- [ariaLabel]="'Set value for ' + feature.name"
3336
- (valueChange)="onFeatureChange(feature.id, $event ?? '')"
3337
- size="small"
3674
+ @if (hasAnyGroups()) {
3675
+ @if (groupedFeatures().pinned.length) {
3676
+ <ndt-list-group
3677
+ name="Pinned"
3678
+ [count]="groupedFeatures().pinned.length"
3679
+ [collapsed]="isCollapsed('Pinned')"
3680
+ (collapsedChange)="setCollapsed('Pinned', $event)"
3681
+ >
3682
+ @for (feature of groupedFeatures().pinned; track feature.id) {
3683
+ <ng-container
3684
+ *ngTemplateOutlet="
3685
+ featureItem;
3686
+ context: { $implicit: feature }
3687
+ "
3688
+ />
3689
+ }
3690
+ </ndt-list-group>
3691
+ }
3692
+ @for (group of groupedFeatures().groups; track group.name) {
3693
+ <ndt-list-group
3694
+ [name]="group.name"
3695
+ [count]="group.items.length"
3696
+ [collapsed]="isCollapsed(group.name)"
3697
+ (collapsedChange)="setCollapsed(group.name, $event)"
3698
+ >
3699
+ @for (feature of group.items; track feature.id) {
3700
+ <ng-container
3701
+ *ngTemplateOutlet="
3702
+ featureItem;
3703
+ context: { $implicit: feature }
3704
+ "
3705
+ />
3706
+ }
3707
+ </ndt-list-group>
3708
+ }
3709
+ @if (groupedFeatures().ungrouped.length) {
3710
+ <ndt-list-group
3711
+ name="Other"
3712
+ [count]="groupedFeatures().ungrouped.length"
3713
+ [collapsed]="isCollapsed('Other')"
3714
+ (collapsedChange)="setCollapsed('Other', $event)"
3715
+ >
3716
+ @for (feature of groupedFeatures().ungrouped; track feature.id) {
3717
+ <ng-container
3718
+ *ngTemplateOutlet="
3719
+ featureItem;
3720
+ context: { $implicit: feature }
3721
+ "
3722
+ />
3723
+ }
3724
+ </ndt-list-group>
3725
+ }
3726
+ } @else {
3727
+ @for (feature of flatFeatures(); track feature.id) {
3728
+ <ng-container
3729
+ *ngTemplateOutlet="
3730
+ featureItem;
3731
+ context: { $implicit: feature }
3732
+ "
3338
3733
  />
3339
- </ndt-list-item>
3734
+ }
3340
3735
  }
3341
3736
  </ndt-list>
3737
+
3738
+ <ng-template #featureItem let-feature>
3739
+ <ndt-list-item
3740
+ [title]="feature.name"
3741
+ [description]="feature.description"
3742
+ [isForced]="feature.isForced"
3743
+ [currentValue]="feature.isEnabled"
3744
+ [originalValue]="feature.originalValue"
3745
+ [isPinned]="pinnedIds().has(feature.id)"
3746
+ [copyableId]="feature.id"
3747
+ (pinToggle)="togglePin(feature.id)"
3748
+ [showApply]="hasApplyCallback()"
3749
+ [applyState]="getApplyState(feature.id)"
3750
+ (applyToSource)="onApplyToSource(feature.id, feature.isEnabled)"
3751
+ >
3752
+ <ndt-select
3753
+ [value]="getFeatureValue(feature)"
3754
+ [options]="featureValueOptions"
3755
+ [ariaLabel]="'Set value for ' + feature.name"
3756
+ (valueChange)="onFeatureChange(feature.id, $event ?? '')"
3757
+ size="small"
3758
+ />
3759
+ </ndt-list-item>
3760
+ </ng-template>
3342
3761
  </div>
3343
3762
  </ndt-toolbar-tool>
3344
- `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);ndt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;border-left:1px solid var(--ndt-border-primary);padding-left:var(--ndt-spacing-sm);ndt-select{flex:0 0 auto;min-width:140px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ndt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarListComponent, selector: "ndt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ndt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue", "showApply", "applyState", "isPinned"], outputs: ["pinToggle", "applyToSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3763
+ `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarToolHeaderComponent, selector: "ndt-tool-header", inputs: ["searchQuery", "activeFilter", "searchPlaceholder", "searchAriaLabel", "filterOptions", "filterAriaLabel", "defaultFilter"], outputs: ["searchQueryChange", "activeFilterChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarListComponent, selector: "ndt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListGroupComponent, selector: "ndt-list-group", inputs: ["name", "count", "collapsed"], outputs: ["collapsedChange"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ndt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue", "showApply", "applyState", "isPinned", "copyableId"], outputs: ["pinToggle", "applyToSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3345
3764
  }
3346
3765
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarAppFeaturesToolComponent, decorators: [{
3347
3766
  type: Component,
3348
3767
  args: [{ selector: 'ndt-app-features-tool', standalone: true, imports: [
3768
+ NgTemplateOutlet,
3349
3769
  FormsModule,
3350
3770
  ToolbarToolComponent,
3351
- ToolbarInputComponent,
3771
+ ToolbarToolHeaderComponent,
3352
3772
  ToolbarSelectComponent,
3353
3773
  ToolbarListComponent,
3774
+ ToolbarListGroupComponent,
3354
3775
  ToolbarListItemComponent,
3355
3776
  ], template: `
3356
3777
  <ndt-toolbar-tool
@@ -3360,21 +3781,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3360
3781
  [badge]="badgeCount()"
3361
3782
  >
3362
3783
  <div class="container">
3363
- <div class="tool-header">
3364
- <ndt-input
3365
- [value]="searchQuery()"
3366
- (valueChange)="onSearchChange($event)"
3367
- placeholder="Search features..."
3368
- />
3369
- <div class="filter-wrapper">
3370
- <ndt-select
3371
- [value]="activeFilter()"
3372
- [options]="filterOptions"
3373
- [size]="'medium'"
3374
- (valueChange)="onFilterChange($event)"
3375
- />
3376
- </div>
3377
- </div>
3784
+ <ndt-tool-header
3785
+ [(searchQuery)]="searchQuery"
3786
+ [activeFilter]="activeFilter()"
3787
+ (activeFilterChange)="onFilterChange($event)"
3788
+ searchPlaceholder="Search features by name or description"
3789
+ searchAriaLabel="Search app features"
3790
+ filterAriaLabel="Filter app features by state"
3791
+ [filterOptions]="filterOptions"
3792
+ />
3378
3793
 
3379
3794
  <ndt-list
3380
3795
  [hasItems]="!hasNoFeatures()"
@@ -3383,32 +3798,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3383
3798
  [emptyHint]="'Call setAvailableOptions() to configure features'"
3384
3799
  noResultsMessage="No features match your filter"
3385
3800
  >
3386
- @for (feature of filteredFeatures(); track feature.id) {
3387
- <ndt-list-item
3388
- [title]="feature.name"
3389
- [description]="feature.description"
3390
- [isForced]="feature.isForced"
3391
- [currentValue]="feature.isEnabled"
3392
- [originalValue]="feature.originalValue"
3393
- [isPinned]="pinnedIds().has(feature.id)"
3394
- (pinToggle)="togglePin(feature.id)"
3395
- [showApply]="hasApplyCallback()"
3396
- [applyState]="getApplyState(feature.id)"
3397
- (applyToSource)="onApplyToSource(feature.id, feature.isEnabled)"
3398
- >
3399
- <ndt-select
3400
- [value]="getFeatureValue(feature)"
3401
- [options]="featureValueOptions"
3402
- [ariaLabel]="'Set value for ' + feature.name"
3403
- (valueChange)="onFeatureChange(feature.id, $event ?? '')"
3404
- size="small"
3801
+ @if (hasAnyGroups()) {
3802
+ @if (groupedFeatures().pinned.length) {
3803
+ <ndt-list-group
3804
+ name="Pinned"
3805
+ [count]="groupedFeatures().pinned.length"
3806
+ [collapsed]="isCollapsed('Pinned')"
3807
+ (collapsedChange)="setCollapsed('Pinned', $event)"
3808
+ >
3809
+ @for (feature of groupedFeatures().pinned; track feature.id) {
3810
+ <ng-container
3811
+ *ngTemplateOutlet="
3812
+ featureItem;
3813
+ context: { $implicit: feature }
3814
+ "
3815
+ />
3816
+ }
3817
+ </ndt-list-group>
3818
+ }
3819
+ @for (group of groupedFeatures().groups; track group.name) {
3820
+ <ndt-list-group
3821
+ [name]="group.name"
3822
+ [count]="group.items.length"
3823
+ [collapsed]="isCollapsed(group.name)"
3824
+ (collapsedChange)="setCollapsed(group.name, $event)"
3825
+ >
3826
+ @for (feature of group.items; track feature.id) {
3827
+ <ng-container
3828
+ *ngTemplateOutlet="
3829
+ featureItem;
3830
+ context: { $implicit: feature }
3831
+ "
3832
+ />
3833
+ }
3834
+ </ndt-list-group>
3835
+ }
3836
+ @if (groupedFeatures().ungrouped.length) {
3837
+ <ndt-list-group
3838
+ name="Other"
3839
+ [count]="groupedFeatures().ungrouped.length"
3840
+ [collapsed]="isCollapsed('Other')"
3841
+ (collapsedChange)="setCollapsed('Other', $event)"
3842
+ >
3843
+ @for (feature of groupedFeatures().ungrouped; track feature.id) {
3844
+ <ng-container
3845
+ *ngTemplateOutlet="
3846
+ featureItem;
3847
+ context: { $implicit: feature }
3848
+ "
3849
+ />
3850
+ }
3851
+ </ndt-list-group>
3852
+ }
3853
+ } @else {
3854
+ @for (feature of flatFeatures(); track feature.id) {
3855
+ <ng-container
3856
+ *ngTemplateOutlet="
3857
+ featureItem;
3858
+ context: { $implicit: feature }
3859
+ "
3405
3860
  />
3406
- </ndt-list-item>
3861
+ }
3407
3862
  }
3408
3863
  </ndt-list>
3864
+
3865
+ <ng-template #featureItem let-feature>
3866
+ <ndt-list-item
3867
+ [title]="feature.name"
3868
+ [description]="feature.description"
3869
+ [isForced]="feature.isForced"
3870
+ [currentValue]="feature.isEnabled"
3871
+ [originalValue]="feature.originalValue"
3872
+ [isPinned]="pinnedIds().has(feature.id)"
3873
+ [copyableId]="feature.id"
3874
+ (pinToggle)="togglePin(feature.id)"
3875
+ [showApply]="hasApplyCallback()"
3876
+ [applyState]="getApplyState(feature.id)"
3877
+ (applyToSource)="onApplyToSource(feature.id, feature.isEnabled)"
3878
+ >
3879
+ <ndt-select
3880
+ [value]="getFeatureValue(feature)"
3881
+ [options]="featureValueOptions"
3882
+ [ariaLabel]="'Set value for ' + feature.name"
3883
+ (valueChange)="onFeatureChange(feature.id, $event ?? '')"
3884
+ size="small"
3885
+ />
3886
+ </ndt-list-item>
3887
+ </ng-template>
3409
3888
  </div>
3410
3889
  </ndt-toolbar-tool>
3411
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);ndt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;border-left:1px solid var(--ndt-border-primary);padding-left:var(--ndt-spacing-sm);ndt-select{flex:0 0 auto;min-width:140px}}}\n"] }]
3890
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}\n"] }]
3412
3891
  }], ctorParameters: () => [] });
3413
3892
 
3414
3893
  class ToolbarInternalFeatureFlagService {
@@ -3547,6 +4026,7 @@ class ToolbarFeatureFlagsToolComponent {
3547
4026
  this.activeFilter = signal('all');
3548
4027
  this.searchQuery = signal('');
3549
4028
  this.pinnedIds = signal(new Set());
4029
+ this.collapsedGroups = signal(new Set());
3550
4030
  this.flags = this.featureFlags.flags;
3551
4031
  // Computed badge count for forced values
3552
4032
  this.badgeCount = computed(() => {
@@ -3558,30 +4038,30 @@ class ToolbarFeatureFlagsToolComponent {
3558
4038
  return count.toString();
3559
4039
  });
3560
4040
  this.hasNoFlags = computed(() => this.flags().length === 0);
4041
+ // Filter step — search + filter applied to the raw flag list
3561
4042
  this.filteredFlags = computed(() => {
3562
- const filtered = this.flags().filter((flag) => {
4043
+ return this.flags().filter((flag) => {
3563
4044
  const searchTerm = this.searchQuery().toLowerCase();
3564
4045
  const flagName = flag.name.toLowerCase();
3565
4046
  const flagDescription = flag.description?.toLowerCase() ?? '';
3566
4047
  const matchesSearch = !this.searchQuery() ||
3567
- flagName.toLowerCase().includes(searchTerm.toLowerCase()) ||
3568
- flagDescription.toLowerCase().includes(searchTerm.toLowerCase());
4048
+ flagName.includes(searchTerm) ||
4049
+ flagDescription.includes(searchTerm);
3569
4050
  const matchesFilter = this.activeFilter() === 'all' ||
3570
4051
  (this.activeFilter() === 'forced' && flag.isForced) ||
3571
4052
  (this.activeFilter() === 'enabled' && flag.isEnabled) ||
3572
4053
  (this.activeFilter() === 'disabled' && !flag.isEnabled);
3573
4054
  return matchesSearch && matchesFilter;
3574
4055
  });
3575
- const pinned = this.pinnedIds();
3576
- // Sort pinned first, then alphabetically within each group
3577
- return filtered.sort((a, b) => {
3578
- const aPinned = pinned.has(a.id);
3579
- const bPinned = pinned.has(b.id);
3580
- if (aPinned !== bPinned)
3581
- return aPinned ? -1 : 1;
3582
- return a.name.localeCompare(b.name);
3583
- });
3584
4056
  });
4057
+ // Grouped view — pinned + named groups + ungrouped
4058
+ this.groupedFlags = computed(() => groupItems(this.filteredFlags(), this.pinnedIds()));
4059
+ // Backward-compat flat list (pinned-first then ungrouped) used when no item has a group
4060
+ this.flatFlags = computed(() => {
4061
+ const { pinned, ungrouped } = this.groupedFlags();
4062
+ return [...pinned, ...ungrouped];
4063
+ });
4064
+ this.hasAnyGroups = computed(() => this.groupedFlags().groups.length > 0);
3585
4065
  this.hasNoFilteredFlags = computed(() => this.filteredFlags().length === 0);
3586
4066
  // Other properties
3587
4067
  this.options = {
@@ -3592,7 +4072,6 @@ class ToolbarFeatureFlagsToolComponent {
3592
4072
  id: 'ndt-feature-flags',
3593
4073
  };
3594
4074
  this.filterOptions = [
3595
- { value: 'all', label: 'All Flags' },
3596
4075
  { value: 'forced', label: 'Forced' },
3597
4076
  { value: 'enabled', label: 'Enabled' },
3598
4077
  { value: 'disabled', label: 'Disabled' },
@@ -3612,6 +4091,7 @@ class ToolbarFeatureFlagsToolComponent {
3612
4091
  filter: this.activeFilter(),
3613
4092
  sortOrder: 'asc',
3614
4093
  pinnedIds: [...this.pinnedIds()],
4094
+ collapsedGroups: [...this.collapsedGroups()],
3615
4095
  };
3616
4096
  this.storageService.set(this.VIEW_STATE_KEY, state);
3617
4097
  });
@@ -3628,6 +4108,9 @@ class ToolbarFeatureFlagsToolComponent {
3628
4108
  if (saved.pinnedIds?.length) {
3629
4109
  this.pinnedIds.set(new Set(saved.pinnedIds));
3630
4110
  }
4111
+ if (saved.collapsedGroups?.length) {
4112
+ this.collapsedGroups.set(new Set(saved.collapsedGroups));
4113
+ }
3631
4114
  }
3632
4115
  }
3633
4116
  catch {
@@ -3675,6 +4158,21 @@ class ToolbarFeatureFlagsToolComponent {
3675
4158
  return next;
3676
4159
  });
3677
4160
  }
4161
+ isCollapsed(name) {
4162
+ return this.collapsedGroups().has(name);
4163
+ }
4164
+ setCollapsed(name, collapsed) {
4165
+ this.collapsedGroups.update((set) => {
4166
+ const next = new Set(set);
4167
+ if (collapsed) {
4168
+ next.add(name);
4169
+ }
4170
+ else {
4171
+ next.delete(name);
4172
+ }
4173
+ return next;
4174
+ });
4175
+ }
3678
4176
  // Protected methods
3679
4177
  getFlagValue(flag) {
3680
4178
  if (!flag.isForced)
@@ -3693,21 +4191,15 @@ class ToolbarFeatureFlagsToolComponent {
3693
4191
  [badge]="badgeCount()"
3694
4192
  >
3695
4193
  <div class="container">
3696
- <div class="tool-header">
3697
- <ndt-input
3698
- [value]="searchQuery()"
3699
- (valueChange)="onSearchChange($event)"
3700
- placeholder="Search..."
3701
- />
3702
- <div class="filter-wrapper">
3703
- <ndt-select
3704
- [value]="activeFilter()"
3705
- [options]="filterOptions"
3706
- [size]="'medium'"
3707
- (valueChange)="onFilterChange($event)"
3708
- />
3709
- </div>
3710
- </div>
4194
+ <ndt-tool-header
4195
+ [(searchQuery)]="searchQuery"
4196
+ [activeFilter]="activeFilter()"
4197
+ (activeFilterChange)="onFilterChange($event)"
4198
+ searchPlaceholder="Search flags by name or description"
4199
+ searchAriaLabel="Search feature flags"
4200
+ filterAriaLabel="Filter feature flags by state"
4201
+ [filterOptions]="filterOptions"
4202
+ />
3711
4203
 
3712
4204
  <ndt-list
3713
4205
  [hasItems]="!hasNoFlags()"
@@ -3715,7 +4207,59 @@ class ToolbarFeatureFlagsToolComponent {
3715
4207
  emptyMessage="No flags found"
3716
4208
  noResultsMessage="No flags found matching your filter"
3717
4209
  >
3718
- @for (flag of filteredFlags(); track flag.id) {
4210
+ @if (hasAnyGroups()) {
4211
+ @if (groupedFlags().pinned.length) {
4212
+ <ndt-list-group
4213
+ name="Pinned"
4214
+ [count]="groupedFlags().pinned.length"
4215
+ [collapsed]="isCollapsed('Pinned')"
4216
+ (collapsedChange)="setCollapsed('Pinned', $event)"
4217
+ >
4218
+ @for (flag of groupedFlags().pinned; track flag.id) {
4219
+ <ng-container
4220
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4221
+ />
4222
+ }
4223
+ </ndt-list-group>
4224
+ }
4225
+ @for (group of groupedFlags().groups; track group.name) {
4226
+ <ndt-list-group
4227
+ [name]="group.name"
4228
+ [count]="group.items.length"
4229
+ [collapsed]="isCollapsed(group.name)"
4230
+ (collapsedChange)="setCollapsed(group.name, $event)"
4231
+ >
4232
+ @for (flag of group.items; track flag.id) {
4233
+ <ng-container
4234
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4235
+ />
4236
+ }
4237
+ </ndt-list-group>
4238
+ }
4239
+ @if (groupedFlags().ungrouped.length) {
4240
+ <ndt-list-group
4241
+ name="Other"
4242
+ [count]="groupedFlags().ungrouped.length"
4243
+ [collapsed]="isCollapsed('Other')"
4244
+ (collapsedChange)="setCollapsed('Other', $event)"
4245
+ >
4246
+ @for (flag of groupedFlags().ungrouped; track flag.id) {
4247
+ <ng-container
4248
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4249
+ />
4250
+ }
4251
+ </ndt-list-group>
4252
+ }
4253
+ } @else {
4254
+ @for (flag of flatFlags(); track flag.id) {
4255
+ <ng-container
4256
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4257
+ />
4258
+ }
4259
+ }
4260
+ </ndt-list>
4261
+
4262
+ <ng-template #flagItem let-flag>
3719
4263
  <ndt-list-item
3720
4264
  [title]="flag.name"
3721
4265
  [description]="flag.description"
@@ -3723,6 +4267,7 @@ class ToolbarFeatureFlagsToolComponent {
3723
4267
  [currentValue]="flag.isEnabled"
3724
4268
  [originalValue]="flag.originalValue"
3725
4269
  [isPinned]="pinnedIds().has(flag.id)"
4270
+ [copyableId]="flag.id"
3726
4271
  (pinToggle)="togglePin(flag.id)"
3727
4272
  [showApply]="hasApplyCallback()"
3728
4273
  [applyState]="getApplyState(flag.id)"
@@ -3737,20 +4282,21 @@ class ToolbarFeatureFlagsToolComponent {
3737
4282
  size="small"
3738
4283
  />
3739
4284
  </ndt-list-item>
3740
- }
3741
- </ndt-list>
4285
+ </ng-template>
3742
4286
  </div>
3743
4287
  </ndt-toolbar-tool>
3744
- `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);ndt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;border-left:1px solid var(--ndt-border-primary);padding-left:var(--ndt-spacing-sm);ndt-select{flex:0 0 auto;min-width:140px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ndt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarListComponent, selector: "ndt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ndt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue", "showApply", "applyState", "isPinned"], outputs: ["pinToggle", "applyToSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4288
+ `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarToolHeaderComponent, selector: "ndt-tool-header", inputs: ["searchQuery", "activeFilter", "searchPlaceholder", "searchAriaLabel", "filterOptions", "filterAriaLabel", "defaultFilter"], outputs: ["searchQueryChange", "activeFilterChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarListComponent, selector: "ndt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListGroupComponent, selector: "ndt-list-group", inputs: ["name", "count", "collapsed"], outputs: ["collapsedChange"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ndt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue", "showApply", "applyState", "isPinned", "copyableId"], outputs: ["pinToggle", "applyToSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3745
4289
  }
3746
4290
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarFeatureFlagsToolComponent, decorators: [{
3747
4291
  type: Component,
3748
4292
  args: [{ selector: 'ndt-feature-flags-tool', standalone: true, imports: [
4293
+ NgTemplateOutlet,
3749
4294
  FormsModule,
3750
4295
  ToolbarToolComponent,
3751
- ToolbarInputComponent,
4296
+ ToolbarToolHeaderComponent,
3752
4297
  ToolbarSelectComponent,
3753
4298
  ToolbarListComponent,
4299
+ ToolbarListGroupComponent,
3754
4300
  ToolbarListItemComponent,
3755
4301
  ], template: `
3756
4302
  <ndt-toolbar-tool
@@ -3760,21 +4306,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3760
4306
  [badge]="badgeCount()"
3761
4307
  >
3762
4308
  <div class="container">
3763
- <div class="tool-header">
3764
- <ndt-input
3765
- [value]="searchQuery()"
3766
- (valueChange)="onSearchChange($event)"
3767
- placeholder="Search..."
3768
- />
3769
- <div class="filter-wrapper">
3770
- <ndt-select
3771
- [value]="activeFilter()"
3772
- [options]="filterOptions"
3773
- [size]="'medium'"
3774
- (valueChange)="onFilterChange($event)"
3775
- />
3776
- </div>
3777
- </div>
4309
+ <ndt-tool-header
4310
+ [(searchQuery)]="searchQuery"
4311
+ [activeFilter]="activeFilter()"
4312
+ (activeFilterChange)="onFilterChange($event)"
4313
+ searchPlaceholder="Search flags by name or description"
4314
+ searchAriaLabel="Search feature flags"
4315
+ filterAriaLabel="Filter feature flags by state"
4316
+ [filterOptions]="filterOptions"
4317
+ />
3778
4318
 
3779
4319
  <ndt-list
3780
4320
  [hasItems]="!hasNoFlags()"
@@ -3782,7 +4322,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3782
4322
  emptyMessage="No flags found"
3783
4323
  noResultsMessage="No flags found matching your filter"
3784
4324
  >
3785
- @for (flag of filteredFlags(); track flag.id) {
4325
+ @if (hasAnyGroups()) {
4326
+ @if (groupedFlags().pinned.length) {
4327
+ <ndt-list-group
4328
+ name="Pinned"
4329
+ [count]="groupedFlags().pinned.length"
4330
+ [collapsed]="isCollapsed('Pinned')"
4331
+ (collapsedChange)="setCollapsed('Pinned', $event)"
4332
+ >
4333
+ @for (flag of groupedFlags().pinned; track flag.id) {
4334
+ <ng-container
4335
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4336
+ />
4337
+ }
4338
+ </ndt-list-group>
4339
+ }
4340
+ @for (group of groupedFlags().groups; track group.name) {
4341
+ <ndt-list-group
4342
+ [name]="group.name"
4343
+ [count]="group.items.length"
4344
+ [collapsed]="isCollapsed(group.name)"
4345
+ (collapsedChange)="setCollapsed(group.name, $event)"
4346
+ >
4347
+ @for (flag of group.items; track flag.id) {
4348
+ <ng-container
4349
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4350
+ />
4351
+ }
4352
+ </ndt-list-group>
4353
+ }
4354
+ @if (groupedFlags().ungrouped.length) {
4355
+ <ndt-list-group
4356
+ name="Other"
4357
+ [count]="groupedFlags().ungrouped.length"
4358
+ [collapsed]="isCollapsed('Other')"
4359
+ (collapsedChange)="setCollapsed('Other', $event)"
4360
+ >
4361
+ @for (flag of groupedFlags().ungrouped; track flag.id) {
4362
+ <ng-container
4363
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4364
+ />
4365
+ }
4366
+ </ndt-list-group>
4367
+ }
4368
+ } @else {
4369
+ @for (flag of flatFlags(); track flag.id) {
4370
+ <ng-container
4371
+ *ngTemplateOutlet="flagItem; context: { $implicit: flag }"
4372
+ />
4373
+ }
4374
+ }
4375
+ </ndt-list>
4376
+
4377
+ <ng-template #flagItem let-flag>
3786
4378
  <ndt-list-item
3787
4379
  [title]="flag.name"
3788
4380
  [description]="flag.description"
@@ -3790,6 +4382,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3790
4382
  [currentValue]="flag.isEnabled"
3791
4383
  [originalValue]="flag.originalValue"
3792
4384
  [isPinned]="pinnedIds().has(flag.id)"
4385
+ [copyableId]="flag.id"
3793
4386
  (pinToggle)="togglePin(flag.id)"
3794
4387
  [showApply]="hasApplyCallback()"
3795
4388
  [applyState]="getApplyState(flag.id)"
@@ -3804,11 +4397,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3804
4397
  size="small"
3805
4398
  />
3806
4399
  </ndt-list-item>
3807
- }
3808
- </ndt-list>
4400
+ </ng-template>
3809
4401
  </div>
3810
4402
  </ndt-toolbar-tool>
3811
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);ndt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;border-left:1px solid var(--ndt-border-primary);padding-left:var(--ndt-spacing-sm);ndt-select{flex:0 0 auto;min-width:140px}}}\n"] }]
4403
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}\n"] }]
3812
4404
  }], ctorParameters: () => [] });
3813
4405
 
3814
4406
  class ToolbarButtonComponent {
@@ -3837,7 +4429,7 @@ class ToolbarButtonComponent {
3837
4429
  }
3838
4430
  <ng-content />
3839
4431
  </button>
3840
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.button{display:inline-flex;align-items:center;gap:var(--ndt-spacing-xs);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);min-height:36px;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);background:var(--ndt-bg-primary);color:var(--ndt-text-primary);cursor:pointer;transition:var(--ndt-transition-default);outline:none;font-family:inherit}.button:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary)}.button:focus-visible{outline:none;background:var(--ndt-hover-bg);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.button.primary{background:var(--ndt-primary);color:var(--ndt-text-on-primary);border-color:var(--ndt-primary)}.button.primary:hover{background:var(--ndt-primary);border-color:var(--ndt-primary)}.button.icon-only{padding:var(--ndt-spacing-xs);width:32px;height:32px;justify-content:center}.button.small{font-size:var(--ndt-font-size-sm)}\n"], dependencies: [{ kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4432
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.button{display:inline-flex;align-items:center;gap:var(--ndt-spacing-xs);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);min-height:36px;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);background:var(--ndt-bg-primary);color:var(--ndt-text-primary);cursor:pointer;transition:var(--ndt-transition-default);outline:none;font-family:inherit}.button:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary)}.button:focus-visible{outline:none;background:var(--ndt-hover-bg);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.button.primary{background:var(--ndt-primary);color:var(--ndt-text-on-primary);border-color:var(--ndt-primary)}.button.primary:hover{background:var(--ndt-primary);border-color:var(--ndt-primary)}.button.icon-only{padding:var(--ndt-spacing-xs);width:32px;height:32px;justify-content:center}.button.small{font-size:var(--ndt-font-size-sm)}\n"], dependencies: [{ kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3841
4433
  }
3842
4434
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarButtonComponent, decorators: [{
3843
4435
  type: Component,
@@ -3857,93 +4449,122 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3857
4449
  }
3858
4450
  <ng-content />
3859
4451
  </button>
3860
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.button{display:inline-flex;align-items:center;gap:var(--ndt-spacing-xs);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);min-height:36px;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);background:var(--ndt-bg-primary);color:var(--ndt-text-primary);cursor:pointer;transition:var(--ndt-transition-default);outline:none;font-family:inherit}.button:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary)}.button:focus-visible{outline:none;background:var(--ndt-hover-bg);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.button.primary{background:var(--ndt-primary);color:var(--ndt-text-on-primary);border-color:var(--ndt-primary)}.button.primary:hover{background:var(--ndt-primary);border-color:var(--ndt-primary)}.button.icon-only{padding:var(--ndt-spacing-xs);width:32px;height:32px;justify-content:center}.button.small{font-size:var(--ndt-font-size-sm)}\n"] }]
4452
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.button{display:inline-flex;align-items:center;gap:var(--ndt-spacing-xs);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);min-height:36px;border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);background:var(--ndt-bg-primary);color:var(--ndt-text-primary);cursor:pointer;transition:var(--ndt-transition-default);outline:none;font-family:inherit}.button:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary)}.button:focus-visible{outline:none;background:var(--ndt-hover-bg);box-shadow:0 0 0 2px rgba(var(--ndt-primary-rgb),.2)}.button.primary{background:var(--ndt-primary);color:var(--ndt-text-on-primary);border-color:var(--ndt-primary)}.button.primary:hover{background:var(--ndt-primary);border-color:var(--ndt-primary)}.button.icon-only{padding:var(--ndt-spacing-xs);width:32px;height:32px;justify-content:center}.button.small{font-size:var(--ndt-font-size-sm)}\n"] }]
3861
4453
  }] });
3862
4454
 
3863
- class ToolbarCardComponent {
4455
+ class ToolbarConfirmDialogComponent {
3864
4456
  constructor() {
3865
- this.click = signal(undefined);
3866
- this.isHovered = signal(false);
4457
+ this.title = input.required();
4458
+ this.message = input('');
4459
+ this.confirmLabel = input('Confirm');
4460
+ this.cancelLabel = input('Cancel');
4461
+ this.danger = input(false);
4462
+ this.confirmed = output();
4463
+ this.cancelled = output();
4464
+ this.dialogRef = viewChild.required('dialog');
4465
+ this.result = null;
3867
4466
  }
3868
- onClick() {
3869
- this.click.set();
4467
+ show() {
4468
+ this.result = null;
4469
+ this.dialogRef().nativeElement.showModal();
3870
4470
  }
3871
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3872
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: ToolbarCardComponent, isStandalone: true, selector: "ndt-card", ngImport: i0, template: `
3873
- <div
3874
- class="card"
3875
- role="button"
3876
- tabindex="0"
3877
- (click)="onClick()"
3878
- (keydown.enter)="onClick()"
3879
- (keydown.space)="onClick()"
3880
- [class.card--hover]="isHovered()"
3881
- (mouseenter)="isHovered.set(true)"
3882
- (mouseleave)="isHovered.set(false)"
3883
- >
3884
- <ng-content></ng-content>
3885
- </div>
3886
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.card{background:var(--ndt-bg-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md);cursor:pointer;transition:var(--ndt-transition-default);border:1px solid var(--ndt-border-subtle);position:relative;flex:1;height:120px;display:flex}.card:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 0 0 1px rgba(var(--ndt-primary-rgb),.3)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3887
- }
3888
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarCardComponent, decorators: [{
3889
- type: Component,
3890
- args: [{ selector: 'ndt-card', standalone: true, template: `
3891
- <div
3892
- class="card"
3893
- role="button"
3894
- tabindex="0"
3895
- (click)="onClick()"
3896
- (keydown.enter)="onClick()"
3897
- (keydown.space)="onClick()"
3898
- [class.card--hover]="isHovered()"
3899
- (mouseenter)="isHovered.set(true)"
3900
- (mouseleave)="isHovered.set(false)"
3901
- >
3902
- <ng-content></ng-content>
3903
- </div>
3904
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.card{background:var(--ndt-bg-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md);cursor:pointer;transition:var(--ndt-transition-default);border:1px solid var(--ndt-border-subtle);position:relative;flex:1;height:120px;display:flex}.card:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 0 0 1px rgba(var(--ndt-primary-rgb),.3)}\n"] }]
3905
- }] });
3906
-
3907
- class ToolbarClickableCardComponent {
3908
- constructor() {
3909
- this.icon = input.required();
3910
- this.title = input.required();
3911
- this.subtitle = input.required();
3912
- this.click = signal(undefined);
4471
+ confirm() {
4472
+ this.result = 'confirm';
4473
+ this.dialogRef().nativeElement.close();
3913
4474
  }
3914
- onClick() {
3915
- this.click.set();
4475
+ cancel() {
4476
+ this.result = 'cancel';
4477
+ this.dialogRef().nativeElement.close();
3916
4478
  }
3917
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarClickableCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3918
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.7", type: ToolbarClickableCardComponent, isStandalone: true, selector: "ndt-clickable-card", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
3919
- <ndt-card (clicked)="onClick()">
3920
- <div class="clickable-card">
3921
- <div class="clickable-card__icon">
3922
- <ndt-icon [name]="icon()" />
3923
- </div>
3924
- <div class="clickable-card__content">
3925
- <div class="clickable-card__title">{{ title() }}</div>
3926
- <div class="clickable-card__subtitle">{{ subtitle() }}</div>
4479
+ onBackdropClick(event) {
4480
+ if (event.target === this.dialogRef().nativeElement) {
4481
+ this.cancel();
4482
+ }
4483
+ }
4484
+ onDialogClose() {
4485
+ if (this.result === 'confirm') {
4486
+ this.confirmed.emit();
4487
+ }
4488
+ else {
4489
+ this.cancelled.emit();
4490
+ }
4491
+ }
4492
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarConfirmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4493
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarConfirmDialogComponent, isStandalone: true, selector: "ndt-confirm-dialog", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, danger: { classPropertyName: "danger", publicName: "danger", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialog"], descendants: true, isSignal: true }], ngImport: i0, template: `
4494
+ <dialog
4495
+ #dialog
4496
+ class="confirm-dialog"
4497
+ tabindex="-1"
4498
+ [class.confirm-dialog--danger]="danger()"
4499
+ (click)="onBackdropClick($event)"
4500
+ (keydown.escape)="cancel()"
4501
+ (close)="onDialogClose()"
4502
+ >
4503
+ <div class="confirm-dialog__content">
4504
+ <h2 class="confirm-dialog__title">{{ title() }}</h2>
4505
+ @if (message()) {
4506
+ <p class="confirm-dialog__message">{{ message() }}</p>
4507
+ }
4508
+ <div class="confirm-dialog__actions">
4509
+ <button
4510
+ type="button"
4511
+ class="confirm-dialog__btn confirm-dialog__btn--secondary"
4512
+ (click)="cancel()"
4513
+ >
4514
+ {{ cancelLabel() }}
4515
+ </button>
4516
+ <button
4517
+ type="button"
4518
+ class="confirm-dialog__btn"
4519
+ [class.confirm-dialog__btn--danger]="danger()"
4520
+ [class.confirm-dialog__btn--primary]="!danger()"
4521
+ (click)="confirm()"
4522
+ >
4523
+ {{ confirmLabel() }}
4524
+ </button>
3927
4525
  </div>
3928
4526
  </div>
3929
- </ndt-card>
3930
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.clickable-card{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);height:100%}.clickable-card__icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.clickable-card__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.clickable-card__title{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.clickable-card__subtitle{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n"], dependencies: [{ kind: "component", type: ToolbarCardComponent, selector: "ndt-card" }, { kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4527
+ </dialog>
4528
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.confirm-dialog{padding:0;border:0;background:var(--ndt-bg-primary);color:var(--ndt-text-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:var(--ndt-shadow-window);max-width:380px;width:calc(100vw - 2rem);font-family:inherit;contain:layout style}.confirm-dialog::backdrop{background:#00000059;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.confirm-dialog__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);padding:var(--ndt-spacing-lg)}.confirm-dialog__title{margin:0;font-size:var(--ndt-font-size-md);font-weight:600;color:var(--ndt-text-primary);line-height:1.3}.confirm-dialog__message{margin:0;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-secondary);line-height:1.5}.confirm-dialog__actions{display:flex;justify-content:flex-end;gap:var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-xs)}.confirm-dialog__btn{appearance:none;border:1px solid transparent;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-sm);font-weight:500;font-family:inherit;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.confirm-dialog__btn:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.confirm-dialog__btn--secondary{background:transparent;border-color:var(--ndt-border-primary);color:var(--ndt-text-primary)}.confirm-dialog__btn--secondary:hover{background:var(--ndt-hover-bg)}.confirm-dialog__btn--primary{background:var(--ndt-primary);color:var(--ndt-text-on-primary)}.confirm-dialog__btn--primary:hover{filter:brightness(.95)}.confirm-dialog__btn--danger{background:var(--ndt-danger);color:#fff}.confirm-dialog__btn--danger:hover{filter:brightness(.95)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3931
4529
  }
3932
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarClickableCardComponent, decorators: [{
4530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarConfirmDialogComponent, decorators: [{
3933
4531
  type: Component,
3934
- args: [{ selector: 'ndt-clickable-card', standalone: true, imports: [ToolbarCardComponent, ToolbarIconComponent], template: `
3935
- <ndt-card (clicked)="onClick()">
3936
- <div class="clickable-card">
3937
- <div class="clickable-card__icon">
3938
- <ndt-icon [name]="icon()" />
3939
- </div>
3940
- <div class="clickable-card__content">
3941
- <div class="clickable-card__title">{{ title() }}</div>
3942
- <div class="clickable-card__subtitle">{{ subtitle() }}</div>
4532
+ args: [{ selector: 'ndt-confirm-dialog', standalone: true, template: `
4533
+ <dialog
4534
+ #dialog
4535
+ class="confirm-dialog"
4536
+ tabindex="-1"
4537
+ [class.confirm-dialog--danger]="danger()"
4538
+ (click)="onBackdropClick($event)"
4539
+ (keydown.escape)="cancel()"
4540
+ (close)="onDialogClose()"
4541
+ >
4542
+ <div class="confirm-dialog__content">
4543
+ <h2 class="confirm-dialog__title">{{ title() }}</h2>
4544
+ @if (message()) {
4545
+ <p class="confirm-dialog__message">{{ message() }}</p>
4546
+ }
4547
+ <div class="confirm-dialog__actions">
4548
+ <button
4549
+ type="button"
4550
+ class="confirm-dialog__btn confirm-dialog__btn--secondary"
4551
+ (click)="cancel()"
4552
+ >
4553
+ {{ cancelLabel() }}
4554
+ </button>
4555
+ <button
4556
+ type="button"
4557
+ class="confirm-dialog__btn"
4558
+ [class.confirm-dialog__btn--danger]="danger()"
4559
+ [class.confirm-dialog__btn--primary]="!danger()"
4560
+ (click)="confirm()"
4561
+ >
4562
+ {{ confirmLabel() }}
4563
+ </button>
3943
4564
  </div>
3944
4565
  </div>
3945
- </ndt-card>
3946
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.clickable-card{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);height:100%}.clickable-card__icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.clickable-card__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.clickable-card__title{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.clickable-card__subtitle{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n"] }]
4566
+ </dialog>
4567
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.confirm-dialog{padding:0;border:0;background:var(--ndt-bg-primary);color:var(--ndt-text-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:var(--ndt-shadow-window);max-width:380px;width:calc(100vw - 2rem);font-family:inherit;contain:layout style}.confirm-dialog::backdrop{background:#00000059;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.confirm-dialog__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);padding:var(--ndt-spacing-lg)}.confirm-dialog__title{margin:0;font-size:var(--ndt-font-size-md);font-weight:600;color:var(--ndt-text-primary);line-height:1.3}.confirm-dialog__message{margin:0;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-secondary);line-height:1.5}.confirm-dialog__actions{display:flex;justify-content:flex-end;gap:var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-xs)}.confirm-dialog__btn{appearance:none;border:1px solid transparent;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-sm);font-weight:500;font-family:inherit;cursor:pointer;transition:background-color .15s ease,border-color .15s ease,color .15s ease}.confirm-dialog__btn:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.confirm-dialog__btn--secondary{background:transparent;border-color:var(--ndt-border-primary);color:var(--ndt-text-primary)}.confirm-dialog__btn--secondary:hover{background:var(--ndt-hover-bg)}.confirm-dialog__btn--primary{background:var(--ndt-primary);color:var(--ndt-text-on-primary)}.confirm-dialog__btn--primary:hover{filter:brightness(.95)}.confirm-dialog__btn--danger{background:var(--ndt-danger);color:#fff}.confirm-dialog__btn--danger:hover{filter:brightness(.95)}\n"] }]
3947
4568
  }] });
3948
4569
 
3949
4570
  class ToolbarLinkButtonComponent {
@@ -3966,7 +4587,7 @@ class ToolbarLinkButtonComponent {
3966
4587
  <ng-content></ng-content>
3967
4588
  </span>
3968
4589
  </a>
3969
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.link-button{display:flex;flex-direction:column;align-items:center;gap:var(--ndt-spacing-xs);text-decoration:none;color:var(--ndt-text-muted);transition:var(--ndt-transition-default)}.link-button:hover{color:var(--ndt-text-primary)}.link-button:hover .link-button__icon{outline:2px solid var(--ndt-primary);outline-offset:2px;box-shadow:0 0 8px var(--ndt-primary)}.link-button__icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);transition:all .2s ease-in-out}.link-button__text{font-size:var(--ndt-font-size-xs);text-align:center;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4590
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.link-button{display:flex;flex-direction:column;align-items:center;gap:var(--ndt-spacing-xs);text-decoration:none;color:var(--ndt-text-muted);transition:color .15s ease}.link-button:hover{color:var(--ndt-text-primary)}.link-button:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px;border-radius:var(--ndt-border-radius-small)}.link-button__icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);transition:background-color .15s ease}.link-button__text{font-size:var(--ndt-font-size-xs);text-align:center;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3970
4591
  }
3971
4592
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarLinkButtonComponent, decorators: [{
3972
4593
  type: Component,
@@ -3984,7 +4605,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
3984
4605
  <ng-content></ng-content>
3985
4606
  </span>
3986
4607
  </a>
3987
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.link-button{display:flex;flex-direction:column;align-items:center;gap:var(--ndt-spacing-xs);text-decoration:none;color:var(--ndt-text-muted);transition:var(--ndt-transition-default)}.link-button:hover{color:var(--ndt-text-primary)}.link-button:hover .link-button__icon{outline:2px solid var(--ndt-primary);outline-offset:2px;box-shadow:0 0 8px var(--ndt-primary)}.link-button__icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);transition:all .2s ease-in-out}.link-button__text{font-size:var(--ndt-font-size-xs);text-align:center;white-space:nowrap}\n"] }]
4608
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.link-button{display:flex;flex-direction:column;align-items:center;gap:var(--ndt-spacing-xs);text-decoration:none;color:var(--ndt-text-muted);transition:color .15s ease}.link-button:hover{color:var(--ndt-text-primary)}.link-button:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px;border-radius:var(--ndt-border-radius-small)}.link-button__icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);transition:background-color .15s ease}.link-button__text{font-size:var(--ndt-font-size-xs);text-align:center;white-space:nowrap}\n"] }]
3988
4609
  }] });
3989
4610
 
3990
4611
  const TOOLBAR_POSITIONS = [
@@ -4062,6 +4683,7 @@ class ToolbarHomeToolComponent {
4062
4683
  label: 'Community',
4063
4684
  },
4064
4685
  ];
4686
+ this.resetDialog = viewChild('resetDialog');
4065
4687
  }
4066
4688
  onPositionChange(position) {
4067
4689
  this.state.setPosition(position);
@@ -4105,11 +4727,14 @@ class ToolbarHomeToolComponent {
4105
4727
  input.click();
4106
4728
  }
4107
4729
  onResetSettings() {
4730
+ this.resetDialog()?.show();
4731
+ }
4732
+ confirmReset() {
4108
4733
  this.storageService.clearAllSettings();
4109
4734
  window.location.reload();
4110
4735
  }
4111
4736
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarHomeToolComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4112
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarHomeToolComponent, isStandalone: true, selector: "ndt-home-tool", inputs: { badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
4737
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarHomeToolComponent, isStandalone: true, selector: "ndt-home-tool", inputs: { badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "resetDialog", first: true, predicate: ["resetDialog"], descendants: true, isSignal: true }], ngImport: i0, template: `
4113
4738
  <ndt-toolbar-tool [options]="options" toolTitle="Home" icon="angular">
4114
4739
  <section class="settings">
4115
4740
  <div class="settings-container">
@@ -4136,35 +4761,53 @@ class ToolbarHomeToolComponent {
4136
4761
 
4137
4762
  <div class="instruction">
4138
4763
  <div class="instruction__label">
4139
- <span class="instruction__label-text">Reset Settings</span>
4764
+ <span class="instruction__label-text">Export Settings</span>
4140
4765
  <span class="instruction__label-description">
4141
- Reset all settings to their default values
4766
+ Download the current setup to share or reproduce in tests
4142
4767
  </span>
4143
4768
  </div>
4144
4769
  <div class="instruction__control">
4145
- <div class="instruction__control-button">
4146
- <ndt-button
4147
- variant="icon"
4148
- icon="trash"
4149
- ariaLabel="Reset all settings"
4150
- (click)="onResetSettings()"
4151
- />
4152
- </div>
4770
+ <ndt-button
4771
+ variant="icon"
4772
+ icon="export"
4773
+ ariaLabel="Export settings"
4774
+ (click)="onExportSettings()"
4775
+ />
4153
4776
  </div>
4154
4777
  </div>
4155
- <div class="settings-actions">
4156
- <ndt-clickable-card
4157
- icon="export"
4158
- title="Export Settings"
4159
- subtitle="Export the current settings to share with other devs or use in your tests"
4160
- (click)="onExportSettings()"
4161
- />
4162
- <ndt-clickable-card
4163
- icon="import"
4164
- title="Import Settings"
4165
- subtitle="Import settings to reproduce a scenario"
4166
- (click)="onImportSettings()"
4167
- />
4778
+
4779
+ <div class="instruction">
4780
+ <div class="instruction__label">
4781
+ <span class="instruction__label-text">Import Settings</span>
4782
+ <span class="instruction__label-description">
4783
+ Load a settings file to reproduce a scenario
4784
+ </span>
4785
+ </div>
4786
+ <div class="instruction__control">
4787
+ <ndt-button
4788
+ variant="icon"
4789
+ icon="import"
4790
+ ariaLabel="Import settings"
4791
+ (click)="onImportSettings()"
4792
+ />
4793
+ </div>
4794
+ </div>
4795
+
4796
+ <div class="instruction instruction--danger-zone">
4797
+ <div class="instruction__label">
4798
+ <span class="instruction__label-text">Reset Settings</span>
4799
+ <span class="instruction__label-description">
4800
+ Clear all forced values, presets, and stored preferences
4801
+ </span>
4802
+ </div>
4803
+ <div class="instruction__control">
4804
+ <ndt-button
4805
+ variant="icon"
4806
+ icon="trash"
4807
+ ariaLabel="Reset all settings"
4808
+ (click)="onResetSettings()"
4809
+ />
4810
+ </div>
4168
4811
  </div>
4169
4812
  </div>
4170
4813
 
@@ -4177,7 +4820,17 @@ class ToolbarHomeToolComponent {
4177
4820
  </div>
4178
4821
  </section>
4179
4822
  </ndt-toolbar-tool>
4180
- `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.settings{display:flex;flex-direction:column;height:100%}.instruction{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--ndt-spacing-sm)}.instruction__label{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.instruction__label-text{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.instruction__label-description{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs)}.instruction__control{flex:1}.instruction__control-button{display:flex;gap:var(--ndt-spacing-xs);justify-content:flex-end}.settings-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-md)}.settings-container .settings-actions{display:flex;gap:var(--ndt-spacing-md)}.settings-container .settings-actions>*{width:50%;min-width:0}.position-selector{display:flex;gap:var(--ndt-spacing-sm)}.position-selector .position-option{flex:1;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);background:transparent;color:var(--ndt-text-secondary);font-size:var(--ndt-font-size-xs);font-family:inherit;cursor:pointer;transition:all .15s ease;text-transform:capitalize}.position-selector .position-option:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.position-selector .position-option--active{background:var(--ndt-primary);color:var(--ndt-text-on-primary);border-color:var(--ndt-primary)}.position-selector .position-option--active:hover{background:var(--ndt-primary);color:var(--ndt-text-on-primary)}.footer-links{margin-top:auto;padding-top:var(--ndt-spacing-lg);border-top:1px solid var(--ndt-border-subtle);display:flex;flex-direction:row;justify-content:space-between;gap:var(--ndt-spacing-lg)}\n"], dependencies: [{ kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarButtonComponent, selector: "ndt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }, { kind: "component", type: ToolbarClickableCardComponent, selector: "ndt-clickable-card", inputs: ["icon", "title", "subtitle"] }, { kind: "component", type: ToolbarLinkButtonComponent, selector: "ndt-link-button", inputs: ["url", "icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4823
+
4824
+ <ndt-confirm-dialog
4825
+ #resetDialog
4826
+ title="Reset all settings?"
4827
+ message="This will clear all forced values, presets, and stored preferences for this session. The page will reload. This cannot be undone."
4828
+ confirmLabel="Reset settings"
4829
+ cancelLabel="Cancel"
4830
+ [danger]="true"
4831
+ (confirmed)="confirmReset()"
4832
+ />
4833
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.settings{display:flex;flex-direction:column;height:100%}.instruction{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--ndt-spacing-sm)}.instruction__label{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.instruction__label-text{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.instruction__label-description{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs)}.instruction__control{flex:0 0 auto}.instruction__control-button{display:flex;gap:var(--ndt-spacing-xs);justify-content:flex-end}.instruction__control ::ng-deep .button{border-color:transparent;background:transparent;width:32px;height:32px;min-height:32px;padding:0;display:inline-flex;align-items:center;justify-content:center}.instruction__control ::ng-deep .button:hover{background:var(--ndt-hover-bg);border-color:transparent}.instruction--danger-zone{margin-top:var(--ndt-spacing-sm);padding-top:var(--ndt-spacing-md);border-top:1px solid var(--ndt-border-subtle)}.instruction--danger-zone .instruction__control ::ng-deep .button:hover{background:rgba(var(--ndt-danger-rgb),.1);color:var(--ndt-danger)}.settings-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-md)}.position-selector{display:inline-flex;padding:2px;background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);align-self:stretch;width:100%}.position-selector .position-option{flex:1;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:0;background:transparent;color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs);font-weight:500;font-family:inherit;cursor:pointer;transition:background-color .15s ease,color .15s ease;text-transform:capitalize;border-radius:calc(var(--ndt-border-radius-medium) - 2px);white-space:nowrap}.position-selector .position-option:hover:not(.position-option--active){color:var(--ndt-text-primary)}.position-selector .position-option:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.position-selector .position-option--active{background:var(--ndt-bg-primary);color:var(--ndt-text-primary);box-shadow:0 1px 2px #0000000f}.footer-links{margin-top:auto;padding-top:var(--ndt-spacing-md);border-top:1px solid var(--ndt-border-subtle);display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:var(--ndt-spacing-sm);flex-wrap:wrap}.footer-links ::ng-deep .link-button{flex-direction:row;align-items:center;gap:var(--ndt-spacing-xs);color:var(--ndt-text-muted);transition:color .15s ease}.footer-links ::ng-deep .link-button:hover{color:var(--ndt-text-primary)}.footer-links ::ng-deep .link-button__icon{width:auto;height:auto;background:transparent;padding:0}.footer-links ::ng-deep .link-button__icon svg{width:12px;height:12px}.footer-links ::ng-deep .link-button__text{font-size:var(--ndt-font-size-xs)}\n"], dependencies: [{ kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarButtonComponent, selector: "ndt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }, { kind: "component", type: ToolbarConfirmDialogComponent, selector: "ndt-confirm-dialog", inputs: ["title", "message", "confirmLabel", "cancelLabel", "danger"], outputs: ["confirmed", "cancelled"] }, { kind: "component", type: ToolbarLinkButtonComponent, selector: "ndt-link-button", inputs: ["url", "icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4181
4834
  }
4182
4835
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarHomeToolComponent, decorators: [{
4183
4836
  type: Component,
@@ -4185,7 +4838,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
4185
4838
  ToolbarToolComponent,
4186
4839
  FormsModule,
4187
4840
  ToolbarButtonComponent,
4188
- ToolbarClickableCardComponent,
4841
+ ToolbarConfirmDialogComponent,
4189
4842
  ToolbarLinkButtonComponent,
4190
4843
  ], template: `
4191
4844
  <ndt-toolbar-tool [options]="options" toolTitle="Home" icon="angular">
@@ -4214,35 +4867,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
4214
4867
 
4215
4868
  <div class="instruction">
4216
4869
  <div class="instruction__label">
4217
- <span class="instruction__label-text">Reset Settings</span>
4870
+ <span class="instruction__label-text">Export Settings</span>
4218
4871
  <span class="instruction__label-description">
4219
- Reset all settings to their default values
4872
+ Download the current setup to share or reproduce in tests
4220
4873
  </span>
4221
4874
  </div>
4222
4875
  <div class="instruction__control">
4223
- <div class="instruction__control-button">
4224
- <ndt-button
4225
- variant="icon"
4226
- icon="trash"
4227
- ariaLabel="Reset all settings"
4228
- (click)="onResetSettings()"
4229
- />
4230
- </div>
4876
+ <ndt-button
4877
+ variant="icon"
4878
+ icon="export"
4879
+ ariaLabel="Export settings"
4880
+ (click)="onExportSettings()"
4881
+ />
4231
4882
  </div>
4232
4883
  </div>
4233
- <div class="settings-actions">
4234
- <ndt-clickable-card
4235
- icon="export"
4236
- title="Export Settings"
4237
- subtitle="Export the current settings to share with other devs or use in your tests"
4238
- (click)="onExportSettings()"
4239
- />
4240
- <ndt-clickable-card
4241
- icon="import"
4242
- title="Import Settings"
4243
- subtitle="Import settings to reproduce a scenario"
4244
- (click)="onImportSettings()"
4245
- />
4884
+
4885
+ <div class="instruction">
4886
+ <div class="instruction__label">
4887
+ <span class="instruction__label-text">Import Settings</span>
4888
+ <span class="instruction__label-description">
4889
+ Load a settings file to reproduce a scenario
4890
+ </span>
4891
+ </div>
4892
+ <div class="instruction__control">
4893
+ <ndt-button
4894
+ variant="icon"
4895
+ icon="import"
4896
+ ariaLabel="Import settings"
4897
+ (click)="onImportSettings()"
4898
+ />
4899
+ </div>
4900
+ </div>
4901
+
4902
+ <div class="instruction instruction--danger-zone">
4903
+ <div class="instruction__label">
4904
+ <span class="instruction__label-text">Reset Settings</span>
4905
+ <span class="instruction__label-description">
4906
+ Clear all forced values, presets, and stored preferences
4907
+ </span>
4908
+ </div>
4909
+ <div class="instruction__control">
4910
+ <ndt-button
4911
+ variant="icon"
4912
+ icon="trash"
4913
+ ariaLabel="Reset all settings"
4914
+ (click)="onResetSettings()"
4915
+ />
4916
+ </div>
4246
4917
  </div>
4247
4918
  </div>
4248
4919
 
@@ -4255,7 +4926,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
4255
4926
  </div>
4256
4927
  </section>
4257
4928
  </ndt-toolbar-tool>
4258
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.settings{display:flex;flex-direction:column;height:100%}.instruction{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--ndt-spacing-sm)}.instruction__label{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.instruction__label-text{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.instruction__label-description{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs)}.instruction__control{flex:1}.instruction__control-button{display:flex;gap:var(--ndt-spacing-xs);justify-content:flex-end}.settings-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-md)}.settings-container .settings-actions{display:flex;gap:var(--ndt-spacing-md)}.settings-container .settings-actions>*{width:50%;min-width:0}.position-selector{display:flex;gap:var(--ndt-spacing-sm)}.position-selector .position-option{flex:1;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);background:transparent;color:var(--ndt-text-secondary);font-size:var(--ndt-font-size-xs);font-family:inherit;cursor:pointer;transition:all .15s ease;text-transform:capitalize}.position-selector .position-option:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.position-selector .position-option--active{background:var(--ndt-primary);color:var(--ndt-text-on-primary);border-color:var(--ndt-primary)}.position-selector .position-option--active:hover{background:var(--ndt-primary);color:var(--ndt-text-on-primary)}.footer-links{margin-top:auto;padding-top:var(--ndt-spacing-lg);border-top:1px solid var(--ndt-border-subtle);display:flex;flex-direction:row;justify-content:space-between;gap:var(--ndt-spacing-lg)}\n"] }]
4929
+
4930
+ <ndt-confirm-dialog
4931
+ #resetDialog
4932
+ title="Reset all settings?"
4933
+ message="This will clear all forced values, presets, and stored preferences for this session. The page will reload. This cannot be undone."
4934
+ confirmLabel="Reset settings"
4935
+ cancelLabel="Cancel"
4936
+ [danger]="true"
4937
+ (confirmed)="confirmReset()"
4938
+ />
4939
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.settings{display:flex;flex-direction:column;height:100%}.instruction{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--ndt-spacing-sm)}.instruction__label{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.instruction__label-text{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.instruction__label-description{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs)}.instruction__control{flex:0 0 auto}.instruction__control-button{display:flex;gap:var(--ndt-spacing-xs);justify-content:flex-end}.instruction__control ::ng-deep .button{border-color:transparent;background:transparent;width:32px;height:32px;min-height:32px;padding:0;display:inline-flex;align-items:center;justify-content:center}.instruction__control ::ng-deep .button:hover{background:var(--ndt-hover-bg);border-color:transparent}.instruction--danger-zone{margin-top:var(--ndt-spacing-sm);padding-top:var(--ndt-spacing-md);border-top:1px solid var(--ndt-border-subtle)}.instruction--danger-zone .instruction__control ::ng-deep .button:hover{background:rgba(var(--ndt-danger-rgb),.1);color:var(--ndt-danger)}.settings-container{display:flex;flex-direction:column;gap:var(--ndt-spacing-md)}.position-selector{display:inline-flex;padding:2px;background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);align-self:stretch;width:100%}.position-selector .position-option{flex:1;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);border:0;background:transparent;color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs);font-weight:500;font-family:inherit;cursor:pointer;transition:background-color .15s ease,color .15s ease;text-transform:capitalize;border-radius:calc(var(--ndt-border-radius-medium) - 2px);white-space:nowrap}.position-selector .position-option:hover:not(.position-option--active){color:var(--ndt-text-primary)}.position-selector .position-option:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:1px}.position-selector .position-option--active{background:var(--ndt-bg-primary);color:var(--ndt-text-primary);box-shadow:0 1px 2px #0000000f}.footer-links{margin-top:auto;padding-top:var(--ndt-spacing-md);border-top:1px solid var(--ndt-border-subtle);display:flex;flex-direction:row;justify-content:space-between;align-items:center;gap:var(--ndt-spacing-sm);flex-wrap:wrap}.footer-links ::ng-deep .link-button{flex-direction:row;align-items:center;gap:var(--ndt-spacing-xs);color:var(--ndt-text-muted);transition:color .15s ease}.footer-links ::ng-deep .link-button:hover{color:var(--ndt-text-primary)}.footer-links ::ng-deep .link-button__icon{width:auto;height:auto;background:transparent;padding:0}.footer-links ::ng-deep .link-button__icon svg{width:12px;height:12px}.footer-links ::ng-deep .link-button__text{font-size:var(--ndt-font-size-xs)}\n"] }]
4259
4940
  }] });
4260
4941
 
4261
4942
  const DEFAULT_TIMEZONES = [
@@ -4804,6 +5485,13 @@ class ToolbarI18nToolComponent {
4804
5485
  this.rtlEnabled = this.i18nService.rtlEnabled;
4805
5486
  // --- Computed ---
4806
5487
  this.toolConfig = computed(() => this.i18nService.toolConfig());
5488
+ this.hasAdvancedFormatSettings = computed(() => {
5489
+ const cfg = this.toolConfig();
5490
+ return (cfg.showUnits !== false ||
5491
+ cfg.showDateFormat !== false ||
5492
+ cfg.showNumberFormat !== false ||
5493
+ cfg.showFirstDayOfWeek !== false);
5494
+ });
4807
5495
  this.localeOptions = toSignal(this.i18nService.getAvailableLocales().pipe(map((locales) => [
4808
5496
  { value: NOT_FORCED, label: 'Not Forced' },
4809
5497
  ...locales.map(({ id: value, name: label }) => ({ value, label })),
@@ -4966,10 +5654,9 @@ class ToolbarI18nToolComponent {
4966
5654
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarI18nToolComponent, isStandalone: true, selector: "ndt-i18n-tool", ngImport: i0, template: `
4967
5655
  <ndt-toolbar-tool toolTitle="i18n" icon="globe" [options]="options">
4968
5656
  <div class="i18n-section">
4969
- <!-- Formatting Preview (at top for immediate feedback) -->
5657
+ <!-- Formatting Preview (immediate feedback, always visible) -->
4970
5658
  @if (toolConfig().showFormattingPreview !== false) {
4971
- <div class="i18n-section-header">FORMATTING PREVIEW</div>
4972
- <div class="i18n-preview">
5659
+ <div class="i18n-preview" aria-label="Formatting preview">
4973
5660
  <div class="i18n-preview-row">
4974
5661
  <span class="preview-label">Number</span>
4975
5662
  <span class="preview-value">{{ previewNumber() }}</span>
@@ -4989,7 +5676,7 @@ class ToolbarI18nToolComponent {
4989
5676
  </div>
4990
5677
  }
4991
5678
 
4992
- <!-- Settings (flat 2-column grid) -->
5679
+ <!-- Core settings: locale, timezone, currency -->
4993
5680
  <div class="i18n-select-grid">
4994
5681
  @if (toolConfig().showLocale !== false) {
4995
5682
  <div class="i18n-select-group">
@@ -5027,108 +5714,118 @@ class ToolbarI18nToolComponent {
5027
5714
  />
5028
5715
  </div>
5029
5716
  }
5030
- @if (toolConfig().showUnits !== false) {
5031
- <div class="i18n-select-group">
5032
- <label for="i18n-units">Units</label>
5033
- <ndt-select
5034
- id="i18n-units"
5035
- [value]="activeUnitSystem()"
5036
- [options]="unitSystemOptions"
5037
- [size]="'medium'"
5038
- (valueChange)="onUnitSystemChange($event ?? '')"
5039
- />
5040
- </div>
5041
- }
5042
- @if (toolConfig().showDateFormat !== false) {
5043
- <div class="i18n-select-group">
5044
- <label for="i18n-date-format">Date Format</label>
5045
- <ndt-select
5046
- id="i18n-date-format"
5047
- [value]="activeDateFormat()"
5048
- [options]="dateFormatOptions"
5049
- [size]="'medium'"
5050
- (valueChange)="onDateFormatChange($event ?? '')"
5051
- />
5052
- </div>
5053
- }
5054
- @if (toolConfig().showNumberFormat !== false) {
5055
- <div class="i18n-select-group">
5056
- <label for="i18n-number-format">Number Format</label>
5057
- <ndt-select
5058
- id="i18n-number-format"
5059
- [value]="activeNumberFormat()"
5060
- [options]="numberFormatOptions"
5061
- [size]="'medium'"
5062
- (valueChange)="onNumberFormatChange($event ?? '')"
5063
- />
5064
- </div>
5065
- }
5066
- @if (toolConfig().showFirstDayOfWeek !== false) {
5067
- <div class="i18n-select-group">
5068
- <label for="i18n-first-day">First Day of Week</label>
5069
- <ndt-select
5070
- id="i18n-first-day"
5071
- [value]="activeFirstDayOfWeek()"
5072
- [options]="firstDayOptions"
5073
- [size]="'medium'"
5074
- (valueChange)="onFirstDayOfWeekChange($event ?? '')"
5075
- />
5076
- </div>
5077
- }
5078
5717
  </div>
5079
5718
 
5080
- <!-- Stress Testing -->
5081
- @if (toolConfig().showStressTesting !== false) {
5082
- <div class="i18n-section-header">STRESS TESTING</div>
5083
- <div class="i18n-toggle-section">
5084
- <div class="i18n-toggle-row">
5085
- <div class="toggle-info">
5086
- <span class="toggle-label">Pseudo-Localization</span>
5087
- <span class="toggle-hint">Detect hardcoded strings</span>
5088
- </div>
5089
- <label class="toggle-switch">
5090
- <input
5091
- type="checkbox"
5092
- [checked]="pseudoLocEnabled()"
5093
- (change)="onPseudoLocToggle($event)"
5094
- />
5095
- <span class="toggle-track"></span>
5096
- </label>
5719
+ <!-- Advanced format options (progressive disclosure) -->
5720
+ @if (hasAdvancedFormatSettings()) {
5721
+ <details class="i18n-disclosure">
5722
+ <summary>Advanced format options</summary>
5723
+ <div class="i18n-select-grid">
5724
+ @if (toolConfig().showUnits !== false) {
5725
+ <div class="i18n-select-group">
5726
+ <label for="i18n-units">Units</label>
5727
+ <ndt-select
5728
+ id="i18n-units"
5729
+ [value]="activeUnitSystem()"
5730
+ [options]="unitSystemOptions"
5731
+ [size]="'medium'"
5732
+ (valueChange)="onUnitSystemChange($event ?? '')"
5733
+ />
5734
+ </div>
5735
+ }
5736
+ @if (toolConfig().showDateFormat !== false) {
5737
+ <div class="i18n-select-group">
5738
+ <label for="i18n-date-format">Date Format</label>
5739
+ <ndt-select
5740
+ id="i18n-date-format"
5741
+ [value]="activeDateFormat()"
5742
+ [options]="dateFormatOptions"
5743
+ [size]="'medium'"
5744
+ (valueChange)="onDateFormatChange($event ?? '')"
5745
+ />
5746
+ </div>
5747
+ }
5748
+ @if (toolConfig().showNumberFormat !== false) {
5749
+ <div class="i18n-select-group">
5750
+ <label for="i18n-number-format">Number Format</label>
5751
+ <ndt-select
5752
+ id="i18n-number-format"
5753
+ [value]="activeNumberFormat()"
5754
+ [options]="numberFormatOptions"
5755
+ [size]="'medium'"
5756
+ (valueChange)="onNumberFormatChange($event ?? '')"
5757
+ />
5758
+ </div>
5759
+ }
5760
+ @if (toolConfig().showFirstDayOfWeek !== false) {
5761
+ <div class="i18n-select-group">
5762
+ <label for="i18n-first-day">First Day of Week</label>
5763
+ <ndt-select
5764
+ id="i18n-first-day"
5765
+ [value]="activeFirstDayOfWeek()"
5766
+ [options]="firstDayOptions"
5767
+ [size]="'medium'"
5768
+ (valueChange)="onFirstDayOfWeekChange($event ?? '')"
5769
+ />
5770
+ </div>
5771
+ }
5097
5772
  </div>
5098
- @if (pseudoLocEnabled()) {
5099
- <div class="i18n-pseudo-preview">
5100
- {{ pseudoPreview() }}
5773
+ </details>
5774
+ }
5775
+
5776
+ <!-- Stress Testing (separate collapsible section) -->
5777
+ @if (toolConfig().showStressTesting !== false) {
5778
+ <details class="i18n-disclosure">
5779
+ <summary>Stress testing</summary>
5780
+ <div class="i18n-toggle-section">
5781
+ <div class="i18n-toggle-row">
5782
+ <div class="toggle-info">
5783
+ <span class="toggle-label">Pseudo-Localization</span>
5784
+ <span class="toggle-hint">Detect hardcoded strings</span>
5785
+ </div>
5786
+ <label class="toggle-switch">
5787
+ <input
5788
+ type="checkbox"
5789
+ [checked]="pseudoLocEnabled()"
5790
+ (change)="onPseudoLocToggle($event)"
5791
+ />
5792
+ <span class="toggle-track"></span>
5793
+ </label>
5101
5794
  </div>
5102
- }
5103
- <div class="i18n-toggle-row">
5104
- <div class="toggle-info">
5105
- <span class="toggle-label">RTL Mirroring</span>
5106
- <span class="toggle-hint">Set document direction to RTL</span>
5795
+ @if (pseudoLocEnabled()) {
5796
+ <div class="i18n-pseudo-preview">
5797
+ {{ pseudoPreview() }}
5798
+ </div>
5799
+ }
5800
+ <div class="i18n-toggle-row">
5801
+ <div class="toggle-info">
5802
+ <span class="toggle-label">RTL Mirroring</span>
5803
+ <span class="toggle-hint">Set document direction to RTL</span>
5804
+ </div>
5805
+ <label class="toggle-switch">
5806
+ <input
5807
+ type="checkbox"
5808
+ [checked]="rtlEnabled()"
5809
+ (change)="onRtlToggle($event)"
5810
+ />
5811
+ <span class="toggle-track"></span>
5812
+ </label>
5107
5813
  </div>
5108
- <label class="toggle-switch">
5109
- <input
5110
- type="checkbox"
5111
- [checked]="rtlEnabled()"
5112
- (change)="onRtlToggle($event)"
5113
- />
5114
- <span class="toggle-track"></span>
5115
- </label>
5116
5814
  </div>
5117
- </div>
5815
+ </details>
5118
5816
  }
5119
5817
  </div>
5120
5818
  </ndt-toolbar-tool>
5121
- `, isInline: true, styles: [":host{display:block}.i18n-section{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);padding-top:0}.i18n-section-header{font-size:var(--ndt-font-size-xxs);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ndt-text-muted);margin-top:var(--ndt-spacing-md);padding:var(--ndt-spacing-xs) 0 var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-left:2px solid rgba(var(--ndt-primary-rgb),.4)}.i18n-section-header:first-child{margin-top:0}.i18n-select-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--ndt-spacing-sm) var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-xs)}.i18n-select-group{display:flex;flex-direction:column;gap:2px}.i18n-select-group label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:600}.i18n-standalone-select{margin-top:var(--ndt-spacing-sm)}.i18n-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);border-left:2px solid var(--ndt-border-primary);padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-xs);display:flex;flex-direction:column;gap:1px}.i18n-preview-row{display:flex;justify-content:space-between;align-items:center;font-size:var(--ndt-font-size-xxs);gap:var(--ndt-spacing-xs);padding:2px 0}.i18n-preview-row .preview-label{color:var(--ndt-text-muted);flex-shrink:0}.i18n-preview-row .preview-value{font-family:JetBrains Mono,ui-monospace,monospace;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-primary);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.i18n-toggle-section{display:flex;flex-direction:column;gap:0;margin-top:var(--ndt-spacing-xs)}.i18n-toggle-row{display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);gap:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);transition:background .15s ease}.i18n-toggle-row:hover{background:var(--ndt-hover-bg)}.i18n-toggle-row .toggle-info{display:flex;flex-direction:column;gap:1px;min-width:0}.i18n-toggle-row .toggle-label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:500}.i18n-toggle-row .toggle-hint{font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);line-height:1.3}.toggle-switch{position:relative;display:inline-flex;align-items:center;width:34px;height:18px;flex-shrink:0;cursor:pointer}.toggle-switch input{opacity:0;width:0;height:0;position:absolute}.toggle-switch input:focus-visible+.toggle-track{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.toggle-switch .toggle-track{position:absolute;inset:0;background:var(--ndt-border-primary);border-radius:9px;transition:background .2s ease}.toggle-switch .toggle-track:after{content:\"\";position:absolute;top:2px;left:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .2s cubic-bezier(.4,0,.2,1);box-shadow:0 1px 2px #0000001f}.toggle-switch input:checked+.toggle-track{background:var(--ndt-primary)}.toggle-switch input:checked+.toggle-track:after{transform:translate(16px)}.i18n-pseudo-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-small);border-left:2px solid rgba(var(--ndt-primary-rgb),.3);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);margin:0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);font-family:JetBrains Mono,ui-monospace,monospace;word-break:break-word;line-height:1.5}\n"], dependencies: [{ kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5819
+ `, isInline: true, styles: [":host{display:block}.i18n-section{display:flex;flex-direction:column;gap:var(--ndt-spacing-sm);padding-top:0}.i18n-select-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--ndt-spacing-sm)}.i18n-disclosure{margin:0}.i18n-disclosure summary{font-size:var(--ndt-font-size-xs);font-weight:500;color:var(--ndt-text-secondary);padding:var(--ndt-spacing-xs) 0;cursor:pointer;list-style:none;display:flex;align-items:center;gap:var(--ndt-spacing-xs);-webkit-user-select:none;user-select:none;border-radius:var(--ndt-border-radius-small)}.i18n-disclosure summary::-webkit-details-marker{display:none}.i18n-disclosure summary:before{content:\"\";display:inline-block;width:0;height:0;border-left:4px solid var(--ndt-text-muted);border-top:3px solid transparent;border-bottom:3px solid transparent;transition:transform .15s ease}.i18n-disclosure summary:hover{color:var(--ndt-text-primary)}.i18n-disclosure summary:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.i18n-disclosure[open] summary:before{transform:rotate(90deg)}.i18n-disclosure>:not(summary){margin-top:var(--ndt-spacing-sm)}.i18n-select-group{display:flex;flex-direction:column;gap:2px}.i18n-select-group label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:600}.i18n-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);display:flex;flex-direction:column;gap:1px}.i18n-preview-row{display:flex;justify-content:space-between;align-items:center;font-size:var(--ndt-font-size-xxs);gap:var(--ndt-spacing-xs);padding:2px 0}.i18n-preview-row .preview-label{color:var(--ndt-text-muted);flex-shrink:0}.i18n-preview-row .preview-value{font-family:JetBrains Mono,ui-monospace,monospace;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-primary);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.i18n-toggle-section{display:flex;flex-direction:column;gap:0}.i18n-toggle-row{display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);gap:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);transition:background .15s ease}.i18n-toggle-row:hover{background:var(--ndt-hover-bg)}.i18n-toggle-row .toggle-info{display:flex;flex-direction:column;gap:1px;min-width:0}.i18n-toggle-row .toggle-label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:500}.i18n-toggle-row .toggle-hint{font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);line-height:1.3}.toggle-switch{position:relative;display:inline-flex;align-items:center;width:34px;height:18px;flex-shrink:0;cursor:pointer}.toggle-switch input{opacity:0;width:0;height:0;position:absolute}.toggle-switch input:focus-visible+.toggle-track{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.toggle-switch .toggle-track{position:absolute;inset:0;background:var(--ndt-border-primary);border-radius:9px;transition:background .2s ease}.toggle-switch .toggle-track:after{content:\"\";position:absolute;top:2px;left:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .2s cubic-bezier(.4,0,.2,1);box-shadow:0 1px 2px #0000001f}.toggle-switch input:checked+.toggle-track{background:var(--ndt-primary)}.toggle-switch input:checked+.toggle-track:after{transform:translate(16px)}.i18n-pseudo-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-small);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);margin:0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);font-family:JetBrains Mono,ui-monospace,monospace;word-break:break-word;line-height:1.5}\n"], dependencies: [{ kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5122
5820
  }
5123
5821
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarI18nToolComponent, decorators: [{
5124
5822
  type: Component,
5125
5823
  args: [{ selector: 'ndt-i18n-tool', standalone: true, imports: [ToolbarToolComponent, ToolbarSelectComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
5126
5824
  <ndt-toolbar-tool toolTitle="i18n" icon="globe" [options]="options">
5127
5825
  <div class="i18n-section">
5128
- <!-- Formatting Preview (at top for immediate feedback) -->
5826
+ <!-- Formatting Preview (immediate feedback, always visible) -->
5129
5827
  @if (toolConfig().showFormattingPreview !== false) {
5130
- <div class="i18n-section-header">FORMATTING PREVIEW</div>
5131
- <div class="i18n-preview">
5828
+ <div class="i18n-preview" aria-label="Formatting preview">
5132
5829
  <div class="i18n-preview-row">
5133
5830
  <span class="preview-label">Number</span>
5134
5831
  <span class="preview-value">{{ previewNumber() }}</span>
@@ -5148,7 +5845,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
5148
5845
  </div>
5149
5846
  }
5150
5847
 
5151
- <!-- Settings (flat 2-column grid) -->
5848
+ <!-- Core settings: locale, timezone, currency -->
5152
5849
  <div class="i18n-select-grid">
5153
5850
  @if (toolConfig().showLocale !== false) {
5154
5851
  <div class="i18n-select-group">
@@ -5186,98 +5883,109 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
5186
5883
  />
5187
5884
  </div>
5188
5885
  }
5189
- @if (toolConfig().showUnits !== false) {
5190
- <div class="i18n-select-group">
5191
- <label for="i18n-units">Units</label>
5192
- <ndt-select
5193
- id="i18n-units"
5194
- [value]="activeUnitSystem()"
5195
- [options]="unitSystemOptions"
5196
- [size]="'medium'"
5197
- (valueChange)="onUnitSystemChange($event ?? '')"
5198
- />
5199
- </div>
5200
- }
5201
- @if (toolConfig().showDateFormat !== false) {
5202
- <div class="i18n-select-group">
5203
- <label for="i18n-date-format">Date Format</label>
5204
- <ndt-select
5205
- id="i18n-date-format"
5206
- [value]="activeDateFormat()"
5207
- [options]="dateFormatOptions"
5208
- [size]="'medium'"
5209
- (valueChange)="onDateFormatChange($event ?? '')"
5210
- />
5211
- </div>
5212
- }
5213
- @if (toolConfig().showNumberFormat !== false) {
5214
- <div class="i18n-select-group">
5215
- <label for="i18n-number-format">Number Format</label>
5216
- <ndt-select
5217
- id="i18n-number-format"
5218
- [value]="activeNumberFormat()"
5219
- [options]="numberFormatOptions"
5220
- [size]="'medium'"
5221
- (valueChange)="onNumberFormatChange($event ?? '')"
5222
- />
5223
- </div>
5224
- }
5225
- @if (toolConfig().showFirstDayOfWeek !== false) {
5226
- <div class="i18n-select-group">
5227
- <label for="i18n-first-day">First Day of Week</label>
5228
- <ndt-select
5229
- id="i18n-first-day"
5230
- [value]="activeFirstDayOfWeek()"
5231
- [options]="firstDayOptions"
5232
- [size]="'medium'"
5233
- (valueChange)="onFirstDayOfWeekChange($event ?? '')"
5234
- />
5235
- </div>
5236
- }
5237
5886
  </div>
5238
5887
 
5239
- <!-- Stress Testing -->
5240
- @if (toolConfig().showStressTesting !== false) {
5241
- <div class="i18n-section-header">STRESS TESTING</div>
5242
- <div class="i18n-toggle-section">
5243
- <div class="i18n-toggle-row">
5244
- <div class="toggle-info">
5245
- <span class="toggle-label">Pseudo-Localization</span>
5246
- <span class="toggle-hint">Detect hardcoded strings</span>
5247
- </div>
5248
- <label class="toggle-switch">
5249
- <input
5250
- type="checkbox"
5251
- [checked]="pseudoLocEnabled()"
5252
- (change)="onPseudoLocToggle($event)"
5253
- />
5254
- <span class="toggle-track"></span>
5255
- </label>
5888
+ <!-- Advanced format options (progressive disclosure) -->
5889
+ @if (hasAdvancedFormatSettings()) {
5890
+ <details class="i18n-disclosure">
5891
+ <summary>Advanced format options</summary>
5892
+ <div class="i18n-select-grid">
5893
+ @if (toolConfig().showUnits !== false) {
5894
+ <div class="i18n-select-group">
5895
+ <label for="i18n-units">Units</label>
5896
+ <ndt-select
5897
+ id="i18n-units"
5898
+ [value]="activeUnitSystem()"
5899
+ [options]="unitSystemOptions"
5900
+ [size]="'medium'"
5901
+ (valueChange)="onUnitSystemChange($event ?? '')"
5902
+ />
5903
+ </div>
5904
+ }
5905
+ @if (toolConfig().showDateFormat !== false) {
5906
+ <div class="i18n-select-group">
5907
+ <label for="i18n-date-format">Date Format</label>
5908
+ <ndt-select
5909
+ id="i18n-date-format"
5910
+ [value]="activeDateFormat()"
5911
+ [options]="dateFormatOptions"
5912
+ [size]="'medium'"
5913
+ (valueChange)="onDateFormatChange($event ?? '')"
5914
+ />
5915
+ </div>
5916
+ }
5917
+ @if (toolConfig().showNumberFormat !== false) {
5918
+ <div class="i18n-select-group">
5919
+ <label for="i18n-number-format">Number Format</label>
5920
+ <ndt-select
5921
+ id="i18n-number-format"
5922
+ [value]="activeNumberFormat()"
5923
+ [options]="numberFormatOptions"
5924
+ [size]="'medium'"
5925
+ (valueChange)="onNumberFormatChange($event ?? '')"
5926
+ />
5927
+ </div>
5928
+ }
5929
+ @if (toolConfig().showFirstDayOfWeek !== false) {
5930
+ <div class="i18n-select-group">
5931
+ <label for="i18n-first-day">First Day of Week</label>
5932
+ <ndt-select
5933
+ id="i18n-first-day"
5934
+ [value]="activeFirstDayOfWeek()"
5935
+ [options]="firstDayOptions"
5936
+ [size]="'medium'"
5937
+ (valueChange)="onFirstDayOfWeekChange($event ?? '')"
5938
+ />
5939
+ </div>
5940
+ }
5256
5941
  </div>
5257
- @if (pseudoLocEnabled()) {
5258
- <div class="i18n-pseudo-preview">
5259
- {{ pseudoPreview() }}
5942
+ </details>
5943
+ }
5944
+
5945
+ <!-- Stress Testing (separate collapsible section) -->
5946
+ @if (toolConfig().showStressTesting !== false) {
5947
+ <details class="i18n-disclosure">
5948
+ <summary>Stress testing</summary>
5949
+ <div class="i18n-toggle-section">
5950
+ <div class="i18n-toggle-row">
5951
+ <div class="toggle-info">
5952
+ <span class="toggle-label">Pseudo-Localization</span>
5953
+ <span class="toggle-hint">Detect hardcoded strings</span>
5954
+ </div>
5955
+ <label class="toggle-switch">
5956
+ <input
5957
+ type="checkbox"
5958
+ [checked]="pseudoLocEnabled()"
5959
+ (change)="onPseudoLocToggle($event)"
5960
+ />
5961
+ <span class="toggle-track"></span>
5962
+ </label>
5260
5963
  </div>
5261
- }
5262
- <div class="i18n-toggle-row">
5263
- <div class="toggle-info">
5264
- <span class="toggle-label">RTL Mirroring</span>
5265
- <span class="toggle-hint">Set document direction to RTL</span>
5964
+ @if (pseudoLocEnabled()) {
5965
+ <div class="i18n-pseudo-preview">
5966
+ {{ pseudoPreview() }}
5967
+ </div>
5968
+ }
5969
+ <div class="i18n-toggle-row">
5970
+ <div class="toggle-info">
5971
+ <span class="toggle-label">RTL Mirroring</span>
5972
+ <span class="toggle-hint">Set document direction to RTL</span>
5973
+ </div>
5974
+ <label class="toggle-switch">
5975
+ <input
5976
+ type="checkbox"
5977
+ [checked]="rtlEnabled()"
5978
+ (change)="onRtlToggle($event)"
5979
+ />
5980
+ <span class="toggle-track"></span>
5981
+ </label>
5266
5982
  </div>
5267
- <label class="toggle-switch">
5268
- <input
5269
- type="checkbox"
5270
- [checked]="rtlEnabled()"
5271
- (change)="onRtlToggle($event)"
5272
- />
5273
- <span class="toggle-track"></span>
5274
- </label>
5275
5983
  </div>
5276
- </div>
5984
+ </details>
5277
5985
  }
5278
5986
  </div>
5279
5987
  </ndt-toolbar-tool>
5280
- `, styles: [":host{display:block}.i18n-section{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);padding-top:0}.i18n-section-header{font-size:var(--ndt-font-size-xxs);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ndt-text-muted);margin-top:var(--ndt-spacing-md);padding:var(--ndt-spacing-xs) 0 var(--ndt-spacing-xs) var(--ndt-spacing-sm);border-left:2px solid rgba(var(--ndt-primary-rgb),.4)}.i18n-section-header:first-child{margin-top:0}.i18n-select-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--ndt-spacing-sm) var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-xs)}.i18n-select-group{display:flex;flex-direction:column;gap:2px}.i18n-select-group label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:600}.i18n-standalone-select{margin-top:var(--ndt-spacing-sm)}.i18n-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);border-left:2px solid var(--ndt-border-primary);padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);margin-top:var(--ndt-spacing-xs);display:flex;flex-direction:column;gap:1px}.i18n-preview-row{display:flex;justify-content:space-between;align-items:center;font-size:var(--ndt-font-size-xxs);gap:var(--ndt-spacing-xs);padding:2px 0}.i18n-preview-row .preview-label{color:var(--ndt-text-muted);flex-shrink:0}.i18n-preview-row .preview-value{font-family:JetBrains Mono,ui-monospace,monospace;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-primary);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.i18n-toggle-section{display:flex;flex-direction:column;gap:0;margin-top:var(--ndt-spacing-xs)}.i18n-toggle-row{display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);gap:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);transition:background .15s ease}.i18n-toggle-row:hover{background:var(--ndt-hover-bg)}.i18n-toggle-row .toggle-info{display:flex;flex-direction:column;gap:1px;min-width:0}.i18n-toggle-row .toggle-label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:500}.i18n-toggle-row .toggle-hint{font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);line-height:1.3}.toggle-switch{position:relative;display:inline-flex;align-items:center;width:34px;height:18px;flex-shrink:0;cursor:pointer}.toggle-switch input{opacity:0;width:0;height:0;position:absolute}.toggle-switch input:focus-visible+.toggle-track{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.toggle-switch .toggle-track{position:absolute;inset:0;background:var(--ndt-border-primary);border-radius:9px;transition:background .2s ease}.toggle-switch .toggle-track:after{content:\"\";position:absolute;top:2px;left:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .2s cubic-bezier(.4,0,.2,1);box-shadow:0 1px 2px #0000001f}.toggle-switch input:checked+.toggle-track{background:var(--ndt-primary)}.toggle-switch input:checked+.toggle-track:after{transform:translate(16px)}.i18n-pseudo-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-small);border-left:2px solid rgba(var(--ndt-primary-rgb),.3);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);margin:0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);font-family:JetBrains Mono,ui-monospace,monospace;word-break:break-word;line-height:1.5}\n"] }]
5988
+ `, styles: [":host{display:block}.i18n-section{display:flex;flex-direction:column;gap:var(--ndt-spacing-sm);padding-top:0}.i18n-select-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--ndt-spacing-sm)}.i18n-disclosure{margin:0}.i18n-disclosure summary{font-size:var(--ndt-font-size-xs);font-weight:500;color:var(--ndt-text-secondary);padding:var(--ndt-spacing-xs) 0;cursor:pointer;list-style:none;display:flex;align-items:center;gap:var(--ndt-spacing-xs);-webkit-user-select:none;user-select:none;border-radius:var(--ndt-border-radius-small)}.i18n-disclosure summary::-webkit-details-marker{display:none}.i18n-disclosure summary:before{content:\"\";display:inline-block;width:0;height:0;border-left:4px solid var(--ndt-text-muted);border-top:3px solid transparent;border-bottom:3px solid transparent;transition:transform .15s ease}.i18n-disclosure summary:hover{color:var(--ndt-text-primary)}.i18n-disclosure summary:focus-visible{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.i18n-disclosure[open] summary:before{transform:rotate(90deg)}.i18n-disclosure>:not(summary){margin-top:var(--ndt-spacing-sm)}.i18n-select-group{display:flex;flex-direction:column;gap:2px}.i18n-select-group label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:600}.i18n-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);display:flex;flex-direction:column;gap:1px}.i18n-preview-row{display:flex;justify-content:space-between;align-items:center;font-size:var(--ndt-font-size-xxs);gap:var(--ndt-spacing-xs);padding:2px 0}.i18n-preview-row .preview-label{color:var(--ndt-text-muted);flex-shrink:0}.i18n-preview-row .preview-value{font-family:JetBrains Mono,ui-monospace,monospace;font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-primary);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.i18n-toggle-section{display:flex;flex-direction:column;gap:0}.i18n-toggle-row{display:flex;align-items:center;justify-content:space-between;padding:var(--ndt-spacing-xs) var(--ndt-spacing-sm);gap:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);transition:background .15s ease}.i18n-toggle-row:hover{background:var(--ndt-hover-bg)}.i18n-toggle-row .toggle-info{display:flex;flex-direction:column;gap:1px;min-width:0}.i18n-toggle-row .toggle-label{font-size:var(--ndt-font-size-xs);color:var(--ndt-text-secondary);font-weight:500}.i18n-toggle-row .toggle-hint{font-size:var(--ndt-font-size-xxs);color:var(--ndt-text-muted);line-height:1.3}.toggle-switch{position:relative;display:inline-flex;align-items:center;width:34px;height:18px;flex-shrink:0;cursor:pointer}.toggle-switch input{opacity:0;width:0;height:0;position:absolute}.toggle-switch input:focus-visible+.toggle-track{outline:2px solid rgba(var(--ndt-primary-rgb),.5);outline-offset:2px}.toggle-switch .toggle-track{position:absolute;inset:0;background:var(--ndt-border-primary);border-radius:9px;transition:background .2s ease}.toggle-switch .toggle-track:after{content:\"\";position:absolute;top:2px;left:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .2s cubic-bezier(.4,0,.2,1);box-shadow:0 1px 2px #0000001f}.toggle-switch input:checked+.toggle-track{background:var(--ndt-primary)}.toggle-switch input:checked+.toggle-track:after{transform:translate(16px)}.i18n-pseudo-preview{background:var(--ndt-hover-bg);border-radius:var(--ndt-border-radius-small);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);margin:0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-xs);color:var(--ndt-text-muted);font-family:JetBrains Mono,ui-monospace,monospace;word-break:break-word;line-height:1.5}\n"] }]
5281
5989
  }], ctorParameters: () => [] });
5282
5990
 
5283
5991
  class ToolbarInternalPermissionsService {
@@ -5456,6 +6164,7 @@ class ToolbarPermissionsToolComponent {
5456
6164
  this.activeFilter = signal('all');
5457
6165
  this.searchQuery = signal('');
5458
6166
  this.pinnedIds = signal(new Set());
6167
+ this.collapsedGroups = signal(new Set());
5459
6168
  this.permissions = this.permissionsService.permissions;
5460
6169
  // Computed badge count for forced values
5461
6170
  this.badgeCount = computed(() => {
@@ -5468,7 +6177,7 @@ class ToolbarPermissionsToolComponent {
5468
6177
  });
5469
6178
  this.hasNoPermissions = computed(() => this.permissions().length === 0);
5470
6179
  this.filteredPermissions = computed(() => {
5471
- const filtered = this.permissions().filter((permission) => {
6180
+ return this.permissions().filter((permission) => {
5472
6181
  const searchTerm = this.searchQuery().toLowerCase();
5473
6182
  const permissionName = permission.name.toLowerCase();
5474
6183
  const permissionDescription = permission.description?.toLowerCase() ?? '';
@@ -5481,16 +6190,13 @@ class ToolbarPermissionsToolComponent {
5481
6190
  (this.activeFilter() === 'denied' && !permission.isGranted);
5482
6191
  return matchesSearch && matchesFilter;
5483
6192
  });
5484
- const pinned = this.pinnedIds();
5485
- // Sort pinned first, then alphabetically within each group
5486
- return filtered.sort((a, b) => {
5487
- const aPinned = pinned.has(a.id);
5488
- const bPinned = pinned.has(b.id);
5489
- if (aPinned !== bPinned)
5490
- return aPinned ? -1 : 1;
5491
- return a.name.localeCompare(b.name);
5492
- });
5493
6193
  });
6194
+ this.groupedPermissions = computed(() => groupItems(this.filteredPermissions(), this.pinnedIds()));
6195
+ this.flatPermissions = computed(() => {
6196
+ const { pinned, ungrouped } = this.groupedPermissions();
6197
+ return [...pinned, ...ungrouped];
6198
+ });
6199
+ this.hasAnyGroups = computed(() => this.groupedPermissions().groups.length > 0);
5494
6200
  this.hasNoFilteredPermissions = computed(() => this.filteredPermissions().length === 0);
5495
6201
  // Other properties
5496
6202
  this.options = {
@@ -5501,7 +6207,6 @@ class ToolbarPermissionsToolComponent {
5501
6207
  id: 'ndt-permissions',
5502
6208
  };
5503
6209
  this.filterOptions = [
5504
- { value: 'all', label: 'All Permissions' },
5505
6210
  { value: 'forced', label: 'Forced' },
5506
6211
  { value: 'granted', label: 'Granted' },
5507
6212
  { value: 'denied', label: 'Denied' },
@@ -5521,6 +6226,7 @@ class ToolbarPermissionsToolComponent {
5521
6226
  filter: this.activeFilter(),
5522
6227
  sortOrder: 'asc',
5523
6228
  pinnedIds: [...this.pinnedIds()],
6229
+ collapsedGroups: [...this.collapsedGroups()],
5524
6230
  };
5525
6231
  this.storageService.set(this.VIEW_STATE_KEY, state);
5526
6232
  });
@@ -5537,6 +6243,9 @@ class ToolbarPermissionsToolComponent {
5537
6243
  if (saved.pinnedIds?.length) {
5538
6244
  this.pinnedIds.set(new Set(saved.pinnedIds));
5539
6245
  }
6246
+ if (saved.collapsedGroups?.length) {
6247
+ this.collapsedGroups.set(new Set(saved.collapsedGroups));
6248
+ }
5540
6249
  }
5541
6250
  }
5542
6251
  catch {
@@ -5584,6 +6293,21 @@ class ToolbarPermissionsToolComponent {
5584
6293
  return next;
5585
6294
  });
5586
6295
  }
6296
+ isCollapsed(name) {
6297
+ return this.collapsedGroups().has(name);
6298
+ }
6299
+ setCollapsed(name, collapsed) {
6300
+ this.collapsedGroups.update((set) => {
6301
+ const next = new Set(set);
6302
+ if (collapsed) {
6303
+ next.add(name);
6304
+ }
6305
+ else {
6306
+ next.delete(name);
6307
+ }
6308
+ return next;
6309
+ });
6310
+ }
5587
6311
  // Protected methods
5588
6312
  getPermissionValue(permission) {
5589
6313
  if (!permission.isForced)
@@ -5599,23 +6323,15 @@ class ToolbarPermissionsToolComponent {
5599
6323
  [badge]="badgeCount()"
5600
6324
  >
5601
6325
  <div class="container">
5602
- <div class="tool-header">
5603
- <ndt-input
5604
- [value]="searchQuery()"
5605
- (valueChange)="onSearchChange($event)"
5606
- placeholder="Search permissions..."
5607
- [ariaLabel]="'Search permissions'"
5608
- />
5609
- <div class="filter-wrapper">
5610
- <ndt-select
5611
- [value]="activeFilter()"
5612
- [options]="filterOptions"
5613
- [size]="'medium'"
5614
- (valueChange)="onFilterChange($event)"
5615
- [ariaLabel]="'Filter permissions by state'"
5616
- />
5617
- </div>
5618
- </div>
6326
+ <ndt-tool-header
6327
+ [(searchQuery)]="searchQuery"
6328
+ [activeFilter]="activeFilter()"
6329
+ (activeFilterChange)="onFilterChange($event)"
6330
+ searchPlaceholder="Search permissions by name or description"
6331
+ searchAriaLabel="Search permissions"
6332
+ filterAriaLabel="Filter permissions by state"
6333
+ [filterOptions]="filterOptions"
6334
+ />
5619
6335
 
5620
6336
  <ndt-list
5621
6337
  [hasItems]="!hasNoPermissions()"
@@ -5624,41 +6340,115 @@ class ToolbarPermissionsToolComponent {
5624
6340
  [emptyHint]="'Call setAvailableOptions() to configure permissions'"
5625
6341
  noResultsMessage="No permissions match your filter"
5626
6342
  >
5627
- @for (permission of filteredPermissions(); track permission.id) {
5628
- <ndt-list-item
5629
- [title]="permission.name"
5630
- [description]="permission.description"
5631
- [isForced]="permission.isForced"
5632
- [currentValue]="permission.isGranted"
5633
- [originalValue]="permission.originalValue"
5634
- [isPinned]="pinnedIds().has(permission.id)"
5635
- (pinToggle)="togglePin(permission.id)"
5636
- [showApply]="hasApplyCallback()"
5637
- [applyState]="getApplyState(permission.id)"
5638
- (applyToSource)="onApplyToSource(permission.id, permission.isGranted)"
5639
- >
5640
- <ndt-select
5641
- [value]="getPermissionValue(permission)"
5642
- [options]="permissionValueOptions"
5643
- [ariaLabel]="'Override state for ' + permission.name"
5644
- (valueChange)="onPermissionChange(permission.id, $event ?? '')"
5645
- size="small"
6343
+ @if (hasAnyGroups()) {
6344
+ @if (groupedPermissions().pinned.length) {
6345
+ <ndt-list-group
6346
+ name="Pinned"
6347
+ [count]="groupedPermissions().pinned.length"
6348
+ [collapsed]="isCollapsed('Pinned')"
6349
+ (collapsedChange)="setCollapsed('Pinned', $event)"
6350
+ >
6351
+ @for (
6352
+ permission of groupedPermissions().pinned;
6353
+ track permission.id
6354
+ ) {
6355
+ <ng-container
6356
+ *ngTemplateOutlet="
6357
+ permissionItem;
6358
+ context: { $implicit: permission }
6359
+ "
6360
+ />
6361
+ }
6362
+ </ndt-list-group>
6363
+ }
6364
+ @for (group of groupedPermissions().groups; track group.name) {
6365
+ <ndt-list-group
6366
+ [name]="group.name"
6367
+ [count]="group.items.length"
6368
+ [collapsed]="isCollapsed(group.name)"
6369
+ (collapsedChange)="setCollapsed(group.name, $event)"
6370
+ >
6371
+ @for (permission of group.items; track permission.id) {
6372
+ <ng-container
6373
+ *ngTemplateOutlet="
6374
+ permissionItem;
6375
+ context: { $implicit: permission }
6376
+ "
6377
+ />
6378
+ }
6379
+ </ndt-list-group>
6380
+ }
6381
+ @if (groupedPermissions().ungrouped.length) {
6382
+ <ndt-list-group
6383
+ name="Other"
6384
+ [count]="groupedPermissions().ungrouped.length"
6385
+ [collapsed]="isCollapsed('Other')"
6386
+ (collapsedChange)="setCollapsed('Other', $event)"
6387
+ >
6388
+ @for (
6389
+ permission of groupedPermissions().ungrouped;
6390
+ track permission.id
6391
+ ) {
6392
+ <ng-container
6393
+ *ngTemplateOutlet="
6394
+ permissionItem;
6395
+ context: { $implicit: permission }
6396
+ "
6397
+ />
6398
+ }
6399
+ </ndt-list-group>
6400
+ }
6401
+ } @else {
6402
+ @for (permission of flatPermissions(); track permission.id) {
6403
+ <ng-container
6404
+ *ngTemplateOutlet="
6405
+ permissionItem;
6406
+ context: { $implicit: permission }
6407
+ "
5646
6408
  />
5647
- </ndt-list-item>
6409
+ }
5648
6410
  }
5649
6411
  </ndt-list>
6412
+
6413
+ <ng-template #permissionItem let-permission>
6414
+ <ndt-list-item
6415
+ [title]="permission.name"
6416
+ [description]="permission.description"
6417
+ [isForced]="permission.isForced"
6418
+ [currentValue]="permission.isGranted"
6419
+ [originalValue]="permission.originalValue"
6420
+ [isPinned]="pinnedIds().has(permission.id)"
6421
+ [copyableId]="permission.id"
6422
+ (pinToggle)="togglePin(permission.id)"
6423
+ [showApply]="hasApplyCallback()"
6424
+ [applyState]="getApplyState(permission.id)"
6425
+ (applyToSource)="
6426
+ onApplyToSource(permission.id, permission.isGranted)
6427
+ "
6428
+ >
6429
+ <ndt-select
6430
+ [value]="getPermissionValue(permission)"
6431
+ [options]="permissionValueOptions"
6432
+ [ariaLabel]="'Override state for ' + permission.name"
6433
+ (valueChange)="onPermissionChange(permission.id, $event ?? '')"
6434
+ size="small"
6435
+ />
6436
+ </ndt-list-item>
6437
+ </ng-template>
5650
6438
  </div>
5651
6439
  </ndt-toolbar-tool>
5652
- `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);ndt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;border-left:1px solid var(--ndt-border-primary);padding-left:var(--ndt-spacing-sm);ndt-select{flex:0 0 auto;min-width:140px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ndt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarListComponent, selector: "ndt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ndt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue", "showApply", "applyState", "isPinned"], outputs: ["pinToggle", "applyToSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6440
+ `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarToolHeaderComponent, selector: "ndt-tool-header", inputs: ["searchQuery", "activeFilter", "searchPlaceholder", "searchAriaLabel", "filterOptions", "filterAriaLabel", "defaultFilter"], outputs: ["searchQueryChange", "activeFilterChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ndt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarListComponent, selector: "ndt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListGroupComponent, selector: "ndt-list-group", inputs: ["name", "count", "collapsed"], outputs: ["collapsedChange"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ndt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue", "showApply", "applyState", "isPinned", "copyableId"], outputs: ["pinToggle", "applyToSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5653
6441
  }
5654
6442
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarPermissionsToolComponent, decorators: [{
5655
6443
  type: Component,
5656
6444
  args: [{ selector: 'ndt-permissions-tool', standalone: true, imports: [
6445
+ NgTemplateOutlet,
5657
6446
  FormsModule,
5658
6447
  ToolbarToolComponent,
5659
- ToolbarInputComponent,
6448
+ ToolbarToolHeaderComponent,
5660
6449
  ToolbarSelectComponent,
5661
6450
  ToolbarListComponent,
6451
+ ToolbarListGroupComponent,
5662
6452
  ToolbarListItemComponent,
5663
6453
  ], template: `
5664
6454
  <ndt-toolbar-tool
@@ -5668,23 +6458,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
5668
6458
  [badge]="badgeCount()"
5669
6459
  >
5670
6460
  <div class="container">
5671
- <div class="tool-header">
5672
- <ndt-input
5673
- [value]="searchQuery()"
5674
- (valueChange)="onSearchChange($event)"
5675
- placeholder="Search permissions..."
5676
- [ariaLabel]="'Search permissions'"
5677
- />
5678
- <div class="filter-wrapper">
5679
- <ndt-select
5680
- [value]="activeFilter()"
5681
- [options]="filterOptions"
5682
- [size]="'medium'"
5683
- (valueChange)="onFilterChange($event)"
5684
- [ariaLabel]="'Filter permissions by state'"
5685
- />
5686
- </div>
5687
- </div>
6461
+ <ndt-tool-header
6462
+ [(searchQuery)]="searchQuery"
6463
+ [activeFilter]="activeFilter()"
6464
+ (activeFilterChange)="onFilterChange($event)"
6465
+ searchPlaceholder="Search permissions by name or description"
6466
+ searchAriaLabel="Search permissions"
6467
+ filterAriaLabel="Filter permissions by state"
6468
+ [filterOptions]="filterOptions"
6469
+ />
5688
6470
 
5689
6471
  <ndt-list
5690
6472
  [hasItems]="!hasNoPermissions()"
@@ -5693,32 +6475,104 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
5693
6475
  [emptyHint]="'Call setAvailableOptions() to configure permissions'"
5694
6476
  noResultsMessage="No permissions match your filter"
5695
6477
  >
5696
- @for (permission of filteredPermissions(); track permission.id) {
5697
- <ndt-list-item
5698
- [title]="permission.name"
5699
- [description]="permission.description"
5700
- [isForced]="permission.isForced"
5701
- [currentValue]="permission.isGranted"
5702
- [originalValue]="permission.originalValue"
5703
- [isPinned]="pinnedIds().has(permission.id)"
5704
- (pinToggle)="togglePin(permission.id)"
5705
- [showApply]="hasApplyCallback()"
5706
- [applyState]="getApplyState(permission.id)"
5707
- (applyToSource)="onApplyToSource(permission.id, permission.isGranted)"
5708
- >
5709
- <ndt-select
5710
- [value]="getPermissionValue(permission)"
5711
- [options]="permissionValueOptions"
5712
- [ariaLabel]="'Override state for ' + permission.name"
5713
- (valueChange)="onPermissionChange(permission.id, $event ?? '')"
5714
- size="small"
6478
+ @if (hasAnyGroups()) {
6479
+ @if (groupedPermissions().pinned.length) {
6480
+ <ndt-list-group
6481
+ name="Pinned"
6482
+ [count]="groupedPermissions().pinned.length"
6483
+ [collapsed]="isCollapsed('Pinned')"
6484
+ (collapsedChange)="setCollapsed('Pinned', $event)"
6485
+ >
6486
+ @for (
6487
+ permission of groupedPermissions().pinned;
6488
+ track permission.id
6489
+ ) {
6490
+ <ng-container
6491
+ *ngTemplateOutlet="
6492
+ permissionItem;
6493
+ context: { $implicit: permission }
6494
+ "
6495
+ />
6496
+ }
6497
+ </ndt-list-group>
6498
+ }
6499
+ @for (group of groupedPermissions().groups; track group.name) {
6500
+ <ndt-list-group
6501
+ [name]="group.name"
6502
+ [count]="group.items.length"
6503
+ [collapsed]="isCollapsed(group.name)"
6504
+ (collapsedChange)="setCollapsed(group.name, $event)"
6505
+ >
6506
+ @for (permission of group.items; track permission.id) {
6507
+ <ng-container
6508
+ *ngTemplateOutlet="
6509
+ permissionItem;
6510
+ context: { $implicit: permission }
6511
+ "
6512
+ />
6513
+ }
6514
+ </ndt-list-group>
6515
+ }
6516
+ @if (groupedPermissions().ungrouped.length) {
6517
+ <ndt-list-group
6518
+ name="Other"
6519
+ [count]="groupedPermissions().ungrouped.length"
6520
+ [collapsed]="isCollapsed('Other')"
6521
+ (collapsedChange)="setCollapsed('Other', $event)"
6522
+ >
6523
+ @for (
6524
+ permission of groupedPermissions().ungrouped;
6525
+ track permission.id
6526
+ ) {
6527
+ <ng-container
6528
+ *ngTemplateOutlet="
6529
+ permissionItem;
6530
+ context: { $implicit: permission }
6531
+ "
6532
+ />
6533
+ }
6534
+ </ndt-list-group>
6535
+ }
6536
+ } @else {
6537
+ @for (permission of flatPermissions(); track permission.id) {
6538
+ <ng-container
6539
+ *ngTemplateOutlet="
6540
+ permissionItem;
6541
+ context: { $implicit: permission }
6542
+ "
5715
6543
  />
5716
- </ndt-list-item>
6544
+ }
5717
6545
  }
5718
6546
  </ndt-list>
6547
+
6548
+ <ng-template #permissionItem let-permission>
6549
+ <ndt-list-item
6550
+ [title]="permission.name"
6551
+ [description]="permission.description"
6552
+ [isForced]="permission.isForced"
6553
+ [currentValue]="permission.isGranted"
6554
+ [originalValue]="permission.originalValue"
6555
+ [isPinned]="pinnedIds().has(permission.id)"
6556
+ [copyableId]="permission.id"
6557
+ (pinToggle)="togglePin(permission.id)"
6558
+ [showApply]="hasApplyCallback()"
6559
+ [applyState]="getApplyState(permission.id)"
6560
+ (applyToSource)="
6561
+ onApplyToSource(permission.id, permission.isGranted)
6562
+ "
6563
+ >
6564
+ <ndt-select
6565
+ [value]="getPermissionValue(permission)"
6566
+ [options]="permissionValueOptions"
6567
+ [ariaLabel]="'Override state for ' + permission.name"
6568
+ (valueChange)="onPermissionChange(permission.id, $event ?? '')"
6569
+ size="small"
6570
+ />
6571
+ </ndt-list-item>
6572
+ </ng-template>
5719
6573
  </div>
5720
6574
  </ndt-toolbar-tool>
5721
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);ndt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;border-left:1px solid var(--ndt-border-primary);padding-left:var(--ndt-spacing-sm);ndt-select{flex:0 0 auto;min-width:140px}}}\n"] }]
6575
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}\n"] }]
5722
6576
  }], ctorParameters: () => [] });
5723
6577
 
5724
6578
  /**
@@ -6954,7 +7808,7 @@ class ToolbarPresetsToolComponent {
6954
7808
  }
6955
7809
  </div>
6956
7810
  </ndt-toolbar-tool>
6957
- `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.toast{position:absolute;bottom:var(--ndt-spacing-md);left:var(--ndt-spacing-md);right:var(--ndt-spacing-md);z-index:10;display:flex;align-items:center;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-sm);animation:slideUp .15s ease-out}.toast--success{background:#22c55e;color:#fff}.toast--error{background:#ef4444;color:#fff}.toast__icon{font-weight:700}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.delete-view{flex:1;display:flex;flex-direction:column;justify-content:center;padding:var(--ndt-spacing-md)}.delete-view__content{text-align:center;padding:var(--ndt-spacing-lg) var(--ndt-spacing-md)}.delete-view__icon{font-size:48px;margin-bottom:var(--ndt-spacing-md)}.delete-view__title{margin:0 0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-md);color:var(--ndt-text-primary)}.delete-view__description{margin:0;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-secondary);line-height:1.5}.delete-button{background:#ef4444;color:#fff;border:none;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);cursor:pointer;font-size:var(--ndt-font-size-sm);font-weight:500;transition:background .2s ease-out;&:hover{background:#dc2626}}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-md);ndt-input{flex:1}ndt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ndt-border-subtle);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:transparent;color:var(--ndt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ndt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ndt-spacing-xs);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ndt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ndt-border-primary);border-radius:4px;&:hover{background:var(--ndt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.preset-card{background:var(--ndt-background-secondary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:2px;position:relative}.preset-card__header{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}.preset-card__row{display:flex;align-items:center;gap:6px;min-height:18px}.preset-card__row--meta{padding-left:36px}.preset-card__row--badges{padding-left:36px;gap:4px}.preset-card__name{font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__spacer{flex:1;min-width:8px}.system-badge{font-size:8px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 4px;border-radius:3px;background:var(--ndt-border-primary);color:var(--ndt-text-muted);flex-shrink:0}.favorite-button{background:transparent;border:none;cursor:pointer;font-size:12px;color:var(--ndt-text-muted);padding:0;line-height:1;transition:color .15s ease-out;flex-shrink:0}.favorite-button:hover,.favorite-button--active{color:#f59e0b}.preset-card__actions{display:flex;gap:2px;flex-shrink:0}.more-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:4px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;width:22px;height:22px;opacity:.5;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out;line-height:1;font-size:14px;font-weight:700;position:relative;&:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}}.action-menu{position:absolute;top:28px;right:var(--ndt-spacing-sm);background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:var(--ndt-shadow-tooltip);z-index:20;min-width:180px;padding:4px;display:flex;flex-direction:column;gap:2px}.action-menu__item{appearance:none;background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:background .15s ease-out;white-space:nowrap;&:hover{background:var(--ndt-hover-bg)}ndt-icon{display:block;width:14px;height:14px;flex-shrink:0;color:var(--ndt-text-muted)}}.action-menu__item--danger{color:#ef4444;ndt-icon{color:#ef4444}&:hover{background:#ef44441a}}.expand-toggle{appearance:none;background:none;border:none;cursor:pointer;padding:0 4px;margin-right:2px;font-size:10px;color:var(--ndt-text-muted);line-height:1;opacity:.6;transition:opacity .15s ease-out;flex-shrink:0;&:hover{opacity:1}}.preset-card__details{padding:var(--ndt-spacing-sm) var(--ndt-spacing-sm) var(--ndt-spacing-xs);margin-top:2px;border-top:1px solid var(--ndt-border-primary);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.details-section__title{font-size:10px;font-weight:600;color:var(--ndt-text-muted);text-transform:uppercase;letter-spacing:.5px}.details-section__items{display:flex;flex-wrap:wrap;gap:4px;margin-top:2px}.detail-badge{font-size:10px;padding:1px 6px;border-radius:var(--ndt-border-radius-small);white-space:nowrap}.detail-badge--on{background:#22c55e1a;color:#22c55e}.detail-badge--off{background:#ef44441a;color:#ef4444}.preset-card__description{font-size:11px;color:var(--ndt-text-secondary);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__date{font-size:10px;color:var(--ndt-text-muted);margin-left:auto;flex-shrink:0}.badge{background:#6366f126;color:#6366f1;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:500;white-space:nowrap}.badge--lang{background:#22c55e26;color:#22c55e}.preset-form,.import-view,.apply-view{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm);ndt-input{width:100%}}.form-title{margin:0;font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary)}.form-hint{margin:0;font-size:11px;color:var(--ndt-text-muted);line-height:1.3}.form-field{display:flex;flex-direction:column;gap:2px}.field-error{color:#ef4444;font-size:11px}.preset-summary{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.category-section{display:flex;flex-direction:column;gap:2px}.checkbox-option{display:flex;align-items:center;gap:var(--ndt-spacing-xs);cursor:pointer;color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);padding:2px 0;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241);border-radius:3px;&:disabled{cursor:not-allowed;opacity:.4}}&:has(input:disabled){opacity:.5;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 20px;display:flex;flex-direction:column;gap:2px;font-size:11px;max-height:100px;overflow-y:auto;li{background:#6366f10d;border-radius:3px;border-left:2px solid rgba(99,102,241,.3)}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:3px 6px;cursor:pointer;gap:6px;input[type=checkbox]{cursor:pointer;width:12px;height:12px;accent-color:rgb(99,102,241);flex-shrink:0}&:hover{background:#6366f114}}.item-name{color:var(--ndt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0;&.enabled{background:#22c55e26;color:#22c55e}&.disabled{background:#ef444426;color:#ef4444}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ndt-spacing-sm);margin-top:auto;padding-top:var(--ndt-spacing-sm)}.config-preview{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.config-category{display:flex;flex-direction:column;gap:2px}.config-category__title{font-size:10px;color:var(--ndt-text-muted);font-weight:500}.config-items{display:flex;flex-wrap:wrap;gap:4px}.config-item{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--ndt-background-primary);color:var(--ndt-text-secondary)}.config-item--on{background:#22c55e1a;color:#22c55e}.config-item--off{background:#ef44441a;color:#ef4444}.replace-config-button{background:transparent;border:1px dashed var(--ndt-border-primary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-secondary);cursor:pointer;font-size:11px;transition:all .15s ease-out;&:hover{background:var(--ndt-hover-bg);border-color:#6366f1;color:#6366f1}}.drop-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--ndt-spacing-md);border:2px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);cursor:pointer;transition:all .15s ease-out}.drop-zone:hover,.drop-zone--active{border-color:#6366f1;background:#6366f10d}.drop-zone__icon{font-size:24px}.drop-zone__text{font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary)}.drop-zone__hint{font-size:11px;color:var(--ndt-text-muted)}.divider{display:flex;align-items:center;gap:var(--ndt-spacing-sm);color:var(--ndt-text-muted);font-size:10px;&:before,&:after{content:\"\";flex:1;height:1px;background:var(--ndt-border-primary)}}.json-textarea{width:100%;min-height:80px;padding:var(--ndt-spacing-xs);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background:var(--ndt-background-secondary);color:var(--ndt-text-primary);font-family:monospace;font-size:11px;resize:vertical;&:focus{outline:none;border-color:#6366f1}&::placeholder{color:var(--ndt-text-muted)}}.apply-description{margin:0;font-size:11px;color:var(--ndt-text-secondary)}.apply-categories{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.apply-category{background:var(--ndt-background-secondary);border-radius:var(--ndt-border-radius-small);overflow:hidden;transition:opacity .15s ease-out}.apply-category--disabled{opacity:.5}.apply-category__header{display:flex;align-items:center;gap:var(--ndt-spacing-xs);padding:6px var(--ndt-spacing-sm);cursor:pointer;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary);font-weight:500;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241)}}.apply-diff{padding:0 var(--ndt-spacing-sm) 6px;display:flex;flex-direction:column;gap:2px}.diff-item{display:flex;align-items:center;gap:6px;font-size:11px;padding:3px 6px;background:var(--ndt-background-primary);border-radius:3px}.diff-item__name{flex:1;color:var(--ndt-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-item__arrow{color:var(--ndt-text-muted);font-size:10px}.diff-item__value{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px}.diff-item__value--on{background:#22c55e26;color:#22c55e}.diff-item__value--off{background:#ef444426;color:#ef4444}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ndt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarButtonComponent, selector: "ndt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }, { kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7811
+ `, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.toast{position:absolute;bottom:var(--ndt-spacing-md);left:var(--ndt-spacing-md);right:var(--ndt-spacing-md);z-index:10;display:flex;align-items:center;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-sm);animation:slideUp .15s ease-out}.toast--success{background:var(--ndt-success);color:#fff}.toast--error{background:var(--ndt-danger);color:#fff}.toast__icon{font-weight:700}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.delete-view{flex:1;display:flex;flex-direction:column;justify-content:center;padding:var(--ndt-spacing-md)}.delete-view__content{text-align:center;padding:var(--ndt-spacing-lg) var(--ndt-spacing-md)}.delete-view__icon{font-size:48px;margin-bottom:var(--ndt-spacing-md)}.delete-view__title{margin:0 0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-md);color:var(--ndt-text-primary)}.delete-view__description{margin:0;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-secondary);line-height:1.5}.delete-button{background:var(--ndt-danger);color:#fff;border:none;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);cursor:pointer;font-size:var(--ndt-font-size-sm);font-weight:500;transition:background .2s ease-out;&:hover{background:#dc2626}}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-md);ndt-input{flex:1}ndt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ndt-border-subtle);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:transparent;color:var(--ndt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ndt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ndt-spacing-xs);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ndt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ndt-border-primary);border-radius:4px;&:hover{background:var(--ndt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.preset-card{background:var(--ndt-background-secondary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:2px;position:relative}.preset-card__header{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}.preset-card__row{display:flex;align-items:center;gap:6px;min-height:18px}.preset-card__row--meta{padding-left:36px}.preset-card__row--badges{padding-left:36px;gap:4px}.preset-card__name{font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__spacer{flex:1;min-width:8px}.system-badge{font-size:8px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 4px;border-radius:3px;background:var(--ndt-border-primary);color:var(--ndt-text-muted);flex-shrink:0}.favorite-button{background:transparent;border:none;cursor:pointer;font-size:12px;color:var(--ndt-text-muted);padding:0;line-height:1;transition:color .15s ease-out;flex-shrink:0}.favorite-button:hover,.favorite-button--active{color:#f59e0b}.preset-card__actions{display:flex;gap:2px;flex-shrink:0}.more-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:4px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;width:22px;height:22px;opacity:.5;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out;line-height:1;font-size:14px;font-weight:700;position:relative;&:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}}.action-menu{position:absolute;top:28px;right:var(--ndt-spacing-sm);background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:var(--ndt-shadow-tooltip);z-index:20;min-width:180px;padding:4px;display:flex;flex-direction:column;gap:2px}.action-menu__item{appearance:none;background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:background .15s ease-out;white-space:nowrap;&:hover{background:var(--ndt-hover-bg)}ndt-icon{display:block;width:14px;height:14px;flex-shrink:0;color:var(--ndt-text-muted)}}.action-menu__item--danger{color:var(--ndt-danger);ndt-icon{color:var(--ndt-danger)}&:hover{background:rgba(var(--ndt-danger-rgb),.1)}}.expand-toggle{appearance:none;background:none;border:none;cursor:pointer;padding:0 4px;margin-right:2px;font-size:10px;color:var(--ndt-text-muted);line-height:1;opacity:.6;transition:opacity .15s ease-out;flex-shrink:0;&:hover{opacity:1}}.preset-card__details{padding:var(--ndt-spacing-sm) var(--ndt-spacing-sm) var(--ndt-spacing-xs);margin-top:2px;border-top:1px solid var(--ndt-border-primary);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.details-section__title{font-size:10px;font-weight:600;color:var(--ndt-text-muted);text-transform:uppercase;letter-spacing:.5px}.details-section__items{display:flex;flex-wrap:wrap;gap:4px;margin-top:2px}.detail-badge{font-size:10px;padding:1px 6px;border-radius:var(--ndt-border-radius-small);white-space:nowrap}.detail-badge--on{background:rgba(var(--ndt-success-rgb),.1);color:var(--ndt-success)}.detail-badge--off{background:rgba(var(--ndt-danger-rgb),.1);color:var(--ndt-danger)}.preset-card__description{font-size:11px;color:var(--ndt-text-secondary);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__date{font-size:10px;color:var(--ndt-text-muted);margin-left:auto;flex-shrink:0}.badge{background:#6366f126;color:#6366f1;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:500;white-space:nowrap}.badge--lang{background:rgba(var(--ndt-success-rgb),.15);color:var(--ndt-success)}.preset-form,.import-view,.apply-view{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm);ndt-input{width:100%}}.form-title{margin:0;font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary)}.form-hint{margin:0;font-size:11px;color:var(--ndt-text-muted);line-height:1.3}.form-field{display:flex;flex-direction:column;gap:2px}.field-error{color:var(--ndt-danger);font-size:11px}.preset-summary{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.category-section{display:flex;flex-direction:column;gap:2px}.checkbox-option{display:flex;align-items:center;gap:var(--ndt-spacing-xs);cursor:pointer;color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);padding:2px 0;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241);border-radius:3px;&:disabled{cursor:not-allowed;opacity:.4}}&:has(input:disabled){opacity:.5;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 20px;display:flex;flex-direction:column;gap:2px;font-size:11px;max-height:100px;overflow-y:auto;li{background:rgba(var(--ndt-primary-rgb),.05);border-radius:3px;padding-left:6px}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:3px 6px;cursor:pointer;gap:6px;input[type=checkbox]{cursor:pointer;width:12px;height:12px;accent-color:rgb(99,102,241);flex-shrink:0}&:hover{background:#6366f114}}.item-name{color:var(--ndt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0;&.enabled{background:rgba(var(--ndt-success-rgb),.15);color:var(--ndt-success)}&.disabled{background:rgba(var(--ndt-danger-rgb),.15);color:var(--ndt-danger)}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ndt-spacing-sm);margin-top:auto;padding-top:var(--ndt-spacing-sm)}.config-preview{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.config-category{display:flex;flex-direction:column;gap:2px}.config-category__title{font-size:10px;color:var(--ndt-text-muted);font-weight:500}.config-items{display:flex;flex-wrap:wrap;gap:4px}.config-item{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--ndt-background-primary);color:var(--ndt-text-secondary)}.config-item--on{background:rgba(var(--ndt-success-rgb),.1);color:var(--ndt-success)}.config-item--off{background:rgba(var(--ndt-danger-rgb),.1);color:var(--ndt-danger)}.replace-config-button{background:transparent;border:1px dashed var(--ndt-border-primary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-secondary);cursor:pointer;font-size:11px;transition:all .15s ease-out;&:hover{background:var(--ndt-hover-bg);border-color:#6366f1;color:#6366f1}}.drop-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--ndt-spacing-md);border:2px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);cursor:pointer;transition:all .15s ease-out}.drop-zone:hover,.drop-zone--active{border-color:#6366f1;background:#6366f10d}.drop-zone__icon{font-size:24px}.drop-zone__text{font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary)}.drop-zone__hint{font-size:11px;color:var(--ndt-text-muted)}.divider{display:flex;align-items:center;gap:var(--ndt-spacing-sm);color:var(--ndt-text-muted);font-size:10px;&:before,&:after{content:\"\";flex:1;height:1px;background:var(--ndt-border-primary)}}.json-textarea{width:100%;min-height:80px;padding:var(--ndt-spacing-xs);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background:var(--ndt-background-secondary);color:var(--ndt-text-primary);font-family:monospace;font-size:11px;resize:vertical;&:focus{outline:none;border-color:#6366f1}&::placeholder{color:var(--ndt-text-muted)}}.apply-description{margin:0;font-size:11px;color:var(--ndt-text-secondary)}.apply-categories{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.apply-category{background:var(--ndt-background-secondary);border-radius:var(--ndt-border-radius-small);overflow:hidden;transition:opacity .15s ease-out}.apply-category--disabled{opacity:.5}.apply-category__header{display:flex;align-items:center;gap:var(--ndt-spacing-xs);padding:6px var(--ndt-spacing-sm);cursor:pointer;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary);font-weight:500;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241)}}.apply-diff{padding:0 var(--ndt-spacing-sm) 6px;display:flex;flex-direction:column;gap:2px}.diff-item{display:flex;align-items:center;gap:6px;font-size:11px;padding:3px 6px;background:var(--ndt-background-primary);border-radius:3px}.diff-item__name{flex:1;color:var(--ndt-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-item__arrow{color:var(--ndt-text-muted);font-size:10px}.diff-item__value{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px}.diff-item__value--on{background:rgba(var(--ndt-success-rgb),.15);color:var(--ndt-success)}.diff-item__value--off{background:rgba(var(--ndt-danger-rgb),.15);color:var(--ndt-danger)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ToolbarToolComponent, selector: "ndt-toolbar-tool", inputs: ["options", "icon", "toolTitle", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ndt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarButtonComponent, selector: "ndt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }, { kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6958
7812
  }
6959
7813
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarPresetsToolComponent, decorators: [{
6960
7814
  type: Component,
@@ -7548,7 +8402,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
7548
8402
  }
7549
8403
  </div>
7550
8404
  </ndt-toolbar-tool>
7551
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.toast{position:absolute;bottom:var(--ndt-spacing-md);left:var(--ndt-spacing-md);right:var(--ndt-spacing-md);z-index:10;display:flex;align-items:center;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-sm);animation:slideUp .15s ease-out}.toast--success{background:#22c55e;color:#fff}.toast--error{background:#ef4444;color:#fff}.toast__icon{font-weight:700}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.delete-view{flex:1;display:flex;flex-direction:column;justify-content:center;padding:var(--ndt-spacing-md)}.delete-view__content{text-align:center;padding:var(--ndt-spacing-lg) var(--ndt-spacing-md)}.delete-view__icon{font-size:48px;margin-bottom:var(--ndt-spacing-md)}.delete-view__title{margin:0 0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-md);color:var(--ndt-text-primary)}.delete-view__description{margin:0;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-secondary);line-height:1.5}.delete-button{background:#ef4444;color:#fff;border:none;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);cursor:pointer;font-size:var(--ndt-font-size-sm);font-weight:500;transition:background .2s ease-out;&:hover{background:#dc2626}}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-md);ndt-input{flex:1}ndt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ndt-border-subtle);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:transparent;color:var(--ndt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ndt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ndt-spacing-xs);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ndt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ndt-border-primary);border-radius:4px;&:hover{background:var(--ndt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.preset-card{background:var(--ndt-background-secondary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:2px;position:relative}.preset-card__header{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}.preset-card__row{display:flex;align-items:center;gap:6px;min-height:18px}.preset-card__row--meta{padding-left:36px}.preset-card__row--badges{padding-left:36px;gap:4px}.preset-card__name{font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__spacer{flex:1;min-width:8px}.system-badge{font-size:8px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 4px;border-radius:3px;background:var(--ndt-border-primary);color:var(--ndt-text-muted);flex-shrink:0}.favorite-button{background:transparent;border:none;cursor:pointer;font-size:12px;color:var(--ndt-text-muted);padding:0;line-height:1;transition:color .15s ease-out;flex-shrink:0}.favorite-button:hover,.favorite-button--active{color:#f59e0b}.preset-card__actions{display:flex;gap:2px;flex-shrink:0}.more-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:4px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;width:22px;height:22px;opacity:.5;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out;line-height:1;font-size:14px;font-weight:700;position:relative;&:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}}.action-menu{position:absolute;top:28px;right:var(--ndt-spacing-sm);background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:var(--ndt-shadow-tooltip);z-index:20;min-width:180px;padding:4px;display:flex;flex-direction:column;gap:2px}.action-menu__item{appearance:none;background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:background .15s ease-out;white-space:nowrap;&:hover{background:var(--ndt-hover-bg)}ndt-icon{display:block;width:14px;height:14px;flex-shrink:0;color:var(--ndt-text-muted)}}.action-menu__item--danger{color:#ef4444;ndt-icon{color:#ef4444}&:hover{background:#ef44441a}}.expand-toggle{appearance:none;background:none;border:none;cursor:pointer;padding:0 4px;margin-right:2px;font-size:10px;color:var(--ndt-text-muted);line-height:1;opacity:.6;transition:opacity .15s ease-out;flex-shrink:0;&:hover{opacity:1}}.preset-card__details{padding:var(--ndt-spacing-sm) var(--ndt-spacing-sm) var(--ndt-spacing-xs);margin-top:2px;border-top:1px solid var(--ndt-border-primary);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.details-section__title{font-size:10px;font-weight:600;color:var(--ndt-text-muted);text-transform:uppercase;letter-spacing:.5px}.details-section__items{display:flex;flex-wrap:wrap;gap:4px;margin-top:2px}.detail-badge{font-size:10px;padding:1px 6px;border-radius:var(--ndt-border-radius-small);white-space:nowrap}.detail-badge--on{background:#22c55e1a;color:#22c55e}.detail-badge--off{background:#ef44441a;color:#ef4444}.preset-card__description{font-size:11px;color:var(--ndt-text-secondary);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__date{font-size:10px;color:var(--ndt-text-muted);margin-left:auto;flex-shrink:0}.badge{background:#6366f126;color:#6366f1;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:500;white-space:nowrap}.badge--lang{background:#22c55e26;color:#22c55e}.preset-form,.import-view,.apply-view{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm);ndt-input{width:100%}}.form-title{margin:0;font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary)}.form-hint{margin:0;font-size:11px;color:var(--ndt-text-muted);line-height:1.3}.form-field{display:flex;flex-direction:column;gap:2px}.field-error{color:#ef4444;font-size:11px}.preset-summary{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.category-section{display:flex;flex-direction:column;gap:2px}.checkbox-option{display:flex;align-items:center;gap:var(--ndt-spacing-xs);cursor:pointer;color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);padding:2px 0;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241);border-radius:3px;&:disabled{cursor:not-allowed;opacity:.4}}&:has(input:disabled){opacity:.5;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 20px;display:flex;flex-direction:column;gap:2px;font-size:11px;max-height:100px;overflow-y:auto;li{background:#6366f10d;border-radius:3px;border-left:2px solid rgba(99,102,241,.3)}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:3px 6px;cursor:pointer;gap:6px;input[type=checkbox]{cursor:pointer;width:12px;height:12px;accent-color:rgb(99,102,241);flex-shrink:0}&:hover{background:#6366f114}}.item-name{color:var(--ndt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0;&.enabled{background:#22c55e26;color:#22c55e}&.disabled{background:#ef444426;color:#ef4444}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ndt-spacing-sm);margin-top:auto;padding-top:var(--ndt-spacing-sm)}.config-preview{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.config-category{display:flex;flex-direction:column;gap:2px}.config-category__title{font-size:10px;color:var(--ndt-text-muted);font-weight:500}.config-items{display:flex;flex-wrap:wrap;gap:4px}.config-item{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--ndt-background-primary);color:var(--ndt-text-secondary)}.config-item--on{background:#22c55e1a;color:#22c55e}.config-item--off{background:#ef44441a;color:#ef4444}.replace-config-button{background:transparent;border:1px dashed var(--ndt-border-primary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-secondary);cursor:pointer;font-size:11px;transition:all .15s ease-out;&:hover{background:var(--ndt-hover-bg);border-color:#6366f1;color:#6366f1}}.drop-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--ndt-spacing-md);border:2px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);cursor:pointer;transition:all .15s ease-out}.drop-zone:hover,.drop-zone--active{border-color:#6366f1;background:#6366f10d}.drop-zone__icon{font-size:24px}.drop-zone__text{font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary)}.drop-zone__hint{font-size:11px;color:var(--ndt-text-muted)}.divider{display:flex;align-items:center;gap:var(--ndt-spacing-sm);color:var(--ndt-text-muted);font-size:10px;&:before,&:after{content:\"\";flex:1;height:1px;background:var(--ndt-border-primary)}}.json-textarea{width:100%;min-height:80px;padding:var(--ndt-spacing-xs);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background:var(--ndt-background-secondary);color:var(--ndt-text-primary);font-family:monospace;font-size:11px;resize:vertical;&:focus{outline:none;border-color:#6366f1}&::placeholder{color:var(--ndt-text-muted)}}.apply-description{margin:0;font-size:11px;color:var(--ndt-text-secondary)}.apply-categories{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.apply-category{background:var(--ndt-background-secondary);border-radius:var(--ndt-border-radius-small);overflow:hidden;transition:opacity .15s ease-out}.apply-category--disabled{opacity:.5}.apply-category__header{display:flex;align-items:center;gap:var(--ndt-spacing-xs);padding:6px var(--ndt-spacing-sm);cursor:pointer;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary);font-weight:500;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241)}}.apply-diff{padding:0 var(--ndt-spacing-sm) 6px;display:flex;flex-direction:column;gap:2px}.diff-item{display:flex;align-items:center;gap:6px;font-size:11px;padding:3px 6px;background:var(--ndt-background-primary);border-radius:3px}.diff-item__name{flex:1;color:var(--ndt-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-item__arrow{color:var(--ndt-text-muted);font-size:10px}.diff-item__value{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px}.diff-item__value--on{background:#22c55e26;color:#22c55e}.diff-item__value--off{background:#ef444426;color:#ef4444}\n"] }]
8405
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.toast{position:absolute;bottom:var(--ndt-spacing-md);left:var(--ndt-spacing-md);right:var(--ndt-spacing-md);z-index:10;display:flex;align-items:center;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);font-size:var(--ndt-font-size-sm);animation:slideUp .15s ease-out}.toast--success{background:var(--ndt-success);color:#fff}.toast--error{background:var(--ndt-danger);color:#fff}.toast__icon{font-weight:700}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.delete-view{flex:1;display:flex;flex-direction:column;justify-content:center;padding:var(--ndt-spacing-md)}.delete-view__content{text-align:center;padding:var(--ndt-spacing-lg) var(--ndt-spacing-md)}.delete-view__icon{font-size:48px;margin-bottom:var(--ndt-spacing-md)}.delete-view__title{margin:0 0 var(--ndt-spacing-sm);font-size:var(--ndt-font-size-md);color:var(--ndt-text-primary)}.delete-view__description{margin:0;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-secondary);line-height:1.5}.delete-button{background:var(--ndt-danger);color:#fff;border:none;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);border-radius:var(--ndt-border-radius-small);cursor:pointer;font-size:var(--ndt-font-size-sm);font-weight:500;transition:background .2s ease-out;&:hover{background:#dc2626}}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-md);ndt-input{flex:1}ndt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ndt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ndt-border-subtle);border-radius:var(--ndt-border-radius-medium);padding:var(--ndt-spacing-md);background:transparent;color:var(--ndt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ndt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ndt-spacing-xs);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ndt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ndt-border-primary);border-radius:4px;&:hover{background:var(--ndt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ndt-border-primary) var(--ndt-background-secondary)}.preset-card{background:var(--ndt-background-secondary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:2px;position:relative}.preset-card__header{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}.preset-card__row{display:flex;align-items:center;gap:6px;min-height:18px}.preset-card__row--meta{padding-left:36px}.preset-card__row--badges{padding-left:36px;gap:4px}.preset-card__name{font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__spacer{flex:1;min-width:8px}.system-badge{font-size:8px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 4px;border-radius:3px;background:var(--ndt-border-primary);color:var(--ndt-text-muted);flex-shrink:0}.favorite-button{background:transparent;border:none;cursor:pointer;font-size:12px;color:var(--ndt-text-muted);padding:0;line-height:1;transition:color .15s ease-out;flex-shrink:0}.favorite-button:hover,.favorite-button--active{color:#f59e0b}.preset-card__actions{display:flex;gap:2px;flex-shrink:0}.more-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:4px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-muted);display:flex;align-items:center;justify-content:center;width:22px;height:22px;opacity:.5;transition:opacity .15s ease-out,color .15s ease-out,background .15s ease-out;line-height:1;font-size:14px;font-weight:700;position:relative;&:hover{background:var(--ndt-hover-bg);color:var(--ndt-text-primary);opacity:1}}.action-menu{position:absolute;top:28px;right:var(--ndt-spacing-sm);background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);box-shadow:var(--ndt-shadow-tooltip);z-index:20;min-width:180px;padding:4px;display:flex;flex-direction:column;gap:2px}.action-menu__item{appearance:none;background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-primary);font-size:var(--ndt-font-size-xs);transition:background .15s ease-out;white-space:nowrap;&:hover{background:var(--ndt-hover-bg)}ndt-icon{display:block;width:14px;height:14px;flex-shrink:0;color:var(--ndt-text-muted)}}.action-menu__item--danger{color:var(--ndt-danger);ndt-icon{color:var(--ndt-danger)}&:hover{background:rgba(var(--ndt-danger-rgb),.1)}}.expand-toggle{appearance:none;background:none;border:none;cursor:pointer;padding:0 4px;margin-right:2px;font-size:10px;color:var(--ndt-text-muted);line-height:1;opacity:.6;transition:opacity .15s ease-out;flex-shrink:0;&:hover{opacity:1}}.preset-card__details{padding:var(--ndt-spacing-sm) var(--ndt-spacing-sm) var(--ndt-spacing-xs);margin-top:2px;border-top:1px solid var(--ndt-border-primary);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.details-section__title{font-size:10px;font-weight:600;color:var(--ndt-text-muted);text-transform:uppercase;letter-spacing:.5px}.details-section__items{display:flex;flex-wrap:wrap;gap:4px;margin-top:2px}.detail-badge{font-size:10px;padding:1px 6px;border-radius:var(--ndt-border-radius-small);white-space:nowrap}.detail-badge--on{background:rgba(var(--ndt-success-rgb),.1);color:var(--ndt-success)}.detail-badge--off{background:rgba(var(--ndt-danger-rgb),.1);color:var(--ndt-danger)}.preset-card__description{font-size:11px;color:var(--ndt-text-secondary);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__date{font-size:10px;color:var(--ndt-text-muted);margin-left:auto;flex-shrink:0}.badge{background:#6366f126;color:#6366f1;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:500;white-space:nowrap}.badge--lang{background:rgba(var(--ndt-success-rgb),.15);color:var(--ndt-success)}.preset-form,.import-view,.apply-view{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ndt-spacing-sm);padding:var(--ndt-spacing-sm);ndt-input{width:100%}}.form-title{margin:0;font-size:var(--ndt-font-size-sm);font-weight:600;color:var(--ndt-text-primary)}.form-hint{margin:0;font-size:11px;color:var(--ndt-text-muted);line-height:1.3}.form-field{display:flex;flex-direction:column;gap:2px}.field-error{color:var(--ndt-danger);font-size:11px}.preset-summary{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.category-section{display:flex;flex-direction:column;gap:2px}.checkbox-option{display:flex;align-items:center;gap:var(--ndt-spacing-xs);cursor:pointer;color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);padding:2px 0;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241);border-radius:3px;&:disabled{cursor:not-allowed;opacity:.4}}&:has(input:disabled){opacity:.5;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 20px;display:flex;flex-direction:column;gap:2px;font-size:11px;max-height:100px;overflow-y:auto;li{background:rgba(var(--ndt-primary-rgb),.05);border-radius:3px;padding-left:6px}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:3px 6px;cursor:pointer;gap:6px;input[type=checkbox]{cursor:pointer;width:12px;height:12px;accent-color:rgb(99,102,241);flex-shrink:0}&:hover{background:#6366f114}}.item-name{color:var(--ndt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0;&.enabled{background:rgba(var(--ndt-success-rgb),.15);color:var(--ndt-success)}&.disabled{background:rgba(var(--ndt-danger-rgb),.15);color:var(--ndt-danger)}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ndt-spacing-sm);margin-top:auto;padding-top:var(--ndt-spacing-sm)}.config-preview{background:var(--ndt-background-secondary);padding:var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ndt-text-secondary)}}.config-category{display:flex;flex-direction:column;gap:2px}.config-category__title{font-size:10px;color:var(--ndt-text-muted);font-weight:500}.config-items{display:flex;flex-wrap:wrap;gap:4px}.config-item{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--ndt-background-primary);color:var(--ndt-text-secondary)}.config-item--on{background:rgba(var(--ndt-success-rgb),.1);color:var(--ndt-success)}.config-item--off{background:rgba(var(--ndt-danger-rgb),.1);color:var(--ndt-danger)}.replace-config-button{background:transparent;border:1px dashed var(--ndt-border-primary);padding:6px var(--ndt-spacing-sm);border-radius:var(--ndt-border-radius-small);color:var(--ndt-text-secondary);cursor:pointer;font-size:11px;transition:all .15s ease-out;&:hover{background:var(--ndt-hover-bg);border-color:#6366f1;color:#6366f1}}.drop-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--ndt-spacing-md);border:2px dashed var(--ndt-border-primary);border-radius:var(--ndt-border-radius-medium);cursor:pointer;transition:all .15s ease-out}.drop-zone:hover,.drop-zone--active{border-color:#6366f1;background:#6366f10d}.drop-zone__icon{font-size:24px}.drop-zone__text{font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary)}.drop-zone__hint{font-size:11px;color:var(--ndt-text-muted)}.divider{display:flex;align-items:center;gap:var(--ndt-spacing-sm);color:var(--ndt-text-muted);font-size:10px;&:before,&:after{content:\"\";flex:1;height:1px;background:var(--ndt-border-primary)}}.json-textarea{width:100%;min-height:80px;padding:var(--ndt-spacing-xs);border:1px solid var(--ndt-border-primary);border-radius:var(--ndt-border-radius-small);background:var(--ndt-background-secondary);color:var(--ndt-text-primary);font-family:monospace;font-size:11px;resize:vertical;&:focus{outline:none;border-color:#6366f1}&::placeholder{color:var(--ndt-text-muted)}}.apply-description{margin:0;font-size:11px;color:var(--ndt-text-secondary)}.apply-categories{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.apply-category{background:var(--ndt-background-secondary);border-radius:var(--ndt-border-radius-small);overflow:hidden;transition:opacity .15s ease-out}.apply-category--disabled{opacity:.5}.apply-category__header{display:flex;align-items:center;gap:var(--ndt-spacing-xs);padding:6px var(--ndt-spacing-sm);cursor:pointer;font-size:var(--ndt-font-size-sm);color:var(--ndt-text-primary);font-weight:500;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241)}}.apply-diff{padding:0 var(--ndt-spacing-sm) 6px;display:flex;flex-direction:column;gap:2px}.diff-item{display:flex;align-items:center;gap:6px;font-size:11px;padding:3px 6px;background:var(--ndt-background-primary);border-radius:3px}.diff-item__name{flex:1;color:var(--ndt-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-item__arrow{color:var(--ndt-text-muted);font-size:10px}.diff-item__value{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px}.diff-item__value--on{background:rgba(var(--ndt-success-rgb),.15);color:var(--ndt-success)}.diff-item__value--off{background:rgba(var(--ndt-danger-rgb),.15);color:var(--ndt-danger)}\n"] }]
7552
8406
  }], ctorParameters: () => [], propDecorators: { onDocumentClick: [{
7553
8407
  type: HostListener,
7554
8408
  args: ['document:click']
@@ -7560,6 +8414,8 @@ class ToolbarComponent {
7560
8414
  this.state = inject(ToolbarStateService);
7561
8415
  this.destroyRef = inject(DestroyRef);
7562
8416
  this.settingsService = inject(SettingsService);
8417
+ this.customToolTypes = inject(TOOLBAR_CUSTOM_TOOLS, { optional: true }) ?? [];
8418
+ this.customToolsContainer = viewChild('customTools', { read: ViewContainerRef });
7563
8419
  this.config = input({});
7564
8420
  this.keyboardShortcut = fromEvent(window, 'keydown')
7565
8421
  .pipe(filter((event) => event.ctrlKey && event.shiftKey && event.key === 'D'), takeUntilDestroyed(this.destroyRef))
@@ -7579,6 +8435,15 @@ class ToolbarComponent {
7579
8435
  effect(() => {
7580
8436
  this.state.setConfig(this.config());
7581
8437
  });
8438
+ // Dynamically render registered custom tool components
8439
+ effect(() => {
8440
+ const container = this.customToolsContainer();
8441
+ if (container && container.length === 0 && this.customToolTypes.length > 0) {
8442
+ for (const toolType of this.customToolTypes) {
8443
+ container.createComponent(toolType);
8444
+ }
8445
+ }
8446
+ });
7582
8447
  }
7583
8448
  ngOnInit() {
7584
8449
  this.injectGlobalStyles();
@@ -7630,8 +8495,8 @@ class ToolbarComponent {
7630
8495
  --ndt-font-size-md: 1rem;
7631
8496
  --ndt-font-size-lg: 1.25rem;
7632
8497
  --ndt-font-size-xl: 2rem;
7633
- --ndt-primary: #df30d4;
7634
- --ndt-primary-rgb: 223, 48, 212;
8498
+ --ndt-primary: #635BFF;
8499
+ --ndt-primary-rgb: 99, 91, 255;
7635
8500
  --ndt-text-on-primary: rgb(255, 255, 255);
7636
8501
  --ndt-bg-primary: rgb(255, 255, 255);
7637
8502
  --ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, 0.88) 100%);
@@ -7656,6 +8521,12 @@ class ToolbarComponent {
7656
8521
  --ndt-warning-border: rgba(202, 138, 4, 0.2);
7657
8522
  --ndt-error-background: rgb(254, 226, 226);
7658
8523
  --ndt-error-border: rgba(220, 38, 38, 0.2);
8524
+ --ndt-success: rgb(34, 197, 94);
8525
+ --ndt-success-rgb: 34, 197, 94;
8526
+ --ndt-danger: rgb(239, 68, 68);
8527
+ --ndt-danger-rgb: 239, 68, 68;
8528
+ --ndt-forced: #f59e0b;
8529
+ --ndt-forced-rgb: 245, 158, 11;
7659
8530
  }
7660
8531
  .ndt-overlay-panel {
7661
8532
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
@@ -7673,7 +8544,7 @@ class ToolbarComponent {
7673
8544
  this.document.head.appendChild(this.globalStyleElement);
7674
8545
  }
7675
8546
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7676
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarComponent, isStandalone: true, selector: "ndt-toolbar", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8547
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarComponent, isStandalone: true, selector: "ndt-toolbar", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "customToolsContainer", first: true, predicate: ["customTools"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
7677
8548
  @if ((config().enabled ?? true) && !state.isCompletelyHidden()) {
7678
8549
  <div
7679
8550
  aria-label="Developer tools"
@@ -7689,6 +8560,7 @@ class ToolbarComponent {
7689
8560
  >
7690
8561
  <ndt-home-tool />
7691
8562
  <ng-content />
8563
+ <ng-container #customTools />
7692
8564
  @if (config().showI18nTool ?? false) {
7693
8565
  <ndt-i18n-tool />
7694
8566
  }
@@ -7706,7 +8578,7 @@ class ToolbarComponent {
7706
8578
  }
7707
8579
  </div>
7708
8580
  }
7709
- `, isInline: true, styles: [":host{display:contents;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-toolbar{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);position:fixed;z-index:999999;display:flex;pointer-events:auto;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:9999px;box-shadow:var(--ndt-shadow-toolbar);transition:transform .3s cubic-bezier(.4,0,.2,1)}.ndt-toolbar--bottom{bottom:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(100% - .5rem))}.ndt-toolbar--bottom.ndt-toolbar--visible{transform:translate(-50%) translateY(-10px)}.ndt-toolbar--top{top:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(-100% + .5rem))}.ndt-toolbar--top.ndt-toolbar--visible{transform:translate(-50%) translateY(10px)}.ndt-toolbar--left{left:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(-100% + .5rem))}.ndt-toolbar--left.ndt-toolbar--visible{transform:translateY(-50%) translate(10px)}.ndt-toolbar--right{right:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(100% - .5rem))}.ndt-toolbar--right.ndt-toolbar--visible{transform:translateY(-50%) translate(-10px)}h1,h2,h3,h4,h5{font-weight:600;color:var(--ndt-text-primary);margin:0}h1{font-size:var(--ndt-font-size-xl)}h2{font-size:var(--ndt-font-size-lg)}h3{font-size:var(--ndt-font-size-md)}h4{font-size:var(--ndt-font-size-sm)}h5{font-size:var(--ndt-font-size-xs)}hr{border:1px solid var(--ndt-border-subtle);margin:1em 0}p{line-height:1.5em;margin:0}\n"], dependencies: [{ kind: "component", type: ToolbarHomeToolComponent, selector: "ndt-home-tool", inputs: ["badge"] }, { kind: "component", type: ToolbarI18nToolComponent, selector: "ndt-i18n-tool" }, { kind: "component", type: ToolbarFeatureFlagsToolComponent, selector: "ndt-feature-flags-tool" }, { kind: "component", type: ToolbarAppFeaturesToolComponent, selector: "ndt-app-features-tool" }, { kind: "component", type: ToolbarPermissionsToolComponent, selector: "ndt-permissions-tool" }, { kind: "component", type: ToolbarPresetsToolComponent, selector: "ndt-presets-tool" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
8581
+ `, isInline: true, styles: [":host{display:contents;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-toolbar{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);position:fixed;z-index:999999;display:flex;pointer-events:auto;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:9999px;box-shadow:var(--ndt-shadow-toolbar);transition:transform .3s cubic-bezier(.4,0,.2,1)}.ndt-toolbar--bottom{bottom:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(100% - .5rem))}.ndt-toolbar--bottom.ndt-toolbar--visible{transform:translate(-50%) translateY(-10px)}.ndt-toolbar--top{top:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(-100% + .5rem))}.ndt-toolbar--top.ndt-toolbar--visible{transform:translate(-50%) translateY(10px)}.ndt-toolbar--left{left:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(-100% + .5rem))}.ndt-toolbar--left.ndt-toolbar--visible{transform:translateY(-50%) translate(10px)}.ndt-toolbar--right{right:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(100% - .5rem))}.ndt-toolbar--right.ndt-toolbar--visible{transform:translateY(-50%) translate(-10px)}h1,h2,h3,h4,h5{font-weight:600;color:var(--ndt-text-primary);margin:0}h1{font-size:var(--ndt-font-size-xl)}h2{font-size:var(--ndt-font-size-lg)}h3{font-size:var(--ndt-font-size-md)}h4{font-size:var(--ndt-font-size-sm)}h5{font-size:var(--ndt-font-size-xs)}hr{border:1px solid var(--ndt-border-subtle);margin:1em 0}p{line-height:1.5em;margin:0}\n"], dependencies: [{ kind: "component", type: ToolbarHomeToolComponent, selector: "ndt-home-tool", inputs: ["badge"] }, { kind: "component", type: ToolbarI18nToolComponent, selector: "ndt-i18n-tool" }, { kind: "component", type: ToolbarFeatureFlagsToolComponent, selector: "ndt-feature-flags-tool" }, { kind: "component", type: ToolbarAppFeaturesToolComponent, selector: "ndt-app-features-tool" }, { kind: "component", type: ToolbarPermissionsToolComponent, selector: "ndt-permissions-tool" }, { kind: "component", type: ToolbarPresetsToolComponent, selector: "ndt-presets-tool" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
7710
8582
  }
7711
8583
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarComponent, decorators: [{
7712
8584
  type: Component,
@@ -7733,6 +8605,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
7733
8605
  >
7734
8606
  <ndt-home-tool />
7735
8607
  <ng-content />
8608
+ <ng-container #customTools />
7736
8609
  @if (config().showI18nTool ?? false) {
7737
8610
  <ndt-i18n-tool />
7738
8611
  }
@@ -7750,7 +8623,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
7750
8623
  }
7751
8624
  </div>
7752
8625
  }
7753
- `, styles: [":host{display:contents;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-toolbar{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #df30d4;--ndt-primary-rgb: 223, 48, 212;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);position:fixed;z-index:999999;display:flex;pointer-events:auto;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:9999px;box-shadow:var(--ndt-shadow-toolbar);transition:transform .3s cubic-bezier(.4,0,.2,1)}.ndt-toolbar--bottom{bottom:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(100% - .5rem))}.ndt-toolbar--bottom.ndt-toolbar--visible{transform:translate(-50%) translateY(-10px)}.ndt-toolbar--top{top:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(-100% + .5rem))}.ndt-toolbar--top.ndt-toolbar--visible{transform:translate(-50%) translateY(10px)}.ndt-toolbar--left{left:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(-100% + .5rem))}.ndt-toolbar--left.ndt-toolbar--visible{transform:translateY(-50%) translate(10px)}.ndt-toolbar--right{right:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(100% - .5rem))}.ndt-toolbar--right.ndt-toolbar--visible{transform:translateY(-50%) translate(-10px)}h1,h2,h3,h4,h5{font-weight:600;color:var(--ndt-text-primary);margin:0}h1{font-size:var(--ndt-font-size-xl)}h2{font-size:var(--ndt-font-size-lg)}h3{font-size:var(--ndt-font-size-md)}h4{font-size:var(--ndt-font-size-sm)}h5{font-size:var(--ndt-font-size-xs)}hr{border:1px solid var(--ndt-border-subtle);margin:1em 0}p{line-height:1.5em;margin:0}\n"] }]
8626
+ `, styles: [":host{display:contents;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ndt-toolbar{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2);position:fixed;z-index:999999;display:flex;pointer-events:auto;background:var(--ndt-bg-primary);border:1px solid var(--ndt-border-primary);border-radius:9999px;box-shadow:var(--ndt-shadow-toolbar);transition:transform .3s cubic-bezier(.4,0,.2,1)}.ndt-toolbar--bottom{bottom:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(100% - .5rem))}.ndt-toolbar--bottom.ndt-toolbar--visible{transform:translate(-50%) translateY(-10px)}.ndt-toolbar--top{top:0;left:50%;flex-direction:row;height:30px;padding:0 2px;transform:translate(-50%) translateY(calc(-100% + .5rem))}.ndt-toolbar--top.ndt-toolbar--visible{transform:translate(-50%) translateY(10px)}.ndt-toolbar--left{left:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(-100% + .5rem))}.ndt-toolbar--left.ndt-toolbar--visible{transform:translateY(-50%) translate(10px)}.ndt-toolbar--right{right:0;top:50%;flex-direction:column;width:30px;padding:2px 0;transform:translateY(-50%) translate(calc(100% - .5rem))}.ndt-toolbar--right.ndt-toolbar--visible{transform:translateY(-50%) translate(-10px)}h1,h2,h3,h4,h5{font-weight:600;color:var(--ndt-text-primary);margin:0}h1{font-size:var(--ndt-font-size-xl)}h2{font-size:var(--ndt-font-size-lg)}h3{font-size:var(--ndt-font-size-md)}h4{font-size:var(--ndt-font-size-sm)}h5{font-size:var(--ndt-font-size-xs)}hr{border:1px solid var(--ndt-border-subtle);margin:1em 0}p{line-height:1.5em;margin:0}\n"] }]
7754
8627
  }], ctorParameters: () => [] });
7755
8628
 
7756
8629
  class ToolbarFeatureFlagService {
@@ -8205,11 +9078,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
8205
9078
  * @returns Angular EnvironmentProviders for all toolbar services
8206
9079
  */
8207
9080
  function provideToolbar(config) {
9081
+ const { customTools, ...configWithoutTools } = config ?? {};
8208
9082
  return makeEnvironmentProviders([
8209
9083
  { provide: TOOLBAR_FEATURE_FLAGS, useClass: ToolbarFeatureFlagService },
8210
9084
  { provide: TOOLBAR_PERMISSIONS, useClass: ToolbarPermissionsService },
8211
9085
  { provide: TOOLBAR_APP_FEATURES, useClass: ToolbarAppFeaturesService },
8212
- { provide: TOOLBAR_CONFIG, useValue: config ?? {} },
9086
+ { provide: TOOLBAR_CONFIG, useValue: configWithoutTools },
9087
+ { provide: TOOLBAR_CUSTOM_TOOLS, useValue: customTools ?? [] },
8213
9088
  {
8214
9089
  provide: ENVIRONMENT_INITIALIZER,
8215
9090
  multi: true,
@@ -8241,6 +9116,92 @@ function provideToolbar(config) {
8241
9116
  ]);
8242
9117
  }
8243
9118
 
9119
+ class ToolbarCardComponent {
9120
+ constructor() {
9121
+ this.click = signal(undefined);
9122
+ this.isHovered = signal(false);
9123
+ }
9124
+ onClick() {
9125
+ this.click.set();
9126
+ }
9127
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9128
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.7", type: ToolbarCardComponent, isStandalone: true, selector: "ndt-card", ngImport: i0, template: `
9129
+ <div
9130
+ class="card"
9131
+ role="button"
9132
+ tabindex="0"
9133
+ (click)="onClick()"
9134
+ (keydown.enter)="onClick()"
9135
+ (keydown.space)="onClick()"
9136
+ [class.card--hover]="isHovered()"
9137
+ (mouseenter)="isHovered.set(true)"
9138
+ (mouseleave)="isHovered.set(false)"
9139
+ >
9140
+ <ng-content></ng-content>
9141
+ </div>
9142
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.card{background:var(--ndt-bg-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md);cursor:pointer;transition:var(--ndt-transition-default);border:1px solid var(--ndt-border-subtle);position:relative;flex:1;height:120px;display:flex}.card:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 0 0 1px rgba(var(--ndt-primary-rgb),.3)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9143
+ }
9144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarCardComponent, decorators: [{
9145
+ type: Component,
9146
+ args: [{ selector: 'ndt-card', standalone: true, template: `
9147
+ <div
9148
+ class="card"
9149
+ role="button"
9150
+ tabindex="0"
9151
+ (click)="onClick()"
9152
+ (keydown.enter)="onClick()"
9153
+ (keydown.space)="onClick()"
9154
+ [class.card--hover]="isHovered()"
9155
+ (mouseenter)="isHovered.set(true)"
9156
+ (mouseleave)="isHovered.set(false)"
9157
+ >
9158
+ <ng-content></ng-content>
9159
+ </div>
9160
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.card{background:var(--ndt-bg-primary);border-radius:var(--ndt-border-radius-large);padding:var(--ndt-spacing-md);cursor:pointer;transition:var(--ndt-transition-default);border:1px solid var(--ndt-border-subtle);position:relative;flex:1;height:120px;display:flex}.card:hover{background:var(--ndt-hover-bg);border-color:var(--ndt-primary);box-shadow:0 0 0 1px rgba(var(--ndt-primary-rgb),.3)}\n"] }]
9161
+ }] });
9162
+
9163
+ class ToolbarClickableCardComponent {
9164
+ constructor() {
9165
+ this.icon = input.required();
9166
+ this.title = input.required();
9167
+ this.subtitle = input.required();
9168
+ this.click = signal(undefined);
9169
+ }
9170
+ onClick() {
9171
+ this.click.set();
9172
+ }
9173
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarClickableCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9174
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.7", type: ToolbarClickableCardComponent, isStandalone: true, selector: "ndt-clickable-card", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
9175
+ <ndt-card (clicked)="onClick()">
9176
+ <div class="clickable-card">
9177
+ <div class="clickable-card__icon">
9178
+ <ndt-icon [name]="icon()" />
9179
+ </div>
9180
+ <div class="clickable-card__content">
9181
+ <div class="clickable-card__title">{{ title() }}</div>
9182
+ <div class="clickable-card__subtitle">{{ subtitle() }}</div>
9183
+ </div>
9184
+ </div>
9185
+ </ndt-card>
9186
+ `, isInline: true, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.clickable-card{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);height:100%}.clickable-card__icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.clickable-card__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.clickable-card__title{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.clickable-card__subtitle{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n"], dependencies: [{ kind: "component", type: ToolbarCardComponent, selector: "ndt-card" }, { kind: "component", type: ToolbarIconComponent, selector: "ndt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9187
+ }
9188
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarClickableCardComponent, decorators: [{
9189
+ type: Component,
9190
+ args: [{ selector: 'ndt-clickable-card', standalone: true, imports: [ToolbarCardComponent, ToolbarIconComponent], template: `
9191
+ <ndt-card (clicked)="onClick()">
9192
+ <div class="clickable-card">
9193
+ <div class="clickable-card__icon">
9194
+ <ndt-icon [name]="icon()" />
9195
+ </div>
9196
+ <div class="clickable-card__content">
9197
+ <div class="clickable-card__title">{{ title() }}</div>
9198
+ <div class="clickable-card__subtitle">{{ subtitle() }}</div>
9199
+ </div>
9200
+ </div>
9201
+ </ndt-card>
9202
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ndt-border-radius-small: 4px;--ndt-border-radius-medium: 8px;--ndt-border-radius-large: 12px;--ndt-transition-default: all .2s ease-out;--ndt-transition-smooth: all .2s ease-in-out;--ndt-bg-primary: rgb(255, 255, 255);--ndt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ndt-text-primary: rgb(17, 24, 39);--ndt-text-secondary: rgb(55, 65, 81);--ndt-text-muted: rgb(107, 114, 128);--ndt-border-primary: #e5e7eb;--ndt-border-subtle: rgba(17, 24, 39, .1);--ndt-hover-bg: rgba(17, 24, 39, .05);--ndt-hover-danger: rgb(239, 68, 68);--ndt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ndt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ndt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ndt-spacing-xs: 4px;--ndt-spacing-sm: 6px;--ndt-spacing-md: 12px;--ndt-spacing-lg: 16px;--ndt-window-padding: 16px;--ndt-font-size-xxs: .65rem;--ndt-font-size-xs: .75rem;--ndt-font-size-sm: .875rem;--ndt-font-size-md: 1rem;--ndt-font-size-lg: 1.25rem;--ndt-font-size-xl: 2rem;--ndt-background-secondary: var(--ndt-bg-primary);--ndt-background-hover: var(--ndt-hover-bg);--ndt-primary: #635BFF;--ndt-primary-rgb: 99, 91, 255;--ndt-text-on-primary: rgb(255, 255, 255);--ndt-border-color: var(--ndt-border-primary);--ndt-tooltip-bg: rgb(17, 24, 39);--ndt-tooltip-text: rgb(255, 255, 255);--ndt-note-background: rgb(219, 234, 254);--ndt-note-border: rgba(37, 99, 235, .2);--ndt-warning-background: rgb(254, 249, 195);--ndt-warning-border: rgba(202, 138, 4, .2);--ndt-error-background: rgb(254, 226, 226);--ndt-error-border: rgba(220, 38, 38, .2)}.clickable-card{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs);height:100%}.clickable-card__icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--ndt-border-radius-medium);background:var(--ndt-hover-bg);color:var(--ndt-text-primary)}.clickable-card__content{display:flex;flex-direction:column;gap:var(--ndt-spacing-xs)}.clickable-card__title{color:var(--ndt-text-primary);font-size:var(--ndt-font-size-sm);font-weight:500}.clickable-card__subtitle{color:var(--ndt-text-muted);font-size:var(--ndt-font-size-xs);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}\n"] }]
9203
+ }] });
9204
+
8244
9205
  class ToolbarStepDirective {
8245
9206
  constructor() {
8246
9207
  this.ndtStep = input.required();
@@ -8303,6 +9264,128 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
8303
9264
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;flex-direction:column}.step-header{display:flex;align-items:center;gap:var(--ndt-spacing-sm);padding-bottom:var(--ndt-spacing-sm);margin-bottom:var(--ndt-spacing-sm);border-bottom:1px solid var(--ndt-border-primary)}.step-title{font-size:var(--ndt-font-size-md);font-weight:600;color:var(--ndt-text-primary)}\n"] }]
8304
9265
  }] });
8305
9266
 
9267
+ class ToolbarTabComponent {
9268
+ constructor() {
9269
+ this.label = input.required();
9270
+ this.isActive = signal(false);
9271
+ }
9272
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9273
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarTabComponent, isStandalone: true, selector: "ndt-tab", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
9274
+ @if (isActive()) {
9275
+ <ng-content />
9276
+ }
9277
+ `, isInline: true, styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9278
+ }
9279
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarTabComponent, decorators: [{
9280
+ type: Component,
9281
+ args: [{ selector: 'ndt-tab', standalone: true, template: `
9282
+ @if (isActive()) {
9283
+ <ng-content />
9284
+ }
9285
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
9286
+ }] });
9287
+
9288
+ class ToolbarTabsComponent {
9289
+ constructor() {
9290
+ this.tabs = contentChildren(ToolbarTabComponent);
9291
+ this.activeIndex = signal(0);
9292
+ this.activeIndexChange = output();
9293
+ this.instanceId = Math.random().toString(36).slice(2, 9);
9294
+ effect(() => {
9295
+ const tabs = this.tabs();
9296
+ const active = this.activeIndex();
9297
+ tabs.forEach((tab, i) => tab.isActive.set(i === active));
9298
+ });
9299
+ }
9300
+ selectTab(index) {
9301
+ this.activeIndex.set(index);
9302
+ this.activeIndexChange.emit(index);
9303
+ }
9304
+ onKeydown(event, currentIndex) {
9305
+ const count = this.tabs().length;
9306
+ let newIndex = null;
9307
+ switch (event.key) {
9308
+ case 'ArrowRight':
9309
+ newIndex = (currentIndex + 1) % count;
9310
+ break;
9311
+ case 'ArrowLeft':
9312
+ newIndex = (currentIndex - 1 + count) % count;
9313
+ break;
9314
+ case 'Home':
9315
+ newIndex = 0;
9316
+ break;
9317
+ case 'End':
9318
+ newIndex = count - 1;
9319
+ break;
9320
+ default:
9321
+ return;
9322
+ }
9323
+ event.preventDefault();
9324
+ this.selectTab(newIndex);
9325
+ const button = event.target
9326
+ .parentElement?.querySelectorAll('[role="tab"]')[newIndex];
9327
+ button?.focus();
9328
+ }
9329
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9330
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarTabsComponent, isStandalone: true, selector: "ndt-tabs", outputs: { activeIndexChange: "activeIndexChange" }, queries: [{ propertyName: "tabs", predicate: ToolbarTabComponent, isSignal: true }], ngImport: i0, template: `
9331
+ <div class="tab-bar" role="tablist">
9332
+ @for (tab of tabs(); track $index) {
9333
+ <button
9334
+ class="tab-button"
9335
+ [class.tab-button--active]="$index === activeIndex()"
9336
+ role="tab"
9337
+ [attr.aria-selected]="$index === activeIndex()"
9338
+ [attr.tabindex]="$index === activeIndex() ? 0 : -1"
9339
+ [attr.id]="'tab-' + instanceId + '-' + $index"
9340
+ [attr.aria-controls]="'tabpanel-' + instanceId"
9341
+ (click)="selectTab($index)"
9342
+ (keydown)="onKeydown($event, $index)"
9343
+ >
9344
+ {{ tab.label() }}
9345
+ </button>
9346
+ }
9347
+ </div>
9348
+ <div
9349
+ class="tab-panel"
9350
+ role="tabpanel"
9351
+ [attr.id]="'tabpanel-' + instanceId"
9352
+ [attr.aria-labelledby]="'tab-' + instanceId + '-' + activeIndex()"
9353
+ >
9354
+ <ng-content />
9355
+ </div>
9356
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column}.tab-bar{display:flex;gap:var(--ndt-spacing-xs);padding:0;margin:0;border-bottom:1px solid var(--ndt-border-primary);flex-shrink:0}.tab-button{all:unset;display:inline-flex;align-items:center;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);font-size:var(--ndt-font-size-sm);font-weight:500;color:var(--ndt-text-secondary);cursor:pointer;border-bottom:2px solid transparent;transition:color .15s ease,border-color .15s ease;box-sizing:border-box}.tab-button:hover{color:var(--ndt-text-primary)}.tab-button:focus-visible{outline:2px solid var(--ndt-text-primary);outline-offset:-2px;border-radius:var(--ndt-border-radius-small)}.tab-button--active{color:var(--ndt-text-primary);border-bottom-color:var(--ndt-text-primary);font-weight:600}.tab-panel{flex:1;min-height:0;overflow:auto;padding-top:var(--ndt-spacing-md)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9357
+ }
9358
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarTabsComponent, decorators: [{
9359
+ type: Component,
9360
+ args: [{ selector: 'ndt-tabs', standalone: true, template: `
9361
+ <div class="tab-bar" role="tablist">
9362
+ @for (tab of tabs(); track $index) {
9363
+ <button
9364
+ class="tab-button"
9365
+ [class.tab-button--active]="$index === activeIndex()"
9366
+ role="tab"
9367
+ [attr.aria-selected]="$index === activeIndex()"
9368
+ [attr.tabindex]="$index === activeIndex() ? 0 : -1"
9369
+ [attr.id]="'tab-' + instanceId + '-' + $index"
9370
+ [attr.aria-controls]="'tabpanel-' + instanceId"
9371
+ (click)="selectTab($index)"
9372
+ (keydown)="onKeydown($event, $index)"
9373
+ >
9374
+ {{ tab.label() }}
9375
+ </button>
9376
+ }
9377
+ </div>
9378
+ <div
9379
+ class="tab-panel"
9380
+ role="tabpanel"
9381
+ [attr.id]="'tabpanel-' + instanceId"
9382
+ [attr.aria-labelledby]="'tab-' + instanceId + '-' + activeIndex()"
9383
+ >
9384
+ <ng-content />
9385
+ </div>
9386
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;flex-direction:column}.tab-bar{display:flex;gap:var(--ndt-spacing-xs);padding:0;margin:0;border-bottom:1px solid var(--ndt-border-primary);flex-shrink:0}.tab-button{all:unset;display:inline-flex;align-items:center;padding:var(--ndt-spacing-sm) var(--ndt-spacing-md);font-size:var(--ndt-font-size-sm);font-weight:500;color:var(--ndt-text-secondary);cursor:pointer;border-bottom:2px solid transparent;transition:color .15s ease,border-color .15s ease;box-sizing:border-box}.tab-button:hover{color:var(--ndt-text-primary)}.tab-button:focus-visible{outline:2px solid var(--ndt-text-primary);outline-offset:-2px;border-radius:var(--ndt-border-radius-small)}.tab-button--active{color:var(--ndt-text-primary);border-bottom-color:var(--ndt-text-primary);font-weight:600}.tab-panel{flex:1;min-height:0;overflow:auto;padding-top:var(--ndt-spacing-md)}\n"] }]
9387
+ }], ctorParameters: () => [] });
9388
+
8306
9389
  class ToolbarI18nService {
8307
9390
  constructor() {
8308
9391
  this.internalService = inject(ToolbarInternalI18nService);
@@ -8591,5 +9674,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
8591
9674
  * Generated bundle index. Do not edit.
8592
9675
  */
8593
9676
 
8594
- export { CURRENCY_SYMBOLS, DEFAULT_CURRENCIES, DEFAULT_TIMEZONES, TOOLBAR_APP_FEATURES, TOOLBAR_CONFIG, TOOLBAR_FEATURE_FLAGS, TOOLBAR_PERMISSIONS, TOOLBAR_POSITIONS, ToolbarAppFeaturesService, ToolbarAppFeaturesToolComponent, ToolbarButtonComponent, ToolbarCardComponent, ToolbarClickableCardComponent, ToolbarComponent, ToolbarFeatureFlagService, ToolbarI18nService, ToolbarI18nToolComponent, ToolbarIconButtonComponent, ToolbarIconComponent, ToolbarInputComponent, ToolbarLinkButtonComponent, ToolbarListComponent, ToolbarListItemComponent, ToolbarPermissionsService, ToolbarPermissionsToolComponent, ToolbarPresetsService, ToolbarPresetsToolComponent, ToolbarSelectComponent, ToolbarStepDirective, ToolbarStepViewComponent, ToolbarToolComponent, expandText, formatCurrency, formatCustomDate, formatCustomNumber, formatDate, formatNumber, formatTime, isHorizontalPosition, provideToolbar, pseudoLocalize };
9677
+ export { CURRENCY_SYMBOLS, DEFAULT_CURRENCIES, DEFAULT_TIMEZONES, TOOLBAR_APP_FEATURES, TOOLBAR_CONFIG, TOOLBAR_FEATURE_FLAGS, TOOLBAR_PERMISSIONS, TOOLBAR_POSITIONS, ToolbarAppFeaturesService, ToolbarAppFeaturesToolComponent, ToolbarButtonComponent, ToolbarCardComponent, ToolbarClickableCardComponent, ToolbarComponent, ToolbarConfirmDialogComponent, ToolbarFeatureFlagService, ToolbarI18nService, ToolbarI18nToolComponent, ToolbarIconButtonComponent, ToolbarIconComponent, ToolbarInputComponent, ToolbarLinkButtonComponent, ToolbarListComponent, ToolbarListGroupComponent, ToolbarListItemComponent, ToolbarPermissionsService, ToolbarPermissionsToolComponent, ToolbarPresetsService, ToolbarPresetsToolComponent, ToolbarSelectComponent, ToolbarStepDirective, ToolbarStepViewComponent, ToolbarTabComponent, ToolbarTabsComponent, ToolbarToolComponent, ToolbarToolHeaderComponent, expandText, formatCurrency, formatCustomDate, formatCustomNumber, formatDate, formatNumber, formatTime, isHorizontalPosition, provideToolbar, pseudoLocalize };
8595
9678
  //# sourceMappingURL=ngx-dev-toolbar.mjs.map