ngx-dev-toolbar 4.2.1 → 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.
package/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './components/icons/icon.component';
4
4
  export * from './components/icons/icon.models';
5
5
  export * from './components/list/list.component';
6
6
  export * from './components/list-item/list-item.component';
7
+ export * from './components/list-group/list-group.component';
7
8
  export * from './components/toolbar-tool/toolbar-tool.component';
8
9
  export * from './components/toolbar-tool/toolbar-tool.models';
9
10
  export * from './components/button/button.component';
@@ -15,6 +16,10 @@ export * from './components/clickable-card/clickable-card.component';
15
16
  export * from './components/link-button/link-button.component';
16
17
  export * from './components/step-view/step-view.component';
17
18
  export * from './components/step-view/step-view.directive';
19
+ export * from './components/tabs/tab.component';
20
+ export * from './components/tabs/tabs.component';
21
+ export * from './components/tool-header/tool-header.component';
22
+ export * from './components/confirm-dialog/confirm-dialog.component';
18
23
  export * from './toolbar.component';
19
24
  export * from './models/toolbar.interface';
20
25
  export * from './models/toolbar-config.interface';
@@ -11,4 +11,6 @@ export interface ToolViewState {
11
11
  sortOrder: 'asc' | 'desc';
12
12
  /** IDs of pinned items that should appear at the top of the list */
13
13
  pinnedIds?: string[];
14
+ /** Names of groups currently collapsed in the UI; persisted to localStorage */
15
+ collapsedGroups?: string[];
14
16
  }
@@ -1,3 +1,4 @@
1
+ import { Type } from '@angular/core';
1
2
  import { ToolbarPosition } from './toolbar-position.model';
2
3
  /**
3
4
  * Configuration options for the Angular Toolbar component.
@@ -43,6 +44,20 @@ export interface ToolbarConfig {
43
44
  * @default true
44
45
  */
45
46
  showPresetsTool?: boolean;
47
+ /**
48
+ * Custom tool components to render inside the toolbar.
49
+ *
50
+ * Each component should use `ToolbarToolComponent` as its wrapper
51
+ * and will appear as an icon in the toolbar strip alongside built-in tools.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * provideToolbar({
56
+ * customTools: [MyFinderTool, MyDebugTool],
57
+ * })
58
+ * ```
59
+ */
60
+ customTools?: Type<unknown>[];
46
61
  /**
47
62
  * Callback to persist a forced feature flag value to the actual source.
48
63
  * When provided, an "Apply to source" button appears on each forced flag.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-dev-toolbar",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "keywords": [
5
5
  "devtools",
6
6
  "development-toolbar",
package/tokens.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { InjectionToken } from '@angular/core';
1
+ import { InjectionToken, Type } from '@angular/core';
2
2
  import { ToolbarConfig } from './models/toolbar-config.interface';
3
3
  import { ToolbarService } from './models/toolbar.interface';
4
4
  import { ToolbarAppFeature } from './tools/app-features-tool/app-features.models';
@@ -62,3 +62,26 @@ export declare const TOOLBAR_PERMISSIONS: InjectionToken<ToolbarService<ToolbarP
62
62
  * ```
63
63
  */
64
64
  export declare const TOOLBAR_APP_FEATURES: InjectionToken<ToolbarService<ToolbarAppFeature>>;
