@toolbox-web/grid-angular 1.9.1 → 2.0.0-beta
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/fesm2022/toolbox-web-grid-angular-features-editing.mjs +2317 -4
- package/fesm2022/toolbox-web-grid-angular-features-editing.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +91 -2
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs +97 -4
- package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs +1 -15
- package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs +109 -3
- package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-shell.mjs +452 -0
- package/fesm2022/toolbox-web-grid-angular-features-shell.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular.mjs +740 -4649
- package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
- package/package.json +2 -6
- package/types/toolbox-web-grid-angular-features-editing.d.ts +1181 -4
- package/types/toolbox-web-grid-angular-features-editing.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-filtering.d.ts +102 -7
- package/types/toolbox-web-grid-angular-features-filtering.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-master-detail.d.ts +88 -4
- package/types/toolbox-web-grid-angular-features-master-detail.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts +2 -7
- package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-responsive.d.ts +109 -3
- package/types/toolbox-web-grid-angular-features-responsive.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-shell.d.ts +229 -0
- package/types/toolbox-web-grid-angular-features-shell.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular.d.ts +483 -2929
- package/types/toolbox-web-grid-angular.d.ts.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs +0 -70
- package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs.map +0 -1
- package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts +0 -25
- package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbox-web-grid-angular-features-responsive.mjs","sources":["../../../../libs/grid-angular/features/responsive/src/grid-responsive.directive.ts","../../../../libs/grid-angular/features/responsive/src/index.ts","../../../../libs/grid-angular/features/responsive/src/toolbox-web-grid-angular-features-responsive.ts"],"sourcesContent":["/**\n * `GridResponsiveDirective` — owns `[responsive]` and `(responsiveChange)`\n * on `<tbw-grid>`. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, OnInit, output, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { claimEvent, registerFeatureClaim, unclaimEvent, unregisterFeatureClaim } from '@toolbox-web/grid-angular';\nimport type {\n ResponsivePluginConfig as CoreResponsivePluginConfig,\n ResponsiveChangeDetail,\n} from '@toolbox-web/grid/plugins/responsive';\n\n/**\n * Angular-specific responsive config that allows an Angular component class\n * as `cardRenderer`.\n *\n * Extends the core `ResponsivePluginConfig` to accept a `Type<unknown>` for\n * `cardRenderer` in addition to the vanilla\n * `(row, rowIndex, column?) => HTMLElement` signature. Bridging to vanilla\n * DOM is handled by the side-effect import\n * `@toolbox-web/grid-angular/features/responsive`.\n *\n * Re-exported from the feature entry under the same name as the core type\n * so Angular consumers see a single canonical `ResponsivePluginConfig` from\n * `@toolbox-web/grid-angular/features/responsive`.\n *\n * @since 1.7.1\n */\nexport type ResponsivePluginConfig<TRow = unknown> = Omit<CoreResponsivePluginConfig<TRow>, 'cardRenderer'> & {\n cardRenderer?: CoreResponsivePluginConfig<TRow>['cardRenderer'] | Type<unknown>;\n};\n\n/**\n * Owns the binding(s) `[responsive], [responsiveChange]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\n@Directive({\n selector: 'tbw-grid[responsive], tbw-grid[responsiveChange]',\n standalone: true,\n})\nexport class GridResponsiveDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly responsive = input<boolean | ResponsivePluginConfig>();\n readonly responsiveChange = output<ResponsiveChangeDetail>();\n\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'responsive', () => this.responsive());\n claimEvent(grid, 'responsive-change');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event): void => this.responsiveChange.emit((e as CustomEvent<ResponsiveChangeDetail>).detail);\n grid.addEventListener('responsive-change', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('responsive-change', this.listener);\n this.listener = undefined;\n }\n unregisterFeatureClaim(grid, 'responsive');\n unclaimEvent(grid, 'responsive-change');\n }\n}\n","/**\n * Responsive feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `[responsive]` input on the `Grid`\n * directive AND to wire `<tbw-grid-responsive-card>` Angular templates into\n * the ResponsivePlugin's `cardRenderer`.\n *\n * @example\n * ```typescript\n * // In your bootstrap (e.g. main.ts or app.component.ts):\n * import '@toolbox-web/grid-angular/features/responsive';\n * ```\n *\n * ```html\n * <tbw-grid [responsive]=\"{ breakpoint: 768 }\">\n * <tbw-grid-responsive-card>\n * <ng-template let-row>...</ng-template>\n * </tbw-grid-responsive-card>\n * </tbw-grid>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Type } from '@angular/core';\nimport {\n getResponsiveCardTemplate,\n isComponentClass,\n registerFeatureConfigPreprocessor,\n registerResponsiveCardRendererBridge,\n registerTemplateBridge,\n type GridAdapter,\n type GridResponsiveCardContext,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/responsive';\nimport type { ResponsivePluginConfig } from './grid-responsive.directive';\nexport { GridResponsiveDirective } from './grid-responsive.directive';\nexport type { ResponsivePluginConfig } from './grid-responsive.directive';\nexport type { _Augmentation as _ResponsiveAugmentation } from '@toolbox-web/grid/features/responsive';\n\n/**\n * Subset of `ResponsivePlugin` we touch from the bridge. Avoids importing\n * the plugin class itself.\n */\ninterface ResponsivePluginLike {\n setCardRenderer?: (renderer: (row: unknown, rowIndex: number) => HTMLElement) => void;\n}\n\n// Install the row renderer bridge on the adapter. This is what\n// `adapter.createResponsiveCardRenderer(grid)` and\n// `adapter.parseResponsiveCardElement(el)` delegate to. Without this import,\n// both methods return undefined.\nregisterResponsiveCardRendererBridge(<TRow = unknown>(gridElement: HTMLElement, adapter: GridAdapter) => {\n // Type inferred from `getResponsiveCardTemplate` (same package instance as\n // `adapter`), not from a local `import type { TemplateRef } from '@angular/core'`\n // — the latter resolves through Bun's `.bun/` cache during ng-packagr build\n // and produces a brand-incompatible TemplateRef vs the built adapter `.d.ts`.\n const template = getResponsiveCardTemplate(gridElement);\n if (!template) return undefined;\n\n return (row: TRow, rowIndex: number) => {\n const context: GridResponsiveCardContext<TRow> = { $implicit: row, row, index: rowIndex };\n const viewRef = adapter.createTrackedEmbeddedView(template, context);\n const container = document.createElement('div');\n viewRef.rootNodes.forEach((node: Node) => container.appendChild(node));\n return container;\n };\n});\n\n// Wire <tbw-grid-responsive-card> Angular templates into the ResponsivePlugin\n// once content templates are registered. Runs from `Grid.ngAfterContentInit`\n// via the template-bridge registry.\nregisterTemplateBridge(({ grid, adapter }) => {\n // Only act when the user actually placed a <tbw-grid-responsive-card> in light DOM.\n const cardElement = grid.querySelector('tbw-grid-responsive-card');\n if (!cardElement) return;\n\n // Build a card renderer from the Angular template.\n const cardRenderer = adapter.createResponsiveCardRenderer(grid);\n if (!cardRenderer) return;\n\n // The plugin must already have been attached (via [responsive] input,\n // gridConfig.features.responsive, or gridConfig.plugins). Use the runtime\n // lookup so we don't miss plugins instantiated from `gridConfig.features`,\n // which never appear in `gridConfig.plugins`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const existingPlugin = (grid as any).getPluginByName?.('responsive') as ResponsivePluginLike | undefined;\n\n if (!existingPlugin) {\n console.warn(\n '[tbw-grid-angular] <tbw-grid-responsive-card> found but ResponsivePlugin is not configured.\\n' +\n 'Add the [responsive] input, set gridConfig.features.responsive, or include\\n' +\n 'ResponsivePlugin in gridConfig.plugins:\\n\\n' +\n ' <tbw-grid [responsive]=\"{ breakpoint: 600 }\">...</tbw-grid>\\n\\n' +\n 'or:\\n\\n' +\n ' gridConfig = { features: { responsive: { breakpoint: 600 } } };',\n );\n return;\n }\n\n existingPlugin.setCardRenderer?.(cardRenderer as (row: unknown, rowIndex: number) => HTMLElement);\n});\n\n/**\n * Bridge any Angular component class used as `responsive.cardRenderer` to a\n * plain `(row, rowIndex, column?) => HTMLElement` function before the core\n * plugin factory consumes the config. Without this preprocessor, a component\n * class passed as `cardRenderer` would be invoked as a function at render\n * time and crash. Light-DOM `<tbw-grid-responsive-card>` templates continue\n * to win via the post-mount template bridge above.\n *\n * @since 1.7.1\n */\nregisterFeatureConfigPreprocessor('responsive', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as ResponsivePluginConfig;\n if (!isComponentClass(cfg.cardRenderer)) return config;\n\n const componentClass = cfg.cardRenderer as Type<unknown>;\n const mount = adapter.mountComponentRenderer<{ row: unknown; rowIndex: number; column?: unknown }>(\n componentClass,\n (ctx) => ({ row: ctx.row, rowIndex: ctx.rowIndex, column: ctx.column }),\n );\n const cached = new Map<unknown, HTMLElement>();\n const cardRenderer: NonNullable<ResponsivePluginConfig['cardRenderer']> = (row, rowIndex, column) => {\n const existing = cached.get(row);\n if (existing) return existing;\n const { hostElement } = mount({ row, rowIndex, column });\n cached.set(row, hostElement);\n return hostElement;\n };\n return { ...cfg, cardRenderer };\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toolbox-web-grid-angular-features-responsive.mjs","sources":["../../../../libs/grid-angular/features/responsive/src/grid-responsive-card.directive.ts","../../../../libs/grid-angular/features/responsive/src/grid-responsive.directive.ts","../../../../libs/grid-angular/features/responsive/src/index.ts","../../../../libs/grid-angular/features/responsive/src/toolbox-web-grid-angular-features-responsive.ts"],"sourcesContent":["import { contentChild, Directive, effect, ElementRef, inject, input, TemplateRef } from '@angular/core';\n\n/**\n * Context object passed to the responsive card template.\n *\n * @template TRow - The type of row data\n *\n * @example\n * ```html\n * <tbw-grid-responsive-card>\n * <ng-template let-row let-index=\"index\">\n * <div class=\"card-content\">\n * <span>{{ row.name }}</span>\n * <span>Row #{{ index }}</span>\n * </div>\n * </ng-template>\n * </tbw-grid-responsive-card>\n * ```\n * @since 0.4.0\n */\nexport interface GridResponsiveCardContext<TRow = unknown> {\n /**\n * The row data (available as `let-row` or `let-myVar`).\n */\n $implicit: TRow;\n\n /**\n * The row data (explicit access via `let-row=\"row\"`).\n */\n row: TRow;\n\n /**\n * The row index (zero-based).\n */\n index: number;\n}\n\n/**\n * Registry to store responsive card templates by grid element.\n * Used by AngularGridAdapter to create card renderers.\n */\nexport const responsiveCardTemplateRegistry = new Map<HTMLElement, TemplateRef<GridResponsiveCardContext>>();\n\n/**\n * Retrieves the responsive card template for a grid element.\n *\n * @param gridElement - The grid element to look up\n * @returns The template reference or undefined if not found\n * @since 0.4.0\n */\nexport function getResponsiveCardTemplate(\n gridElement: HTMLElement,\n): TemplateRef<GridResponsiveCardContext> | undefined {\n // Find the tbw-grid-responsive-card element inside the grid\n const cardElement = gridElement.querySelector('tbw-grid-responsive-card');\n if (!cardElement) return undefined;\n return responsiveCardTemplateRegistry.get(cardElement as HTMLElement);\n}\n\n/**\n * Directive for providing custom Angular templates for responsive card layout.\n *\n * Use this directive to define how each row should render when the grid\n * is in responsive/mobile mode. The template receives the row data and index.\n *\n * ## Usage\n *\n * ```html\n * <tbw-grid [rows]=\"employees\">\n * <tbw-grid-responsive-card>\n * <ng-template let-employee let-idx=\"index\">\n * <div class=\"employee-card\">\n * <img [src]=\"employee.avatar\" alt=\"\">\n * <div class=\"info\">\n * <strong>{{ employee.name }}</strong>\n * <span>{{ employee.department }}</span>\n * </div>\n * </div>\n * </ng-template>\n * </tbw-grid-responsive-card>\n * </tbw-grid>\n * ```\n *\n * ## Important Notes\n *\n * - The ResponsivePlugin must be added to your grid config\n * - The Grid directive will automatically configure the plugin's cardRenderer\n * - Template context provides `$implicit` (row), `row`, and `index`\n *\n * @see ResponsivePlugin\n * @category Directive\n * @since 0.4.0\n */\n@Directive({\n selector: 'tbw-grid-responsive-card',\n})\nexport class GridResponsiveCard<TRow = unknown> {\n private elementRef = inject(ElementRef<HTMLElement>);\n\n /**\n * Card row height in pixels. Use `'auto'` for dynamic height based on content.\n *\n * Mirrors to the `card-row-height` attribute on the underlying\n * `<tbw-grid-responsive-card>` element which the ResponsivePlugin reads.\n *\n * @default 'auto'\n */\n cardRowHeight = input<number | 'auto'>();\n\n /**\n * The ng-template containing the card content.\n */\n template = contentChild(TemplateRef<GridResponsiveCardContext<TRow>>);\n\n /**\n * Effect that registers the template when it becomes available.\n */\n private onTemplateReceived = effect(() => {\n const template = this.template();\n if (template) {\n responsiveCardTemplateRegistry.set(\n this.elementRef.nativeElement,\n template as TemplateRef<GridResponsiveCardContext>,\n );\n }\n });\n\n /**\n * Effect that mirrors the `cardRowHeight` input to the kebab-cased attribute\n * read by the ResponsivePlugin.\n */\n private onCardRowHeightChange = effect(() => {\n const value = this.cardRowHeight();\n const element = this.elementRef.nativeElement;\n if (value === undefined) {\n element.removeAttribute('card-row-height');\n return;\n }\n element.setAttribute('card-row-height', value === 'auto' ? 'auto' : String(value));\n });\n\n /**\n * Type guard for template context inference.\n */\n static ngTemplateContextGuard<T>(\n _directive: GridResponsiveCard<T>,\n context: unknown,\n ): context is GridResponsiveCardContext<T> {\n return true;\n }\n}\n","/**\n * `GridResponsiveDirective` — owns `[responsive]` and `(responsiveChange)`\n * on `<tbw-grid>`. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, OnInit, output, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { claimEvent, registerFeatureClaim, unclaimEvent, unregisterFeatureClaim } from '@toolbox-web/grid-angular';\nimport type {\n ResponsivePluginConfig as CoreResponsivePluginConfig,\n ResponsiveChangeDetail,\n} from '@toolbox-web/grid/plugins/responsive';\n\n/**\n * Angular-specific responsive config that allows an Angular component class\n * as `cardRenderer`.\n *\n * Extends the core `ResponsivePluginConfig` to accept a `Type<unknown>` for\n * `cardRenderer` in addition to the vanilla\n * `(row, rowIndex, column?) => HTMLElement` signature. Bridging to vanilla\n * DOM is handled by the side-effect import\n * `@toolbox-web/grid-angular/features/responsive`.\n *\n * Re-exported from the feature entry under the same name as the core type\n * so Angular consumers see a single canonical `ResponsivePluginConfig` from\n * `@toolbox-web/grid-angular/features/responsive`.\n *\n * @since 1.7.1\n */\nexport type ResponsivePluginConfig<TRow = unknown> = Omit<CoreResponsivePluginConfig<TRow>, 'cardRenderer'> & {\n cardRenderer?: CoreResponsivePluginConfig<TRow>['cardRenderer'] | Type<unknown>;\n};\n\n/**\n * Owns the binding(s) `[responsive], [responsiveChange]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\n@Directive({\n selector: 'tbw-grid[responsive], tbw-grid[responsiveChange]',\n standalone: true,\n})\nexport class GridResponsiveDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly responsive = input<boolean | ResponsivePluginConfig>();\n readonly responsiveChange = output<ResponsiveChangeDetail>();\n\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'responsive', () => this.responsive());\n claimEvent(grid, 'responsive-change');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event): void => this.responsiveChange.emit((e as CustomEvent<ResponsiveChangeDetail>).detail);\n grid.addEventListener('responsive-change', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('responsive-change', this.listener);\n this.listener = undefined;\n }\n unregisterFeatureClaim(grid, 'responsive');\n unclaimEvent(grid, 'responsive-change');\n }\n}\n","/**\n * Responsive feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `[responsive]` input on the `Grid`\n * directive AND to wire `<tbw-grid-responsive-card>` Angular templates into\n * the ResponsivePlugin's `cardRenderer`.\n *\n * @example\n * ```typescript\n * // In your bootstrap (e.g. main.ts or app.component.ts):\n * import '@toolbox-web/grid-angular/features/responsive';\n * ```\n *\n * ```html\n * <tbw-grid [responsive]=\"{ breakpoint: 768 }\">\n * <tbw-grid-responsive-card>\n * <ng-template let-row>...</ng-template>\n * </tbw-grid-responsive-card>\n * </tbw-grid>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Type } from '@angular/core';\nimport {\n isComponentClass,\n registerFeatureConfigPreprocessor,\n registerResponsiveCardRendererBridge,\n registerTemplateBridge,\n type GridAdapter,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/responsive';\nimport { getResponsiveCardTemplate, type GridResponsiveCardContext } from './grid-responsive-card.directive';\nimport type { ResponsivePluginConfig } from './grid-responsive.directive';\nexport { GridResponsiveDirective } from './grid-responsive.directive';\nexport type { ResponsivePluginConfig } from './grid-responsive.directive';\nexport type { _Augmentation as _ResponsiveAugmentation } from '@toolbox-web/grid/features/responsive';\n\n// ---------------------------------------------------------------------------\n// Responsive-owned directive + helpers. These physically live in this\n// secondary entry (the runtime behaviour lives here too).\n// ---------------------------------------------------------------------------\nexport { getResponsiveCardTemplate, GridResponsiveCard } from './grid-responsive-card.directive';\nexport type { GridResponsiveCardContext } from './grid-responsive-card.directive';\n\n/**\n * Subset of `ResponsivePlugin` we touch from the bridge. Avoids importing\n * the plugin class itself.\n */\ninterface ResponsivePluginLike {\n setCardRenderer?: (renderer: (row: unknown, rowIndex: number) => HTMLElement) => void;\n}\n\n// Install the row renderer bridge on the adapter. This is what\n// `adapter.createResponsiveCardRenderer(grid)` and\n// `adapter.parseResponsiveCardElement(el)` delegate to. Without this import,\n// both methods return undefined.\nregisterResponsiveCardRendererBridge(<TRow = unknown>(gridElement: HTMLElement, adapter: GridAdapter) => {\n // Type inferred from `getResponsiveCardTemplate` (same package instance as\n // `adapter`), not from a local `import type { TemplateRef } from '@angular/core'`\n // — the latter resolves through Bun's `.bun/` cache during ng-packagr build\n // and produces a brand-incompatible TemplateRef vs the built adapter `.d.ts`.\n const template = getResponsiveCardTemplate(gridElement);\n if (!template) return undefined;\n\n return (row: TRow, rowIndex: number) => {\n const context: GridResponsiveCardContext<TRow> = { $implicit: row, row, index: rowIndex };\n const viewRef = adapter.createTrackedEmbeddedView(template, context);\n const container = document.createElement('div');\n viewRef.rootNodes.forEach((node: Node) => container.appendChild(node));\n return container;\n };\n});\n\n// Wire <tbw-grid-responsive-card> Angular templates into the ResponsivePlugin\n// once content templates are registered. Runs from `Grid.ngAfterContentInit`\n// via the template-bridge registry.\nregisterTemplateBridge(({ grid, adapter }) => {\n // Only act when the user actually placed a <tbw-grid-responsive-card> in light DOM.\n const cardElement = grid.querySelector('tbw-grid-responsive-card');\n if (!cardElement) return;\n\n // Build a card renderer from the Angular template.\n const cardRenderer = adapter.createResponsiveCardRenderer(grid);\n if (!cardRenderer) return;\n\n // The plugin must already have been attached (via [responsive] input,\n // gridConfig.features.responsive, or gridConfig.plugins). Use the runtime\n // lookup so we don't miss plugins instantiated from `gridConfig.features`,\n // which never appear in `gridConfig.plugins`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const existingPlugin = (grid as any).getPluginByName?.('responsive') as ResponsivePluginLike | undefined;\n\n if (!existingPlugin) {\n console.warn(\n '[tbw-grid-angular] <tbw-grid-responsive-card> found but ResponsivePlugin is not configured.\\n' +\n 'Add the [responsive] input, set gridConfig.features.responsive, or include\\n' +\n 'ResponsivePlugin in gridConfig.plugins:\\n\\n' +\n ' <tbw-grid [responsive]=\"{ breakpoint: 600 }\">...</tbw-grid>\\n\\n' +\n 'or:\\n\\n' +\n ' gridConfig = { features: { responsive: { breakpoint: 600 } } };',\n );\n return;\n }\n\n existingPlugin.setCardRenderer?.(cardRenderer as (row: unknown, rowIndex: number) => HTMLElement);\n});\n\n/**\n * Bridge any Angular component class used as `responsive.cardRenderer` to a\n * plain `(row, rowIndex, column?) => HTMLElement` function before the core\n * plugin factory consumes the config. Without this preprocessor, a component\n * class passed as `cardRenderer` would be invoked as a function at render\n * time and crash. Light-DOM `<tbw-grid-responsive-card>` templates continue\n * to win via the post-mount template bridge above.\n *\n * @since 1.7.1\n */\nregisterFeatureConfigPreprocessor('responsive', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as ResponsivePluginConfig;\n if (!isComponentClass(cfg.cardRenderer)) return config;\n\n const componentClass = cfg.cardRenderer as Type<unknown>;\n const mount = adapter.mountComponentRenderer<{ row: unknown; rowIndex: number; column?: unknown }>(\n componentClass,\n (ctx) => ({ row: ctx.row, rowIndex: ctx.rowIndex, column: ctx.column }),\n );\n const cached = new Map<unknown, HTMLElement>();\n const cardRenderer: NonNullable<ResponsivePluginConfig['cardRenderer']> = (row, rowIndex, column) => {\n const existing = cached.get(row);\n if (existing) return existing;\n const { hostElement } = mount({ row, rowIndex, column });\n cached.set(row, hostElement);\n return hostElement;\n };\n return { ...cfg, cardRenderer };\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,430 @@
|
|
|
1
|
+
import { registerToolPanelRendererBridge } from '@toolbox-web/grid-angular';
|
|
1
2
|
import '@toolbox-web/grid/features/shell';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { inject, ElementRef, input, contentChild, TemplateRef, effect, Directive, ViewContainerRef, DestroyRef, afterNextRender } from '@angular/core';
|
|
5
|
+
|
|
6
|
+
// Global registry mapping DOM elements to their templates
|
|
7
|
+
const toolPanelTemplateRegistry = new Map();
|
|
8
|
+
/**
|
|
9
|
+
* Gets the tool panel template registered for a given tool panel element.
|
|
10
|
+
* Used by AngularGridAdapter to retrieve templates at render time.
|
|
11
|
+
*/
|
|
12
|
+
function getToolPanelTemplate(panelElement) {
|
|
13
|
+
return toolPanelTemplateRegistry.get(panelElement);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Gets all tool panel elements with registered templates within a grid element.
|
|
17
|
+
*/
|
|
18
|
+
function getToolPanelElements(gridElement) {
|
|
19
|
+
const panelElements = gridElement.querySelectorAll('tbw-grid-tool-panel');
|
|
20
|
+
return Array.from(panelElements).filter((el) => toolPanelTemplateRegistry.has(el));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Directive that captures an `<ng-template>` for use as a custom tool panel.
|
|
24
|
+
*
|
|
25
|
+
* This enables declarative Angular component usage for tool panels
|
|
26
|
+
* that appear in the grid's side panel.
|
|
27
|
+
*
|
|
28
|
+
* ## Usage
|
|
29
|
+
*
|
|
30
|
+
* ```html
|
|
31
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
32
|
+
* <tbw-grid-tool-panel
|
|
33
|
+
* id="quick-filters"
|
|
34
|
+
* title="Quick Filters"
|
|
35
|
+
* icon="🔍"
|
|
36
|
+
* tooltip="Apply quick filters"
|
|
37
|
+
* [order]="10"
|
|
38
|
+
* >
|
|
39
|
+
* <ng-template let-grid>
|
|
40
|
+
* <app-quick-filters [grid]="grid" />
|
|
41
|
+
* </ng-template>
|
|
42
|
+
* </tbw-grid-tool-panel>
|
|
43
|
+
* </tbw-grid>
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* The template context provides:
|
|
47
|
+
* - `$implicit` / `grid`: The grid element reference
|
|
48
|
+
*
|
|
49
|
+
* ### Attributes
|
|
50
|
+
*
|
|
51
|
+
* - `id` (required): Unique identifier for the panel
|
|
52
|
+
* - `title` (required): Panel title shown in accordion header
|
|
53
|
+
* - `icon`: Icon for accordion section header (emoji or text)
|
|
54
|
+
* - `tooltip`: Tooltip for accordion section header
|
|
55
|
+
* - `order`: Panel order priority (lower = first, default: 100)
|
|
56
|
+
*
|
|
57
|
+
* Import the directive in your component:
|
|
58
|
+
*
|
|
59
|
+
* ```typescript
|
|
60
|
+
* import { GridToolPanel } from '@toolbox-web/grid-angular/features/shell';
|
|
61
|
+
*
|
|
62
|
+
* @Component({
|
|
63
|
+
* imports: [GridToolPanel],
|
|
64
|
+
* // ...
|
|
65
|
+
* })
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```html
|
|
70
|
+
* <tbw-grid [rows]="rows">
|
|
71
|
+
* <tbw-grid-tool-panel id="quick-filters" title="Quick Filters" icon="\uD83D\uDD0D">
|
|
72
|
+
* <ng-template let-grid>
|
|
73
|
+
* <app-quick-filters [grid]="grid" />
|
|
74
|
+
* </ng-template>
|
|
75
|
+
* </tbw-grid-tool-panel>
|
|
76
|
+
* </tbw-grid>
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @category Directive
|
|
80
|
+
* @since 0.1.0
|
|
81
|
+
*/
|
|
82
|
+
class GridToolPanel {
|
|
83
|
+
elementRef = inject((ElementRef));
|
|
84
|
+
/** Unique panel identifier (required) */
|
|
85
|
+
id = input.required({ ...(ngDevMode ? { debugName: "id" } : /* istanbul ignore next */ {}), alias: 'id' });
|
|
86
|
+
/** Panel title shown in accordion header (required) */
|
|
87
|
+
title = input.required({ ...(ngDevMode ? { debugName: "title" } : /* istanbul ignore next */ {}), alias: 'title' });
|
|
88
|
+
/** Icon for accordion section header (emoji or text) */
|
|
89
|
+
icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
90
|
+
/** Tooltip for accordion section header */
|
|
91
|
+
tooltip = input(...(ngDevMode ? [undefined, { debugName: "tooltip" }] : /* istanbul ignore next */ []));
|
|
92
|
+
/** Panel order priority (lower = first, default: 100) */
|
|
93
|
+
order = input(100, ...(ngDevMode ? [{ debugName: "order" }] : /* istanbul ignore next */ []));
|
|
94
|
+
/**
|
|
95
|
+
* Query for the ng-template content child.
|
|
96
|
+
*/
|
|
97
|
+
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
98
|
+
/** Effect that triggers when the template is available */
|
|
99
|
+
onTemplateReceived = effect(() => {
|
|
100
|
+
const template = this.template();
|
|
101
|
+
const element = this.elementRef.nativeElement;
|
|
102
|
+
if (template) {
|
|
103
|
+
// Set attributes from inputs (for light DOM parsing to read)
|
|
104
|
+
element.setAttribute('id', this.id());
|
|
105
|
+
element.setAttribute('title', this.title());
|
|
106
|
+
const icon = this.icon();
|
|
107
|
+
if (icon)
|
|
108
|
+
element.setAttribute('icon', icon);
|
|
109
|
+
const tooltip = this.tooltip();
|
|
110
|
+
if (tooltip)
|
|
111
|
+
element.setAttribute('tooltip', tooltip);
|
|
112
|
+
element.setAttribute('order', String(this.order()));
|
|
113
|
+
// Register the template for this element
|
|
114
|
+
toolPanelTemplateRegistry.set(element, template);
|
|
115
|
+
}
|
|
116
|
+
}, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
|
|
117
|
+
/**
|
|
118
|
+
* Static type guard for template context.
|
|
119
|
+
* Enables type inference in templates.
|
|
120
|
+
*/
|
|
121
|
+
static ngTemplateContextGuard(dir, ctx) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridToolPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
125
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridToolPanel, isStandalone: true, selector: "tbw-grid-tool-panel", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, order: { classPropertyName: "order", publicName: "order", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
126
|
+
}
|
|
127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridToolPanel, decorators: [{
|
|
128
|
+
type: Directive,
|
|
129
|
+
args: [{ selector: 'tbw-grid-tool-panel' }]
|
|
130
|
+
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], order: [{ type: i0.Input, args: [{ isSignal: true, alias: "order", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
131
|
+
|
|
132
|
+
let autoIdCounter$1 = 0;
|
|
133
|
+
/**
|
|
134
|
+
* Declarative wrapper around the grid's imperative
|
|
135
|
+
* {@link ShellPlugin.registerHeaderContent} API.
|
|
136
|
+
*
|
|
137
|
+
* Captures an `<ng-template>` and mounts it as an Angular embedded view into
|
|
138
|
+
* the slot the grid provides for header content. Must be a child of
|
|
139
|
+
* `<tbw-grid>`.
|
|
140
|
+
*
|
|
141
|
+
* ## Usage
|
|
142
|
+
*
|
|
143
|
+
* ```html
|
|
144
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
145
|
+
* <tbw-grid-header-content id="calendar-nav" [order]="0">
|
|
146
|
+
* <ng-template let-grid>
|
|
147
|
+
* <app-header-nav [year]="year()" (yearChange)="setYear($event)" />
|
|
148
|
+
* </ng-template>
|
|
149
|
+
* </tbw-grid-header-content>
|
|
150
|
+
* </tbw-grid>
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* @category Directive
|
|
154
|
+
* @since 1.7.0
|
|
155
|
+
*/
|
|
156
|
+
class GridHeaderContent {
|
|
157
|
+
elementRef = inject((ElementRef));
|
|
158
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
159
|
+
destroyRef = inject(DestroyRef);
|
|
160
|
+
/** Unique identifier for this header content entry. Optional — defaults to a stable generated id. */
|
|
161
|
+
id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
162
|
+
/** Render order priority. Lower values appear first. @default 100 */
|
|
163
|
+
order = input(100, ...(ngDevMode ? [{ debugName: "order" }] : /* istanbul ignore next */ []));
|
|
164
|
+
/** The template to mount into the grid's header content slot. */
|
|
165
|
+
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
166
|
+
viewRef = null;
|
|
167
|
+
registeredId = null;
|
|
168
|
+
resolvedId = `tbw-header-content-${++autoIdCounter$1}`;
|
|
169
|
+
destroyed = false;
|
|
170
|
+
constructor() {
|
|
171
|
+
afterNextRender(() => {
|
|
172
|
+
void this.register();
|
|
173
|
+
});
|
|
174
|
+
this.destroyRef.onDestroy(() => {
|
|
175
|
+
this.destroyed = true;
|
|
176
|
+
this.unregister();
|
|
177
|
+
});
|
|
178
|
+
// Re-register when id or order changes after mount.
|
|
179
|
+
effect(() => {
|
|
180
|
+
const nextId = this.id() ?? this.resolvedId;
|
|
181
|
+
const nextOrder = this.order();
|
|
182
|
+
if (this.registeredId && this.registeredId !== nextId) {
|
|
183
|
+
this.unregister();
|
|
184
|
+
void this.register();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (this.registeredId && nextOrder !== this.lastOrder) {
|
|
188
|
+
this.unregister();
|
|
189
|
+
void this.register();
|
|
190
|
+
}
|
|
191
|
+
this.lastOrder = nextOrder;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
lastOrder;
|
|
195
|
+
async register() {
|
|
196
|
+
const grid = this.findGrid();
|
|
197
|
+
if (!grid)
|
|
198
|
+
return;
|
|
199
|
+
try {
|
|
200
|
+
await grid.ready?.();
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (this.destroyed)
|
|
206
|
+
return;
|
|
207
|
+
const template = this.template();
|
|
208
|
+
const id = this.id() ?? this.resolvedId;
|
|
209
|
+
const order = this.order();
|
|
210
|
+
const def = {
|
|
211
|
+
id,
|
|
212
|
+
order,
|
|
213
|
+
render: (container) => {
|
|
214
|
+
if (!template)
|
|
215
|
+
return undefined;
|
|
216
|
+
// Sticky container: the shell may re-invoke `render` with the SAME
|
|
217
|
+
// container across refreshes. If our embedded view is still attached
|
|
218
|
+
// inside it, the previous render is live and this is a refresh — do
|
|
219
|
+
// nothing (no-op cleanup preserves child state).
|
|
220
|
+
const firstNode = this.viewRef?.rootNodes[0];
|
|
221
|
+
if (this.viewRef && firstNode && container.contains(firstNode)) {
|
|
222
|
+
return () => {
|
|
223
|
+
/* intentionally empty */
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
// Fresh container (first render or container was replaced) — destroy
|
|
227
|
+
// any stale view, then build a new one.
|
|
228
|
+
if (this.viewRef) {
|
|
229
|
+
this.viewRef.destroy();
|
|
230
|
+
this.viewRef = null;
|
|
231
|
+
}
|
|
232
|
+
this.viewRef = this.viewContainerRef.createEmbeddedView(template, {
|
|
233
|
+
$implicit: grid,
|
|
234
|
+
grid,
|
|
235
|
+
});
|
|
236
|
+
this.viewRef.detectChanges();
|
|
237
|
+
for (const node of this.viewRef.rootNodes) {
|
|
238
|
+
container.appendChild(node);
|
|
239
|
+
}
|
|
240
|
+
// No-op cleanup: the grid may call this between re-renders before
|
|
241
|
+
// invoking `render` again with the SAME container. Tearing the view
|
|
242
|
+
// down here would destroy any internal state in the projected
|
|
243
|
+
// template on every shell refresh. Teardown happens in `unregister`
|
|
244
|
+
// (component destroy / id / order change).
|
|
245
|
+
return () => {
|
|
246
|
+
/* intentionally empty */
|
|
247
|
+
};
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
// Route through the shell plugin (#370). The shell is opt-in at v3 —
|
|
251
|
+
// content registers only when a shell plugin is present.
|
|
252
|
+
grid.getPluginByName?.('shell')?.registerHeaderContent(def);
|
|
253
|
+
this.registeredId = id;
|
|
254
|
+
}
|
|
255
|
+
unregister() {
|
|
256
|
+
const grid = this.findGrid();
|
|
257
|
+
if (grid && this.registeredId) {
|
|
258
|
+
grid.getPluginByName?.('shell')?.unregisterHeaderContent(this.registeredId);
|
|
259
|
+
}
|
|
260
|
+
this.registeredId = null;
|
|
261
|
+
if (this.viewRef) {
|
|
262
|
+
this.viewRef.destroy();
|
|
263
|
+
this.viewRef = null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
findGrid() {
|
|
267
|
+
const host = this.elementRef.nativeElement;
|
|
268
|
+
// Use the stable `[data-tbw-grid]` attribute (set by core on connect) rather
|
|
269
|
+
// than the literal `tbw-grid` tag, so a version-suffixed grid host (e.g.
|
|
270
|
+
// `<tbw-grid-v2-15-0>`) is still found. See the multi-version guide.
|
|
271
|
+
const grid = host.closest('[data-tbw-grid]');
|
|
272
|
+
return grid;
|
|
273
|
+
}
|
|
274
|
+
/** Type guard for template context inference. */
|
|
275
|
+
static ngTemplateContextGuard(_dir, ctx) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridHeaderContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
279
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridHeaderContent, isStandalone: true, selector: "tbw-grid-header-content", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, order: { classPropertyName: "order", publicName: "order", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
280
|
+
}
|
|
281
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridHeaderContent, decorators: [{
|
|
282
|
+
type: Directive,
|
|
283
|
+
args: [{ selector: 'tbw-grid-header-content', standalone: true }]
|
|
284
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], order: [{ type: i0.Input, args: [{ isSignal: true, alias: "order", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
285
|
+
|
|
286
|
+
let autoIdCounter = 0;
|
|
287
|
+
/**
|
|
288
|
+
* Declarative wrapper around the grid's imperative
|
|
289
|
+
* {@link ShellPlugin.registerToolbarContent} API.
|
|
290
|
+
*
|
|
291
|
+
* Captures an `<ng-template>` and mounts it as an Angular embedded view into
|
|
292
|
+
* the slot the grid provides for toolbar content. Must be a child of
|
|
293
|
+
* `<tbw-grid>`.
|
|
294
|
+
*
|
|
295
|
+
* Prefer this over `<tbw-grid-tool-buttons>` (light DOM) when you need
|
|
296
|
+
* Angular template bindings to component state. Use the light-DOM form for
|
|
297
|
+
* static markup that should be moved verbatim into the toolbar.
|
|
298
|
+
*
|
|
299
|
+
* ## Usage
|
|
300
|
+
*
|
|
301
|
+
* ```html
|
|
302
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
303
|
+
* <tbw-grid-toolbar-content id="calendar-nav" [order]="0">
|
|
304
|
+
* <ng-template let-grid>
|
|
305
|
+
* <app-toolbar-nav (prev)="prev()" (today)="today()" (next)="next()" />
|
|
306
|
+
* </ng-template>
|
|
307
|
+
* </tbw-grid-toolbar-content>
|
|
308
|
+
* </tbw-grid>
|
|
309
|
+
* ```
|
|
310
|
+
*
|
|
311
|
+
* @category Directive
|
|
312
|
+
* @since 1.7.0
|
|
313
|
+
*/
|
|
314
|
+
class GridToolbarContent {
|
|
315
|
+
elementRef = inject((ElementRef));
|
|
316
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
317
|
+
destroyRef = inject(DestroyRef);
|
|
318
|
+
id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
319
|
+
order = input(100, ...(ngDevMode ? [{ debugName: "order" }] : /* istanbul ignore next */ []));
|
|
320
|
+
template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
321
|
+
viewRef = null;
|
|
322
|
+
registeredId = null;
|
|
323
|
+
resolvedId = `tbw-toolbar-content-${++autoIdCounter}`;
|
|
324
|
+
lastOrder;
|
|
325
|
+
destroyed = false;
|
|
326
|
+
constructor() {
|
|
327
|
+
afterNextRender(() => {
|
|
328
|
+
void this.register();
|
|
329
|
+
});
|
|
330
|
+
this.destroyRef.onDestroy(() => {
|
|
331
|
+
this.destroyed = true;
|
|
332
|
+
this.unregister();
|
|
333
|
+
});
|
|
334
|
+
effect(() => {
|
|
335
|
+
const nextId = this.id() ?? this.resolvedId;
|
|
336
|
+
const nextOrder = this.order();
|
|
337
|
+
if (this.registeredId && this.registeredId !== nextId) {
|
|
338
|
+
this.unregister();
|
|
339
|
+
void this.register();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (this.registeredId && nextOrder !== this.lastOrder) {
|
|
343
|
+
this.unregister();
|
|
344
|
+
void this.register();
|
|
345
|
+
}
|
|
346
|
+
this.lastOrder = nextOrder;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
async register() {
|
|
350
|
+
const grid = this.findGrid();
|
|
351
|
+
if (!grid)
|
|
352
|
+
return;
|
|
353
|
+
try {
|
|
354
|
+
await grid.ready?.();
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (this.destroyed)
|
|
360
|
+
return;
|
|
361
|
+
const template = this.template();
|
|
362
|
+
const id = this.id() ?? this.resolvedId;
|
|
363
|
+
const order = this.order();
|
|
364
|
+
const def = {
|
|
365
|
+
id,
|
|
366
|
+
order,
|
|
367
|
+
render: (container) => {
|
|
368
|
+
if (!template)
|
|
369
|
+
return undefined;
|
|
370
|
+
// Sticky container: see grid-header-content.directive.ts for rationale.
|
|
371
|
+
const firstNode = this.viewRef?.rootNodes[0];
|
|
372
|
+
if (this.viewRef && firstNode && container.contains(firstNode)) {
|
|
373
|
+
return () => {
|
|
374
|
+
/* intentionally empty */
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
if (this.viewRef) {
|
|
378
|
+
this.viewRef.destroy();
|
|
379
|
+
this.viewRef = null;
|
|
380
|
+
}
|
|
381
|
+
this.viewRef = this.viewContainerRef.createEmbeddedView(template, {
|
|
382
|
+
$implicit: grid,
|
|
383
|
+
grid,
|
|
384
|
+
});
|
|
385
|
+
this.viewRef.detectChanges();
|
|
386
|
+
for (const node of this.viewRef.rootNodes) {
|
|
387
|
+
container.appendChild(node);
|
|
388
|
+
}
|
|
389
|
+
// No-op cleanup — see comment in grid-header-content.directive.ts.
|
|
390
|
+
return () => {
|
|
391
|
+
/* intentionally empty */
|
|
392
|
+
};
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
// Route through the shell plugin (#370). The shell is opt-in at v3 —
|
|
396
|
+
// content registers only when a shell plugin is present.
|
|
397
|
+
grid.getPluginByName?.('shell')?.registerToolbarContent(def);
|
|
398
|
+
this.registeredId = id;
|
|
399
|
+
}
|
|
400
|
+
unregister() {
|
|
401
|
+
const grid = this.findGrid();
|
|
402
|
+
if (grid && this.registeredId) {
|
|
403
|
+
grid.getPluginByName?.('shell')?.unregisterToolbarContent(this.registeredId);
|
|
404
|
+
}
|
|
405
|
+
this.registeredId = null;
|
|
406
|
+
if (this.viewRef) {
|
|
407
|
+
this.viewRef.destroy();
|
|
408
|
+
this.viewRef = null;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
findGrid() {
|
|
412
|
+
const host = this.elementRef.nativeElement;
|
|
413
|
+
// Use the stable `[data-tbw-grid]` attribute (set by core on connect) rather
|
|
414
|
+
// than the literal `tbw-grid` tag, so a version-suffixed grid host (e.g.
|
|
415
|
+
// `<tbw-grid-v2-15-0>`) is still found. See the multi-version guide.
|
|
416
|
+
return host.closest('[data-tbw-grid]');
|
|
417
|
+
}
|
|
418
|
+
static ngTemplateContextGuard(_dir, ctx) {
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridToolbarContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
422
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridToolbarContent, isStandalone: true, selector: "tbw-grid-toolbar-content", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, order: { classPropertyName: "order", publicName: "order", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
|
|
423
|
+
}
|
|
424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridToolbarContent, decorators: [{
|
|
425
|
+
type: Directive,
|
|
426
|
+
args: [{ selector: 'tbw-grid-toolbar-content', standalone: true }]
|
|
427
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], order: [{ type: i0.Input, args: [{ isSignal: true, alias: "order", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
2
428
|
|
|
3
429
|
/**
|
|
4
430
|
* Shell feature for @toolbox-web/grid-angular
|
|
@@ -25,8 +451,34 @@ import '@toolbox-web/grid/features/shell';
|
|
|
25
451
|
*
|
|
26
452
|
* @packageDocumentation
|
|
27
453
|
*/
|
|
454
|
+
// Install the tool-panel renderer bridge on the adapter. This is what
|
|
455
|
+
// `adapter.createToolPanelRenderer(element)` delegates to. Without this import,
|
|
456
|
+
// the method returns undefined and light-DOM `<tbw-grid-tool-panel>` Angular
|
|
457
|
+
// templates are never mounted by the core ShellPlugin.
|
|
458
|
+
registerToolPanelRendererBridge((element, adapter) => {
|
|
459
|
+
// Type inferred from `getToolPanelTemplate` (same package instance as the
|
|
460
|
+
// adapter), not from a local `import type { TemplateRef } from '@angular/core'`
|
|
461
|
+
// — the latter resolves through Bun's `.bun/` cache during ng-packagr build
|
|
462
|
+
// and produces a brand-incompatible TemplateRef vs the built adapter `.d.ts`.
|
|
463
|
+
const template = getToolPanelTemplate(element);
|
|
464
|
+
if (!template)
|
|
465
|
+
return undefined;
|
|
466
|
+
// Find the parent grid element for context.
|
|
467
|
+
const gridElement = element.closest('tbw-grid, [data-tbw-grid]');
|
|
468
|
+
return (container) => {
|
|
469
|
+
const context = {
|
|
470
|
+
$implicit: gridElement ?? container,
|
|
471
|
+
grid: gridElement ?? container,
|
|
472
|
+
};
|
|
473
|
+
const viewRef = adapter.createTrackedEmbeddedView(template, context);
|
|
474
|
+
viewRef.rootNodes.forEach((node) => container.appendChild(node));
|
|
475
|
+
return () => viewRef.destroy();
|
|
476
|
+
};
|
|
477
|
+
});
|
|
28
478
|
|
|
29
479
|
/**
|
|
30
480
|
* Generated bundle index. Do not edit.
|
|
31
481
|
*/
|
|
482
|
+
|
|
483
|
+
export { GridHeaderContent, GridToolPanel, GridToolbarContent, getToolPanelElements, getToolPanelTemplate };
|
|
32
484
|
//# sourceMappingURL=toolbox-web-grid-angular-features-shell.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbox-web-grid-angular-features-shell.mjs","sources":["../../../../libs/grid-angular/features/shell/src/index.ts","../../../../libs/grid-angular/features/shell/src/toolbox-web-grid-angular-features-shell.ts"],"sourcesContent":["/**\n * Shell feature for @toolbox-web/grid-angular\n *\n * Import this module to opt the grid shell (header bar + tool panels) into\n * the build. The shell also auto-registers in v2.x (so it is on by default\n * and non-breaking); importing this module makes the opt-in explicit and\n * tree-shakeable for v3, where the auto-register is removed.\n *\n * The shell is configured through `gridConfig` (`features: { shell }` or the\n * `<tbw-grid-header-content>` / `<tbw-grid-toolbar-content>` /\n * `<tbw-grid-tool-panel>` directives), not a boolean input.\n *\n * @example\n * ```typescript\n * // In your bootstrap (e.g. main.ts or app.component.ts):\n * import '@toolbox-web/grid-angular/features/shell';\n * ```\n *\n * ```html\n * <tbw-grid [gridConfig]=\"{ features: { shell: { header: { title: 'Employees' } } } }\">\n * </tbw-grid>\n * ```\n *\n * @packageDocumentation\n */\n\nimport '@toolbox-web/grid/features/shell';\nexport type { _Augmentation as _ShellAugmentation } from '@toolbox-web/grid/features/shell';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;;ACxBH;;AAEG"}
|
|
1
|
+
{"version":3,"file":"toolbox-web-grid-angular-features-shell.mjs","sources":["../../../../libs/grid-angular/features/shell/src/grid-tool-panel.directive.ts","../../../../libs/grid-angular/features/shell/src/grid-header-content.directive.ts","../../../../libs/grid-angular/features/shell/src/grid-toolbar-content.directive.ts","../../../../libs/grid-angular/features/shell/src/index.ts","../../../../libs/grid-angular/features/shell/src/toolbox-web-grid-angular-features-shell.ts"],"sourcesContent":["import { contentChild, Directive, effect, ElementRef, inject, input, TemplateRef } from '@angular/core';\n\n/**\n * Context object passed to the tool panel template.\n * Provides access to grid-related information for the panel content.\n * @since 0.1.0\n */\nexport interface GridToolPanelContext {\n /** The grid element (implicit binding) */\n $implicit: HTMLElement;\n /** The grid element */\n grid: HTMLElement;\n}\n\n// Global registry mapping DOM elements to their templates\nconst toolPanelTemplateRegistry = new Map<HTMLElement, TemplateRef<GridToolPanelContext>>();\n\n/**\n * Gets the tool panel template registered for a given tool panel element.\n * Used by AngularGridAdapter to retrieve templates at render time.\n */\nexport function getToolPanelTemplate(panelElement: HTMLElement): TemplateRef<GridToolPanelContext> | undefined {\n return toolPanelTemplateRegistry.get(panelElement);\n}\n\n/**\n * Gets all tool panel elements with registered templates within a grid element.\n */\nexport function getToolPanelElements(gridElement: HTMLElement): HTMLElement[] {\n const panelElements = gridElement.querySelectorAll('tbw-grid-tool-panel');\n return Array.from(panelElements).filter((el) => toolPanelTemplateRegistry.has(el as HTMLElement)) as HTMLElement[];\n}\n\n/**\n * Directive that captures an `<ng-template>` for use as a custom tool panel.\n *\n * This enables declarative Angular component usage for tool panels\n * that appear in the grid's side panel.\n *\n * ## Usage\n *\n * ```html\n * <tbw-grid [rows]=\"rows\" [gridConfig]=\"config\">\n * <tbw-grid-tool-panel\n * id=\"quick-filters\"\n * title=\"Quick Filters\"\n * icon=\"🔍\"\n * tooltip=\"Apply quick filters\"\n * [order]=\"10\"\n * >\n * <ng-template let-grid>\n * <app-quick-filters [grid]=\"grid\" />\n * </ng-template>\n * </tbw-grid-tool-panel>\n * </tbw-grid>\n * ```\n *\n * The template context provides:\n * - `$implicit` / `grid`: The grid element reference\n *\n * ### Attributes\n *\n * - `id` (required): Unique identifier for the panel\n * - `title` (required): Panel title shown in accordion header\n * - `icon`: Icon for accordion section header (emoji or text)\n * - `tooltip`: Tooltip for accordion section header\n * - `order`: Panel order priority (lower = first, default: 100)\n *\n * Import the directive in your component:\n *\n * ```typescript\n * import { GridToolPanel } from '@toolbox-web/grid-angular/features/shell';\n *\n * @Component({\n * imports: [GridToolPanel],\n * // ...\n * })\n * ```\n *\n * @example\n * ```html\n * <tbw-grid [rows]=\"rows\">\n * <tbw-grid-tool-panel id=\"quick-filters\" title=\"Quick Filters\" icon=\"\\uD83D\\uDD0D\">\n * <ng-template let-grid>\n * <app-quick-filters [grid]=\"grid\" />\n * </ng-template>\n * </tbw-grid-tool-panel>\n * </tbw-grid>\n * ```\n *\n * @category Directive\n * @since 0.1.0\n */\n@Directive({ selector: 'tbw-grid-tool-panel' })\nexport class GridToolPanel {\n private elementRef = inject(ElementRef<HTMLElement>);\n\n /** Unique panel identifier (required) */\n id = input.required<string>({ alias: 'id' });\n\n /** Panel title shown in accordion header (required) */\n title = input.required<string>({ alias: 'title' });\n\n /** Icon for accordion section header (emoji or text) */\n icon = input<string>();\n\n /** Tooltip for accordion section header */\n tooltip = input<string>();\n\n /** Panel order priority (lower = first, default: 100) */\n order = input<number>(100);\n\n /**\n * Query for the ng-template content child.\n */\n template = contentChild(TemplateRef<GridToolPanelContext>);\n\n /** Effect that triggers when the template is available */\n private onTemplateReceived = effect(() => {\n const template = this.template();\n const element = this.elementRef.nativeElement;\n\n if (template) {\n // Set attributes from inputs (for light DOM parsing to read)\n element.setAttribute('id', this.id());\n element.setAttribute('title', this.title());\n\n const icon = this.icon();\n if (icon) element.setAttribute('icon', icon);\n\n const tooltip = this.tooltip();\n if (tooltip) element.setAttribute('tooltip', tooltip);\n\n element.setAttribute('order', String(this.order()));\n\n // Register the template for this element\n toolPanelTemplateRegistry.set(element, template);\n }\n });\n\n /**\n * Static type guard for template context.\n * Enables type inference in templates.\n */\n static ngTemplateContextGuard(dir: GridToolPanel, ctx: unknown): ctx is GridToolPanelContext {\n return true;\n }\n}\n","import {\n afterNextRender,\n contentChild,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n EmbeddedViewRef,\n inject,\n input,\n TemplateRef,\n ViewContainerRef,\n} from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport type { HeaderContentDefinition } from '@toolbox-web/grid/plugins/shell';\n\n/**\n * Context object passed to the header content template.\n * @since 1.7.0\n */\nexport interface GridHeaderContentContext {\n /** The grid element (implicit binding for `let-grid`). */\n $implicit: DataGridElement;\n /** The grid element. */\n grid: DataGridElement;\n}\n\nlet autoIdCounter = 0;\n\n/**\n * Declarative wrapper around the grid's imperative\n * {@link ShellPlugin.registerHeaderContent} API.\n *\n * Captures an `<ng-template>` and mounts it as an Angular embedded view into\n * the slot the grid provides for header content. Must be a child of\n * `<tbw-grid>`.\n *\n * ## Usage\n *\n * ```html\n * <tbw-grid [rows]=\"rows\" [gridConfig]=\"config\">\n * <tbw-grid-header-content id=\"calendar-nav\" [order]=\"0\">\n * <ng-template let-grid>\n * <app-header-nav [year]=\"year()\" (yearChange)=\"setYear($event)\" />\n * </ng-template>\n * </tbw-grid-header-content>\n * </tbw-grid>\n * ```\n *\n * @category Directive\n * @since 1.7.0\n */\n@Directive({ selector: 'tbw-grid-header-content', standalone: true })\nexport class GridHeaderContent {\n private elementRef = inject(ElementRef<HTMLElement>);\n private viewContainerRef = inject(ViewContainerRef);\n private destroyRef = inject(DestroyRef);\n\n /** Unique identifier for this header content entry. Optional — defaults to a stable generated id. */\n id = input<string | undefined>(undefined);\n\n /** Render order priority. Lower values appear first. @default 100 */\n order = input<number>(100);\n\n /** The template to mount into the grid's header content slot. */\n template = contentChild(TemplateRef<GridHeaderContentContext>);\n\n private viewRef: EmbeddedViewRef<GridHeaderContentContext> | null = null;\n private registeredId: string | null = null;\n private resolvedId = `tbw-header-content-${++autoIdCounter}`;\n private destroyed = false;\n\n constructor() {\n afterNextRender(() => {\n void this.register();\n });\n\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n this.unregister();\n });\n\n // Re-register when id or order changes after mount.\n effect(() => {\n const nextId = this.id() ?? this.resolvedId;\n const nextOrder = this.order();\n if (this.registeredId && this.registeredId !== nextId) {\n this.unregister();\n void this.register();\n return;\n }\n if (this.registeredId && nextOrder !== this.lastOrder) {\n this.unregister();\n void this.register();\n }\n this.lastOrder = nextOrder;\n });\n }\n\n private lastOrder: number | undefined;\n\n private async register(): Promise<void> {\n const grid = this.findGrid();\n if (!grid) return;\n try {\n await grid.ready?.();\n } catch {\n return;\n }\n if (this.destroyed) return;\n\n const template = this.template();\n const id = this.id() ?? this.resolvedId;\n const order = this.order();\n\n const def: HeaderContentDefinition = {\n id,\n order,\n render: (container) => {\n if (!template) return undefined;\n // Sticky container: the shell may re-invoke `render` with the SAME\n // container across refreshes. If our embedded view is still attached\n // inside it, the previous render is live and this is a refresh — do\n // nothing (no-op cleanup preserves child state).\n const firstNode = this.viewRef?.rootNodes[0] as Node | undefined;\n if (this.viewRef && firstNode && container.contains(firstNode)) {\n return () => {\n /* intentionally empty */\n };\n }\n // Fresh container (first render or container was replaced) — destroy\n // any stale view, then build a new one.\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n this.viewRef = this.viewContainerRef.createEmbeddedView(template, {\n $implicit: grid,\n grid,\n });\n this.viewRef.detectChanges();\n for (const node of this.viewRef.rootNodes as Node[]) {\n container.appendChild(node);\n }\n // No-op cleanup: the grid may call this between re-renders before\n // invoking `render` again with the SAME container. Tearing the view\n // down here would destroy any internal state in the projected\n // template on every shell refresh. Teardown happens in `unregister`\n // (component destroy / id / order change).\n return () => {\n /* intentionally empty */\n };\n },\n };\n // Route through the shell plugin (#370). The shell is opt-in at v3 —\n // content registers only when a shell plugin is present.\n grid.getPluginByName?.('shell')?.registerHeaderContent(def);\n this.registeredId = id;\n }\n\n private unregister(): void {\n const grid = this.findGrid();\n if (grid && this.registeredId) {\n grid.getPluginByName?.('shell')?.unregisterHeaderContent(this.registeredId);\n }\n this.registeredId = null;\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n }\n\n private findGrid(): DataGridElement | null {\n const host = this.elementRef.nativeElement;\n // Use the stable `[data-tbw-grid]` attribute (set by core on connect) rather\n // than the literal `tbw-grid` tag, so a version-suffixed grid host (e.g.\n // `<tbw-grid-v2-15-0>`) is still found. See the multi-version guide.\n const grid = host.closest('[data-tbw-grid]') as DataGridElement | null;\n return grid;\n }\n\n /** Type guard for template context inference. */\n static ngTemplateContextGuard(_dir: GridHeaderContent, ctx: unknown): ctx is GridHeaderContentContext {\n return true;\n }\n}\n","import {\n afterNextRender,\n contentChild,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n EmbeddedViewRef,\n inject,\n input,\n TemplateRef,\n ViewContainerRef,\n} from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport type { ToolbarContentDefinition } from '@toolbox-web/grid/plugins/shell';\n\n/**\n * Context object passed to the toolbar content template.\n * @since 1.7.0\n */\nexport interface GridToolbarContentContext {\n /** The grid element (implicit binding for `let-grid`). */\n $implicit: DataGridElement;\n /** The grid element. */\n grid: DataGridElement;\n}\n\nlet autoIdCounter = 0;\n\n/**\n * Declarative wrapper around the grid's imperative\n * {@link ShellPlugin.registerToolbarContent} API.\n *\n * Captures an `<ng-template>` and mounts it as an Angular embedded view into\n * the slot the grid provides for toolbar content. Must be a child of\n * `<tbw-grid>`.\n *\n * Prefer this over `<tbw-grid-tool-buttons>` (light DOM) when you need\n * Angular template bindings to component state. Use the light-DOM form for\n * static markup that should be moved verbatim into the toolbar.\n *\n * ## Usage\n *\n * ```html\n * <tbw-grid [rows]=\"rows\" [gridConfig]=\"config\">\n * <tbw-grid-toolbar-content id=\"calendar-nav\" [order]=\"0\">\n * <ng-template let-grid>\n * <app-toolbar-nav (prev)=\"prev()\" (today)=\"today()\" (next)=\"next()\" />\n * </ng-template>\n * </tbw-grid-toolbar-content>\n * </tbw-grid>\n * ```\n *\n * @category Directive\n * @since 1.7.0\n */\n@Directive({ selector: 'tbw-grid-toolbar-content', standalone: true })\nexport class GridToolbarContent {\n private elementRef = inject(ElementRef<HTMLElement>);\n private viewContainerRef = inject(ViewContainerRef);\n private destroyRef = inject(DestroyRef);\n\n id = input<string | undefined>(undefined);\n order = input<number>(100);\n template = contentChild(TemplateRef<GridToolbarContentContext>);\n\n private viewRef: EmbeddedViewRef<GridToolbarContentContext> | null = null;\n private registeredId: string | null = null;\n private resolvedId = `tbw-toolbar-content-${++autoIdCounter}`;\n private lastOrder: number | undefined;\n private destroyed = false;\n\n constructor() {\n afterNextRender(() => {\n void this.register();\n });\n\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n this.unregister();\n });\n\n effect(() => {\n const nextId = this.id() ?? this.resolvedId;\n const nextOrder = this.order();\n if (this.registeredId && this.registeredId !== nextId) {\n this.unregister();\n void this.register();\n return;\n }\n if (this.registeredId && nextOrder !== this.lastOrder) {\n this.unregister();\n void this.register();\n }\n this.lastOrder = nextOrder;\n });\n }\n\n private async register(): Promise<void> {\n const grid = this.findGrid();\n if (!grid) return;\n try {\n await grid.ready?.();\n } catch {\n return;\n }\n if (this.destroyed) return;\n\n const template = this.template();\n const id = this.id() ?? this.resolvedId;\n const order = this.order();\n\n const def: ToolbarContentDefinition = {\n id,\n order,\n render: (container) => {\n if (!template) return undefined;\n // Sticky container: see grid-header-content.directive.ts for rationale.\n const firstNode = this.viewRef?.rootNodes[0] as Node | undefined;\n if (this.viewRef && firstNode && container.contains(firstNode)) {\n return () => {\n /* intentionally empty */\n };\n }\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n this.viewRef = this.viewContainerRef.createEmbeddedView(template, {\n $implicit: grid,\n grid,\n });\n this.viewRef.detectChanges();\n for (const node of this.viewRef.rootNodes as Node[]) {\n container.appendChild(node);\n }\n // No-op cleanup — see comment in grid-header-content.directive.ts.\n return () => {\n /* intentionally empty */\n };\n },\n };\n // Route through the shell plugin (#370). The shell is opt-in at v3 —\n // content registers only when a shell plugin is present.\n grid.getPluginByName?.('shell')?.registerToolbarContent(def);\n this.registeredId = id;\n }\n\n private unregister(): void {\n const grid = this.findGrid();\n if (grid && this.registeredId) {\n grid.getPluginByName?.('shell')?.unregisterToolbarContent(this.registeredId);\n }\n this.registeredId = null;\n if (this.viewRef) {\n this.viewRef.destroy();\n this.viewRef = null;\n }\n }\n\n private findGrid(): DataGridElement | null {\n const host = this.elementRef.nativeElement;\n // Use the stable `[data-tbw-grid]` attribute (set by core on connect) rather\n // than the literal `tbw-grid` tag, so a version-suffixed grid host (e.g.\n // `<tbw-grid-v2-15-0>`) is still found. See the multi-version guide.\n return host.closest('[data-tbw-grid]') as DataGridElement | null;\n }\n\n static ngTemplateContextGuard(_dir: GridToolbarContent, ctx: unknown): ctx is GridToolbarContentContext {\n return true;\n }\n}\n","/**\n * Shell feature for @toolbox-web/grid-angular\n *\n * Import this module to opt the grid shell (header bar + tool panels) into\n * the build. The shell also auto-registers in v2.x (so it is on by default\n * and non-breaking); importing this module makes the opt-in explicit and\n * tree-shakeable for v3, where the auto-register is removed.\n *\n * The shell is configured through `gridConfig` (`features: { shell }` or the\n * `<tbw-grid-header-content>` / `<tbw-grid-toolbar-content>` /\n * `<tbw-grid-tool-panel>` directives), not a boolean input.\n *\n * @example\n * ```typescript\n * // In your bootstrap (e.g. main.ts or app.component.ts):\n * import '@toolbox-web/grid-angular/features/shell';\n * ```\n *\n * ```html\n * <tbw-grid [gridConfig]=\"{ features: { shell: { header: { title: 'Employees' } } } }\">\n * </tbw-grid>\n * ```\n *\n * @packageDocumentation\n */\n\nimport { registerToolPanelRendererBridge, type GridAdapter } from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/shell';\nimport { getToolPanelTemplate, type GridToolPanelContext } from './grid-tool-panel.directive';\n\nexport type { _Augmentation as _ShellAugmentation } from '@toolbox-web/grid/features/shell';\n\n// ---------------------------------------------------------------------------\n// Shell-owned directives + helpers. These physically live in this secondary\n// entry (the runtime behaviour lives here too).\n// ---------------------------------------------------------------------------\nexport { GridHeaderContent } from './grid-header-content.directive';\nexport type { GridHeaderContentContext } from './grid-header-content.directive';\nexport { getToolPanelElements, getToolPanelTemplate, GridToolPanel } from './grid-tool-panel.directive';\nexport type { GridToolPanelContext } from './grid-tool-panel.directive';\nexport { GridToolbarContent } from './grid-toolbar-content.directive';\nexport type { GridToolbarContentContext } from './grid-toolbar-content.directive';\n\n// Install the tool-panel renderer bridge on the adapter. This is what\n// `adapter.createToolPanelRenderer(element)` delegates to. Without this import,\n// the method returns undefined and light-DOM `<tbw-grid-tool-panel>` Angular\n// templates are never mounted by the core ShellPlugin.\nregisterToolPanelRendererBridge((element: HTMLElement, adapter: GridAdapter) => {\n // Type inferred from `getToolPanelTemplate` (same package instance as the\n // adapter), not from a local `import type { TemplateRef } from '@angular/core'`\n // — the latter resolves through Bun's `.bun/` cache during ng-packagr build\n // and produces a brand-incompatible TemplateRef vs the built adapter `.d.ts`.\n const template = getToolPanelTemplate(element);\n if (!template) return undefined;\n\n // Find the parent grid element for context.\n const gridElement = element.closest('tbw-grid, [data-tbw-grid]') as HTMLElement | null;\n\n return (container: HTMLElement) => {\n const context: GridToolPanelContext = {\n $implicit: gridElement ?? container,\n grid: gridElement ?? container,\n };\n const viewRef = adapter.createTrackedEmbeddedView(template, context);\n viewRef.rootNodes.forEach((node: Node) => container.appendChild(node));\n return () => viewRef.destroy();\n };\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["autoIdCounter"],"mappings":"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"}
|