65
+ /**
66
+ * InjectionToken for registering custom tool components with the toolbar.
67
+ *
68
+ * Custom tools are Angular components that extend the toolbar with app-specific
69
+ * functionality. They are dynamically rendered inside the toolbar at runtime.
70
+ *
71
+ * Use `provideToolbarCustomTools()` to register custom tool components.
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * // app.config.ts
76
+ * import { provideToolbar, provideToolbarCustomTools } from 'ngx-dev-toolbar';
77
+ * import { MyCustomToolComponent } from './my-custom-tool.component';
78
+ *
79
+ * export const appConfig: ApplicationConfig = {
80
+ * providers: [
81
+ * provideToolbar({ ... }),
82
+ * provideToolbarCustomTools(MyCustomToolComponent),
83
+ * ],
84
+ * };
85
+ * ```
86
+ */
87
+ export declare const TOOLBAR_CUSTOM_TOOLS: InjectionToken<Type<unknown>[]>;
@@ -8,6 +8,8 @@ export declare class ToolbarComponent implements OnInit, OnDestroy {
8
8
  state: ToolbarStateService;
9
9
  destroyRef: DestroyRef;
10
10
  settingsService: SettingsService;
11
+ private customToolTypes;
12
+ private customToolsContainer;
11
13
  config: import("@angular/core").InputSignal<ToolbarConfig>;
12
14
  private globalStyleElement?;
13
15
  private keyboardShortcut;
@@ -22,12 +22,16 @@ export declare class ToolbarAppFeaturesToolComponent {
22
22
  protected readonly activeFilter: import("@angular/core").WritableSignal<AppFeatureFilter>;
23
23
  protected readonly searchQuery: import("@angular/core").WritableSignal<string>;
24
24
  protected readonly pinnedIds: import("@angular/core").WritableSignal<Set<string>>;
25
+ protected readonly collapsedGroups: import("@angular/core").WritableSignal<Set<string>>;
25
26
  constructor();
26
27
  private loadViewState;
27
28
  protected readonly features: import("@angular/core").Signal<ToolbarAppFeature[]>;
28
29
  protected readonly badgeCount: import("@angular/core").Signal<string>;
29
30
  protected readonly hasNoFeatures: import("@angular/core").Signal<boolean>;
30
- protected readonly filteredFeatures: import("@angular/core").Signal<ToolbarAppFeature[]>;
31
+ private readonly filteredFeatures;
32
+ protected readonly groupedFeatures: import("@angular/core").Signal<import("../../utils/group-items.util").GroupedItems<ToolbarAppFeature>>;
33
+ protected readonly flatFeatures: import("@angular/core").Signal<ToolbarAppFeature[]>;
34
+ protected readonly hasAnyGroups: import("@angular/core").Signal<boolean>;
31
35
  protected readonly hasNoFilteredFeatures: import("@angular/core").Signal<boolean>;
32
36
  protected readonly options: ToolbarWindowOptions;
33
37
  protected readonly filterOptions: {
@@ -59,6 +63,8 @@ export declare class ToolbarAppFeaturesToolComponent {
59
63
  */
60
64
  onSearchChange(query: string): void;
61
65
  togglePin(featureId: string): void;
66
+ protected isCollapsed(name: string): boolean;
67
+ protected setCollapsed(name: string, collapsed: boolean): void;
62
68
  /**
63
69
  * Get the dropdown value for a feature's current state.
64
70
  * - Returns empty string if not forced (natural state)
@@ -47,6 +47,11 @@ export interface ToolbarAppFeature {
47
47
  * Used to display what the feature's state was before being overridden
48
48
  */
49
49
  originalValue?: boolean;
50
+ /**
51
+ * Optional group name. Items without a group render in an "Other" section.
52
+ * @example 'Billing', 'Reporting'
53
+ */
54
+ group?: string;
50
55
  }
51
56
  /**
52
57
  * Filter options for displaying features in the toolbar UI.
@@ -1,5 +1,5 @@
1
1
  import { ToolbarWindowOptions } from '../../components/toolbar-tool/toolbar-tool.models';
2
- import { ToolbarFlag, FeatureFlagFilter } from './feature-flags.models';
2
+ import { FeatureFlagFilter, ToolbarFlag } from './feature-flags.models';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class ToolbarFeatureFlagsToolComponent {
5
5
  private readonly featureFlags;
@@ -8,12 +8,16 @@ export declare class ToolbarFeatureFlagsToolComponent {
8
8
  protected readonly activeFilter: import("@angular/core").WritableSignal<FeatureFlagFilter>;
9
9
  protected readonly searchQuery: import("@angular/core").WritableSignal<string>;
10
10
  protected readonly pinnedIds: import("@angular/core").WritableSignal<Set<string>>;
11
+ protected readonly collapsedGroups: import("@angular/core").WritableSignal<Set<string>>;
11
12
  constructor();
12
13
  private loadViewState;
13
14
  protected readonly flags: import("@angular/core").Signal<ToolbarFlag[]>;
14
15
  protected readonly badgeCount: import("@angular/core").Signal<string>;
15
16
  protected readonly hasNoFlags: import("@angular/core").Signal<boolean>;
16
- protected readonly filteredFlags: import("@angular/core").Signal<ToolbarFlag[]>;
17
+ private readonly filteredFlags;
18
+ protected readonly groupedFlags: import("@angular/core").Signal<import("../../utils/group-items.util").GroupedItems<ToolbarFlag>>;
19
+ protected readonly flatFlags: import("@angular/core").Signal<ToolbarFlag[]>;
20
+ protected readonly hasAnyGroups: import("@angular/core").Signal<boolean>;
17
21
  protected readonly hasNoFilteredFlags: import("@angular/core").Signal<boolean>;
18
22
  protected readonly options: ToolbarWindowOptions;
19
23
  protected readonly filterOptions: {
@@ -31,6 +35,8 @@ export declare class ToolbarFeatureFlagsToolComponent {
31
35
  onFlagChange(flagId: string, value: string): void;
32
36
  onSearchChange(query: string): void;
33
37
  togglePin(flagId: string): void;
38
+ protected isCollapsed(name: string): boolean;
39
+ protected setCollapsed(name: string, collapsed: boolean): void;
34
40
  protected getFlagValue(flag: ToolbarFlag): string;
35
41
  protected getFlagPlaceholder(flag: ToolbarFlag): string;
36
42
  static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarFeatureFlagsToolComponent, never>;
@@ -6,5 +6,7 @@ export interface ToolbarFlag {
6
6
  isEnabled: boolean;
7
7
  isForced: boolean;
8
8
  originalValue?: boolean;
9
+ /** Optional group name. Items without a group render in an "Other" section. */
10
+ group?: string;
9
11
  }
10
12
  export type FeatureFlagFilter = 'all' | 'forced' | 'enabled' | 'disabled';
@@ -35,6 +35,8 @@ export declare class ToolbarHomeToolComponent {
35
35
  onExportSettings(): void;
36
36
  onImportSettings(): void;
37
37
  onResetSettings(): void;
38
+ protected confirmReset(): void;
39
+ private readonly resetDialog;
38
40
  static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarHomeToolComponent, never>;
39
41
  static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarHomeToolComponent, "ndt-home-tool", never, { "badge": { "alias": "badge"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
40
42
  }
@@ -30,6 +30,7 @@ export declare class ToolbarI18nToolComponent {
30
30
  pseudoLocEnabled: import("@angular/core").Signal<boolean>;
31
31
  rtlEnabled: import("@angular/core").Signal<boolean>;
32
32
  toolConfig: import("@angular/core").Signal<I18nToolConfig>;
33
+ hasAdvancedFormatSettings: import("@angular/core").Signal<boolean>;
33
34
  localeOptions: import("@angular/core").Signal<{
34
35
  value: string;
35
36
  label: string;
@@ -1,5 +1,5 @@
1
1
  import { ToolbarWindowOptions } from '../../components/toolbar-tool/toolbar-tool.models';
2
- import { ToolbarPermission, PermissionFilter } from './permissions.models';
2
+ import { PermissionFilter, ToolbarPermission } from './permissions.models';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class ToolbarPermissionsToolComponent {
5
5
  private readonly permissionsService;
@@ -8,12 +8,16 @@ export declare class ToolbarPermissionsToolComponent {
8
8
  protected readonly activeFilter: import("@angular/core").WritableSignal<PermissionFilter>;
9
9
  protected readonly searchQuery: import("@angular/core").WritableSignal<string>;
10
10
  protected readonly pinnedIds: import("@angular/core").WritableSignal<Set<string>>;
11
+ protected readonly collapsedGroups: import("@angular/core").WritableSignal<Set<string>>;
11
12
  constructor();
12
13
  private loadViewState;
13
14
  protected readonly permissions: import("@angular/core").Signal<ToolbarPermission[]>;
14
15
  protected readonly badgeCount: import("@angular/core").Signal<string>;
15
16
  protected readonly hasNoPermissions: import("@angular/core").Signal<boolean>;
16
- protected readonly filteredPermissions: import("@angular/core").Signal<ToolbarPermission[]>;
17
+ private readonly filteredPermissions;
18
+ protected readonly groupedPermissions: import("@angular/core").Signal<import("../../utils/group-items.util").GroupedItems<ToolbarPermission>>;
19
+ protected readonly flatPermissions: import("@angular/core").Signal<ToolbarPermission[]>;
20
+ protected readonly hasAnyGroups: import("@angular/core").Signal<boolean>;
17
21
  protected readonly hasNoFilteredPermissions: import("@angular/core").Signal<boolean>;
18
22
  protected readonly options: ToolbarWindowOptions;
19
23
  protected readonly filterOptions: {
@@ -31,6 +35,8 @@ export declare class ToolbarPermissionsToolComponent {
31
35
  onPermissionChange(id: string, value: string): void;
32
36
  onSearchChange(query: string): void;
33
37
  togglePin(permissionId: string): void;
38
+ protected isCollapsed(name: string): boolean;
39
+ protected setCollapsed(name: string, collapsed: boolean): void;
34
40
  protected getPermissionValue(permission: ToolbarPermission): string;
35
41
  static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarPermissionsToolComponent, never>;
36
42
  static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarPermissionsToolComponent, "ndt-permissions-tool", never, {}, {}, never, never, true, never>;
@@ -15,6 +15,8 @@ export interface ToolbarPermission {
15
15
  isForced: boolean;
16
16
  /** Original value before forcing (only present when isForced is true) */
17
17
  originalValue?: boolean;
18
+ /** Optional group name. Items without a group render in an "Other" section. */
19
+ group?: string;
18
20
  }
19
21
  /**
20
22
  * Internal state representing forced permission overrides.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Minimum shape required by {@link groupItems}: each item needs a stable id,
3
+ * a display name (used for sorting), and an optional group label.
4
+ */
5
+ export interface Groupable {
6
+ id: string;
7
+ name: string;
8
+ group?: string;
9
+ }
10
+ /**
11
+ * Result of partitioning a list of items into pinned, named groups, and ungrouped.
12
+ */
13
+ export interface GroupedItems<T extends Groupable> {
14
+ /** Pinned items, alphabetically sorted. Always rendered first, regardless of group. */
15
+ pinned: T[];
16
+ /** Named groups, sorted alphabetically by group name; items inside each group sorted alphabetically by name. */
17
+ groups: {
18
+ name: string;
19
+ items: T[];
20
+ }[];
21
+ /** Items without a group (and not pinned), sorted alphabetically. Rendered last. */
22
+ ungrouped: T[];
23
+ }
24
+ /**
25
+ * Partitions items into pinned + named groups + ungrouped sections, applying
26
+ * the same alphabetical-name ordering used elsewhere in the toolbar.
27
+ *
28
+ * Backward-compatible: if no item has a `group`, `groups` is `[]` and the
29
+ * result is equivalent to the legacy pinned-first flat list.
30
+ *
31
+ * Pure function — no side effects, returns a new object.
32
+ */
33
+ export declare function groupItems<T extends Groupable>(items: T[], pinnedIds: Set<string>): GroupedItems<T>;