@handsontable/angular-wrapper 0.0.0-next-0491dcb-20261103 → 0.0.0-next-dddc256-20261103

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.
@@ -1140,6 +1140,7 @@ const SIZE_SETTING_KEYS = /* @__PURE__ */ new Set([
1140
1140
  "minRowHeights",
1141
1141
  "colWidths"
1142
1142
  ]);
1143
+ const CLEARED_BY_NULL_SETTINGS = ["height", "width"];
1143
1144
  function isHookCallback(value) {
1144
1145
  return typeof value === "function" || Array.isArray(value);
1145
1146
  }
@@ -1165,6 +1166,7 @@ var HotTableComponent = class HotTableComponent {
1165
1166
  isBrowser = inject(PLATFORM_ID) === "browser";
1166
1167
  _gridColumns;
1167
1168
  _passedHookKeys = /* @__PURE__ */ new Set();
1169
+ _passedClearedByNullKeys = /* @__PURE__ */ new Set();
1168
1170
  constructor(_hotSettingsResolver, _hotConfig, ngZone, environmentInjector, _dynamicComponentService) {
1169
1171
  this._hotSettingsResolver = _hotSettingsResolver;
1170
1172
  this._hotConfig = _hotConfig;
@@ -1187,6 +1189,7 @@ var HotTableComponent = class HotTableComponent {
1187
1189
  let options = this._hotSettingsResolver.applyCustomSettings(this.settings);
1188
1190
  if (Array.isArray(options.columns)) this._gridColumns = options.columns;
1189
1191
  this._passedHookKeys = this.collectHookKeys(options);
1192
+ this._passedClearedByNullKeys = this.collectClearedByNullKeys(options);
1190
1193
  const negotiatedSettings = this.getNegotiatedSettings(options);
1191
1194
  options = {
1192
1195
  ...options,
@@ -1217,6 +1220,8 @@ var HotTableComponent = class HotTableComponent {
1217
1220
  const newOptions = this._hotSettingsResolver.applyCustomSettings(changes.settings.currentValue, prevColumnsArray);
1218
1221
  this.clearRemovedHooks(newOptions);
1219
1222
  this._passedHookKeys = this.collectHookKeys(newOptions);
1223
+ this.clearUnsetSizes(newOptions);
1224
+ this._passedClearedByNullKeys = this.collectClearedByNullKeys(newOptions, this._passedClearedByNullKeys);
1220
1225
  this.updateHotTable(newOptions);
1221
1226
  if (prevColumnsArray && Array.isArray(newOptions.columns)) {
1222
1227
  const reusedRefs = new Set(newOptions.columns.map((column) => column._editorComponentReference).filter((ref) => !!ref));
@@ -1251,6 +1256,15 @@ var HotTableComponent = class HotTableComponent {
1251
1256
  if (!isHookCallback(newOptions[key])) newOptions[key] = null;
1252
1257
  });
1253
1258
  }
1259
+ clearUnsetSizes(newOptions) {
1260
+ Object.keys(newOptions).forEach((key) => {
1261
+ if (this._passedClearedByNullKeys.has(key) && newOptions[key] === void 0) newOptions[key] = null;
1262
+ });
1263
+ }
1264
+ collectClearedByNullKeys(settings, previousKeys = /* @__PURE__ */ new Set()) {
1265
+ const ownKeys = new Set(Object.keys(settings));
1266
+ return new Set(CLEARED_BY_NULL_SETTINGS.filter((key) => ownKeys.has(key) ? settings[key] !== void 0 && settings[key] !== null : previousKeys.has(key)));
1267
+ }
1254
1268
  collectHookKeys(settings) {
1255
1269
  return new Set(Object.keys(settings).filter((key) => isHookCallback(settings[key]) && (Handsontable.hooks.isRegistered(key) || Handsontable.hooks.isDeprecated(key))));
1256
1270
  }
@@ -1351,7 +1365,7 @@ i0.ɵɵngDeclareClassMetadata({
1351
1365
  }
1352
1366
  });
1353
1367
  var HotTableModule = class HotTableModule {
1354
- static version = "0.0.0-next-0491dcb-20261103";
1368
+ static version = "0.0.0-next-dddc256-20261103";
1355
1369
  static ɵfac = i0.ɵɵngDeclareFactory({
1356
1370
  minVersion: "12.0.0",
1357
1371
  version: "22.2.2",
@@ -1 +1 @@
1
- {"version":3,"file":"handsontable-angular-wrapper.mjs","names":["i1.DynamicComponentService","i1.HotSettingsResolver","i2.HotGlobalConfigService","i3.DynamicComponentService"],"sources":["../../../projects/hot-table/src/lib/editor/custom-editor-placeholder.component.ts","../../../projects/hot-table/src/lib/editor/base-editor-adapter.ts","../../../projects/hot-table/src/lib/renderer/hot-cell-renderer-base.directive.ts","../../../projects/hot-table/src/lib/renderer/hot-cell-renderer.component.ts","../../../projects/hot-table/src/lib/editor/hot-cell-editor-base.directive.ts","../../../projects/hot-table/src/lib/editor/hot-cell-editor.component.ts","../../../projects/hot-table/src/lib/editor/editor-factory-adapter.ts","../../../projects/hot-table/src/lib/renderer/hot-cell-renderer-advanced.component.ts","../../../projects/hot-table/src/lib/editor/hot-cell-editor-advanced.component.ts","../../../projects/hot-table/src/lib/renderer/hot-dynamic-renderer-component.service.ts","../../../projects/hot-table/src/lib/services/hot-settings-resolver.service.ts","../../../projects/hot-table/src/lib/services/hot-global-config.service.ts","../../../projects/hot-table/src/lib/hot-table.component.ts","../../../projects/hot-table/src/lib/hot-table.module.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ComponentRef, Input, ViewChild, ViewContainerRef } from '@angular/core';\nimport { HotCellEditorComponent } from './hot-cell-editor.component';\nimport { HotCellEditorAdvancedComponent } from './hot-cell-editor-advanced.component';\n\n/**\n * Component representing a placeholder for a custom editor in Handsontable.\n * It is used only within the wrapper.\n */\n@Component({\n template: ` <div\n [class]=\"placeholderCustomClass\"\n [style.display]=\"display\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n [style.maxWidth.px]=\"width\"\n [style.maxHeight.px]=\"height\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\"\n >\n <ng-template #inputPlaceholder></ng-template>\n </div>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class CustomEditorPlaceholderComponent {\n /** The top position of the editor. */\n @Input() top: number;\n\n /** The left position of the editor. */\n @Input() left: number;\n\n /** The height of the editor. */\n @Input() height: number;\n\n /** The width of the editor. */\n @Input() width: number;\n\n @Input()\n set isVisible(value: boolean) {\n this._isVisible = value;\n }\n\n @Input() placeholderCustomClass = 'handsontableInputHolder ht_clone_master';\n\n /** The reference to the component instance of the editor. */\n @Input() set componentRef(\n hotEditorComponentRef: ComponentRef<HotCellEditorComponent<any>> |\n ComponentRef<HotCellEditorAdvancedComponent<any>>) {\n if (hotEditorComponentRef) {\n this.container.insert(hotEditorComponentRef.hostView);\n }\n }\n\n /** The container for the editor's input placeholder. */\n @ViewChild('inputPlaceholder', { read: ViewContainerRef, static: true }) container: ViewContainerRef;\n\n /** The display style of the editor. */\n get display(): string {\n return this._isVisible ? 'block' : 'none';\n }\n\n private _isVisible = false;\n\n /**\n * Detaches the container from the Handsontable.\n */\n detachEditor(): void {\n this.container.detach();\n }\n}\n","import Handsontable from 'handsontable/base';\nimport {\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n} from '@angular/core';\nimport { CustomEditorPlaceholderComponent } from './custom-editor-placeholder.component';\nimport { ColumnSettingsInternal } from '../models/column-settings';\nimport { HotCellEditorComponent } from './hot-cell-editor.component';\nimport { Subscription } from 'rxjs';\nimport { take } from 'rxjs/operators';\n\n/**\n * Adapter for BaseEditor from Handsontable.\n */\nexport class BaseEditorAdapter extends Handsontable.editors.BaseEditor {\n /** Reference to the custom editor component. */\n private _componentRef?: ComponentRef<HotCellEditorComponent<any>>;\n\n /** Reference to the editor placeholder component. */\n private _editorPlaceHolderRef: ComponentRef<CustomEditorPlaceholderComponent>;\n\n /** Flag indicating whether the placeholder is ready. */\n private _isPlaceholderReady = false;\n\n /** Subscription for the finish edit event. */\n private _finishEditSubscription?: Subscription;\n\n /** Subscription for the cancel edit event. */\n private _cancelEditSubscription?: Subscription;\n\n /**\n * Creates an instance of BaseEditorAdapter.\n * @param instance The Handsontable instance.\n */\n constructor(instance: Handsontable.Core) {\n super(instance);\n\n this.hot.addHook('afterRowResize', this.onAfterRowResize.bind(this));\n this.hot.addHook('afterColumnResize', this.onAfterColumnResize.bind(this));\n this.hot.addHook('afterDestroy', this.onAfterDestroy.bind(this));\n }\n\n /**\n * Prepares the editor for editing. Parameters are passed from Handsontable.\n * @param row The row index.\n * @param column The column index.\n * @param prop The property name.\n * @param TD The table cell element.\n * @param originalValue The original value of the cell.\n * @param cellProperties The cell properties.\n */\n override prepare(\n row: number,\n column: number,\n prop: string | number,\n TD: HTMLTableCellElement,\n originalValue: any,\n cellProperties: Handsontable.CellProperties\n ): void {\n if (!this.isOpened()) {\n super.prepare(row, column, prop, TD, originalValue, cellProperties);\n const columnMeta: ColumnSettingsInternal = this.hot.getColumnMeta(\n column\n ) as ColumnSettingsInternal;\n\n if (!this._isPlaceholderReady) {\n this.createEditorPlaceholder(columnMeta._environmentInjector);\n this._isPlaceholderReady = true;\n }\n\n this._componentRef = columnMeta._editorComponentReference;\n\n this.cleanupSubscriptions();\n\n this._finishEditSubscription = this._componentRef.instance.finishEdit\n .pipe(take(1))\n .subscribe(() => {\n this.finishEditing();\n });\n\n this._cancelEditSubscription = this._componentRef.instance.cancelEdit\n .pipe(take(1))\n .subscribe(() => {\n this.cancelChanges();\n });\n }\n }\n\n /**\n * Closes the editor. This event is triggered by Handsontable.\n */\n close(): void {\n if (this.isOpened()) {\n this.resetEditorState();\n this._editorPlaceHolderRef?.changeDetectorRef.detectChanges();\n this._editorPlaceHolderRef?.instance.detachEditor();\n this._componentRef?.instance.onClose();\n }\n }\n\n /**\n * Focuses the editor. This event is triggered by Handsontable.\n */\n focus(): void {\n this._componentRef?.instance.onFocus();\n }\n\n /**\n * Gets the value from the editor.\n * @returns The value from the editor.\n */\n getValue(): any {\n return this._componentRef?.instance?.getValue();\n }\n\n /**\n * Opens the editor. This event is triggered by Handsontable.\n * When opening, we set the shortcut context to 'editor'.\n * This allows the built-in keyboard shortcuts to operate within the editor.\n * @param event The event that triggered the opening of the editor.\n * @remarks When entering edit mode using double-click, keyboard shortcuts do not work.\n */\n open(event?: Event): void {\n this.hot.getShortcutManager().setActiveContextName('editor');\n this.applyPropsToEditor();\n this._componentRef?.instance.onOpen(event);\n }\n\n /**\n * Sets the value for the custom editor.\n * @param newValue The value to set.\n */\n setValue(newValue?: any): void {\n this._componentRef?.instance?.setValue(newValue);\n this._componentRef?.changeDetectorRef.detectChanges();\n }\n\n /**\n * Applies properties to the custom editor and editor placeholder.\n */\n private applyPropsToEditor(): void {\n if (!this._componentRef || !this._editorPlaceHolderRef) {\n return;\n }\n\n const rect = this.getEditedCellRect();\n\n if (!this.isInFullEditMode()) {\n this._componentRef.instance.setValue(null);\n }\n\n this._componentRef.setInput('originalValue', this.originalValue);\n this._componentRef.setInput('row', this.row);\n this._componentRef.setInput('column', this.col);\n this._componentRef.setInput('prop', this.prop);\n this._componentRef.setInput('cellProperties', this.cellProperties);\n\n this._editorPlaceHolderRef.setInput('top', rect.top);\n this._editorPlaceHolderRef.setInput('left', rect.start);\n this._editorPlaceHolderRef.setInput('height', rect.height);\n this._editorPlaceHolderRef.setInput('width', rect.width);\n this._editorPlaceHolderRef.setInput('isVisible', true);\n this._editorPlaceHolderRef.setInput('componentRef', this._componentRef);\n this._editorPlaceHolderRef.changeDetectorRef.detectChanges();\n }\n\n /**\n * Creates the editor placeholder and append it to hot rootElement.\n * @param injector The environment injector.\n */\n private createEditorPlaceholder(injector: EnvironmentInjector): void {\n this._editorPlaceHolderRef = createComponent(\n CustomEditorPlaceholderComponent,\n {\n environmentInjector: injector as EnvironmentInjector,\n }\n );\n\n this.hot.rootElement.appendChild(\n this._editorPlaceHolderRef.location.nativeElement\n );\n }\n\n /**\n * Handles the after column resize event.\n * Helps adjust the editor size to the column size and update its position.\n */\n private onAfterColumnResize(): void {\n if (this.isOpened()) {\n this.applyPropsToEditor();\n }\n }\n\n /**\n * Handles the after row resize event.\n * Helps adjust the editor size to the column size and update its position.\n */\n private onAfterRowResize(): void {\n if (this.isOpened()) {\n this.applyPropsToEditor();\n }\n }\n\n /**\n * Handles the after destroy event.\n */\n private onAfterDestroy(): void {\n this.cleanupSubscriptions();\n this._editorPlaceHolderRef?.destroy();\n }\n\n /**\n * Unsubscribes the finish/cancel edit subscriptions if they are still active.\n * Without this, destroying the table while an editor was prepared but never\n * finished/canceled leaves the `take(1)` subscriptions hanging (they never emit).\n */\n private cleanupSubscriptions(): void {\n if (this._finishEditSubscription) {\n this._finishEditSubscription.unsubscribe();\n this._finishEditSubscription = undefined;\n }\n\n if (this._cancelEditSubscription) {\n this._cancelEditSubscription.unsubscribe();\n this._cancelEditSubscription = undefined;\n }\n }\n\n /**\n * Resets the editor placeholder state.\n * We need to reset the editor placeholder state because we use it\n * to store multiple references to the custom editor.\n */\n private resetEditorState(): void {\n if (!this._editorPlaceHolderRef) {\n return;\n }\n\n this._editorPlaceHolderRef.setInput('top', undefined);\n this._editorPlaceHolderRef.setInput('left', undefined);\n this._editorPlaceHolderRef.setInput('height', undefined);\n this._editorPlaceHolderRef.setInput('width', undefined);\n this._editorPlaceHolderRef.setInput('isVisible', false);\n this._editorPlaceHolderRef.setInput('componentRef', undefined);\n }\n}\n","import Handsontable from 'handsontable/base';\nimport { Directive, Input } from '@angular/core';\n\n/**\n * Shared base directive for HotCellRendererComponent and HotCellRendererAdvancedComponent.\n * Holds all @Input() properties and getProps() that both renderer variants share.\n *\n * @template TValue - The type of the rendered cell value.\n * @template TProps - The type of additional renderer properties.\n */\n@Directive()\nexport abstract class HotCellRendererBase<\n TValue extends string | number | boolean | Record<string, any> | Array<any> = string,\n TProps extends {} = any\n> {\n @Input() value: TValue = '' as TValue;\n\n @Input() instance: Handsontable;\n @Input() td: HTMLTableCellElement;\n @Input() row: number;\n @Input() col: number;\n @Input() prop: string | number;\n\n @Input() cellProperties: Handsontable.CellProperties & { rendererProps?: TProps };\n\n public getProps(): TProps {\n return this.cellProperties?.rendererProps ?? ({} as TProps);\n }\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { HotCellRendererBase } from './hot-cell-renderer-base.directive';\n\n/**\n * Abstract base component for creating custom cell renderer components for Handsontable.\n *\n * Extend this component and provide your own template to implement a custom renderer.\n * Value type is limited to primitives (`string | number | boolean`).\n * For object and array values use {@link HotCellRendererAdvancedComponent}.\n *\n * @template TValue - The type of the component renderer.\n * @template TProps - The type of additional renderer properties.\n */\n@Component({\n selector: 'hot-cell-renderer',\n template: `<!-- This is an abstract component. Extend this component and provide your own template. -->`,\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport abstract class HotCellRendererComponent<TValue extends string | number | boolean = string, TProps extends {} = any>\n extends HotCellRendererBase<TValue, TProps> {\n static readonly RENDERER_MARKER = Symbol('HotCellRendererComponent');\n}\n","import Handsontable from 'handsontable/base';\nimport { Directive, EventEmitter, HostBinding, Input, Output } from '@angular/core';\n\n/**\n * Shared base directive for HotCellEditorComponent and HotCellEditorAdvancedComponent.\n * Holds all @Input(), @Output() and @HostBinding() declarations that both editor variants share.\n *\n * @template T - The type of the edited cell value.\n */\n@Directive()\nexport abstract class HotCellEditorBase<\n T extends string | number | boolean | Record<string, any> | Array<any>\n> {\n @HostBinding('style.height.%') protected heightFitParentContainer = 100;\n @HostBinding('style.width.%') protected widthFitParentContainer = 100;\n\n @Input() row: number;\n @Input() column: number;\n @Input() prop: string | number;\n @Input() originalValue: T;\n @Input() cellProperties: Handsontable.CellProperties;\n\n @Output() finishEdit = new EventEmitter<void>();\n @Output() cancelEdit = new EventEmitter<void>();\n\n protected value: T;\n\n getValue(): T {\n return this.value;\n }\n\n setValue(value: T): void {\n this.value = value;\n }\n}\n","import { Directive, HostBinding } from '@angular/core';\nimport { HotCellEditorBase } from './hot-cell-editor-base.directive';\n\n/**\n * Abstract class representing a basic Handsontable cell editor in Angular.\n *\n * Extend this class and decorate the subclass with `@Component()` to implement a custom editor.\n * Value type is limited to primitives (`string | number | boolean`).\n * For object and array values use {@link HotCellEditorAdvancedComponent}.\n */\n@Directive()\nexport abstract class HotCellEditorComponent<T extends string | number | boolean> extends HotCellEditorBase<T> {\n static readonly EDITOR_MARKER = Symbol('HotCellEditorComponent');\n\n /** The tabindex attribute for the editor. */\n @HostBinding('attr.tabindex') protected tabindex = -1;\n\n /** The data-hot-input attribute for the editor. */\n @HostBinding('attr.data-hot-input') protected dataHotInput = '';\n\n /** The handsontableInput class for the editor. */\n @HostBinding('class.handsontableInput') protected handsontableInputClass = true;\n\n /** Event triggered by Handsontable on closing the editor. */\n onClose(): void {}\n\n /** Event triggered by Handsontable on opening the editor. */\n onOpen(event?: Event): void {}\n\n /**\n * Event triggered by Handsontable on focusing the editor.\n * Must be implemented by the subclass to move focus to the actual input element.\n * @example\n * ```typescript\n * @Component({ template: `<input #inputElement>` })\n * class CustomEditor extends HotCellEditorComponent<string> {\n * @ViewChild('inputElement') inputElement!: ElementRef;\n * onFocus(): void { this.inputElement.nativeElement.focus(); }\n * }\n * ```\n */\n abstract onFocus(): void;\n}\n","import { ComponentRef, createComponent, EnvironmentInjector } from '@angular/core';\nimport { CustomEditorPlaceholderComponent } from './custom-editor-placeholder.component';\nimport { AngularEditorProperties, HotInstanceWithAngularInjector } from './models/factory-editor-properties';\nimport { editorFactory, ExtendedEditor } from 'handsontable/editors/factory';\nimport { take } from 'rxjs/operators';\nimport { HotCellEditorAdvancedComponent } from './hot-cell-editor-advanced.component';\n\n/**\n * Combined type representing an extended editor with Angular component properties.\n * Used internally by the factory adapter to bridge Angular and Handsontable.\n */\ntype EditorInstance = ExtendedEditor<AngularEditorProperties & HotCellEditorAdvancedComponent<any>>;\n\n/**\n * Factory function to create a custom Handsontable editor adapter for Angular components.\n *\n * This adapter integrates Angular components with Handsontable's editor system using the new\n * editorFactory API, allowing you to use Angular components as custom cell editors while\n * maintaining full Angular lifecycle management and change detection.\n *\n * @returns A custom editor class that can be used in Handsontable column settings.\n *\n */\nexport const FactoryEditorAdapter = (componentRef: ComponentRef<HotCellEditorAdvancedComponent<any>>) =>\n editorFactory<ExtendedEditor<any>>({\n position: componentRef.instance.position,\n shortcuts: componentRef.instance.shortcuts,\n shortcutsGroup: componentRef.instance.shortcutsGroup,\n config: componentRef.instance.config,\n init(editor: EditorInstance): void {\n editor._componentRef = componentRef;\n editor._editorPlaceHolderRef = undefined;\n editor._finishEditSubscription = undefined;\n editor._cancelEditSubscription = undefined;\n\n createEditorPlaceholder(editor, (editor.hot as HotInstanceWithAngularInjector)._angularEnvironmentInjector);\n editor.input = editor._editorPlaceHolderRef?.location.nativeElement ?? document.createElement('div');\n\n editor._afterRowResizeCallback = (): void => {\n if (editor.isOpened()) {\n applyPropsToEditor(editor);\n }\n };\n\n editor._afterColumnResizeCallback = (): void => {\n if (editor.isOpened()) {\n applyPropsToEditor(editor);\n }\n };\n\n editor._afterDestroyCallback = (): void => {\n cleanupSubscriptions(editor);\n if (editor._editorPlaceHolderRef) {\n editor._editorPlaceHolderRef.destroy();\n }\n };\n\n // Hooks are automatically removed by Handsontable on table destroy\n editor.hot.addHook('afterRowResize', editor._afterRowResizeCallback);\n editor.hot.addHook('afterColumnResize', editor._afterColumnResizeCallback);\n editor.hot.addHook('afterDestroy', editor._afterDestroyCallback);\n },\n\n afterInit: (editor) => editor._componentRef.instance.afterInit?.(editor),\n beforeOpen: (editor: EditorInstance, context) => {\n cleanupSubscriptions(editor);\n\n applyPropsToEditor(editor);\n\n editor._finishEditSubscription = editor._componentRef.instance.finishEdit.pipe(take(1)).subscribe((): void => {\n editor.finishEditing();\n });\n\n editor._cancelEditSubscription = editor._componentRef.instance.cancelEdit.pipe(take(1)).subscribe((): void => {\n editor.cancelChanges();\n });\n editor._componentRef.instance.beforeOpen?.(editor, context);\n },\n afterOpen: (editor, event) => {\n editor._componentRef.instance.afterOpen?.(editor, event);\n },\n onFocus: (editor) => editor._componentRef.instance.onFocus?.(editor),\n afterClose: (editor: EditorInstance) => {\n cleanupSubscriptions(editor);\n resetEditorState(editor);\n editor._editorPlaceHolderRef?.changeDetectorRef.detectChanges();\n editor._editorPlaceHolderRef?.instance.detachEditor();\n editor._componentRef.instance.afterClose?.(editor);\n },\n getValue: (editor) => editor._componentRef.instance.getValue(),\n setValue: (editor: EditorInstance, value) => {\n editor.value = value;\n editor._componentRef.instance.setValue(value);\n editor._componentRef.changeDetectorRef.detectChanges();\n },\n });\n\n/**\n * Creates the editor placeholder component.\n * @param editor The editor instance.\n * @param injector The environment injector from Angular.\n */\nfunction createEditorPlaceholder(editor: EditorInstance, injector: EnvironmentInjector | undefined): void {\n if (!injector) {\n return;\n }\n\n editor._editorPlaceHolderRef = createComponent(CustomEditorPlaceholderComponent, {\n environmentInjector: injector,\n });\n}\n\n/**\n * Applies properties to the custom Angular editor and editor placeholder.\n * Updates position, size, and cell context information.\n * @param editor The editor instance.\n */\nfunction applyPropsToEditor(editor: EditorInstance): void {\n if (!editor._componentRef || !editor._editorPlaceHolderRef) {\n return;\n }\n\n editor._componentRef.setInput('originalValue', editor.originalValue);\n editor._componentRef.setInput('row', editor.row);\n editor._componentRef.setInput('column', editor.col);\n editor._componentRef.setInput('prop', editor.prop);\n editor._componentRef.setInput('cellProperties', editor.cellProperties);\n\n const rect = editor.hot.getCell(editor.row, editor.col)?.getBoundingClientRect();\n\n editor._editorPlaceHolderRef.setInput('placeholderCustomClass', '');\n editor._editorPlaceHolderRef.setInput('height', rect?.height ?? 0);\n editor._editorPlaceHolderRef.setInput('width', rect?.width ?? 0);\n editor._editorPlaceHolderRef.setInput('isVisible', true);\n editor._editorPlaceHolderRef.setInput('componentRef', editor._componentRef);\n\n editor._editorPlaceHolderRef.changeDetectorRef.detectChanges();\n}\n\n/**\n * Resets the editor placeholder state.\n * Clears all positioning and visibility settings.\n * @param editor The editor instance.\n */\nfunction resetEditorState(editor: EditorInstance): void {\n if (!editor._editorPlaceHolderRef) {\n return;\n }\n\n editor._editorPlaceHolderRef.setInput('top', undefined);\n editor._editorPlaceHolderRef.setInput('left', undefined);\n editor._editorPlaceHolderRef.setInput('height', undefined);\n editor._editorPlaceHolderRef.setInput('width', undefined);\n editor._editorPlaceHolderRef.setInput('isVisible', false);\n editor._editorPlaceHolderRef.setInput('componentRef', undefined);\n}\n\n/**\n * Cleans up existing subscriptions.\n * @param editor The editor instance.\n */\nfunction cleanupSubscriptions(editor: EditorInstance): void {\n if (editor._finishEditSubscription) {\n editor._finishEditSubscription.unsubscribe();\n editor._finishEditSubscription = undefined;\n }\n\n if (editor._cancelEditSubscription) {\n editor._cancelEditSubscription.unsubscribe();\n editor._cancelEditSubscription = undefined;\n }\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { HotCellRendererBase } from './hot-cell-renderer-base.directive';\n\n/**\n * Abstract base component for creating advanced custom cell renderer components for Handsontable.\n *\n * Extend this component and provide your own template to implement a custom renderer.\n * Unlike {@link HotCellRendererComponent}, this variant also accepts object and array values.\n *\n * @template TValue - The type of the component renderer.\n * @template TProps - The type of additional renderer properties.\n */\n@Component({\n selector: 'hot-cell-renderer-advanced',\n template: `<!-- This is an abstract component. Extend this component and provide your own template. -->`,\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport abstract class HotCellRendererAdvancedComponent<\n TValue extends string | number | boolean | Record<string, any> | Array<any> = string,\n TProps extends {} = any\n> extends HotCellRendererBase<TValue, TProps> {\n static readonly RENDERER_MARKER = Symbol('HotCellRendererAdvancedComponent');\n}\n","import { Directive } from '@angular/core';\nimport { ExtendedEditor } from 'handsontable/editors/factory';\nimport { CellProperties } from 'handsontable/settings';\nimport { KeyboardShortcutConfig } from './models/keyboard-shortcut-config';\nimport { HotCellEditorBase } from './hot-cell-editor-base.directive';\n\n/**\n * Abstract class representing an advanced Handsontable cell editor in Angular.\n *\n * Extend this class and decorate the subclass with `@Component()` to implement a custom editor.\n * Unlike {@link HotCellEditorComponent}, this variant also accepts object and array values\n * and provides additional lifecycle hooks and positioning options.\n */\n@Directive()\nexport abstract class HotCellEditorAdvancedComponent<\n T extends string | number | boolean | Record<string, any> | Array<any>\n> extends HotCellEditorBase<T> {\n static readonly EDITOR_MARKER = Symbol('HotCellEditorAdvancedComponent');\n\n /** Event triggered by Handsontable on focusing the editor. Available in advanced mode. */\n onFocus(editor?: ExtendedEditor<T>): void {}\n\n /** The position of the editor in the DOM. Available in advanced mode. */\n position: 'container' | 'portal' = 'container';\n\n /** The shortcuts available for the editor. Available in advanced mode. */\n shortcuts?: KeyboardShortcutConfig[];\n\n /** The group name for the shortcuts. Available in advanced mode. */\n shortcutsGroup?: string;\n\n /** Configuration object. Available in advanced mode. */\n config?: any;\n\n /** Lifecycle hook called after the editor is opened. Available in advanced mode. */\n afterOpen(editor: ExtendedEditor<T>, event?: Event): void {}\n\n /** Lifecycle hook called after the editor is closed. Available in advanced mode. */\n afterClose(editor: ExtendedEditor<T>): void {}\n\n /** Lifecycle hook called after the editor is initialized. Available in advanced mode. */\n afterInit(editor: ExtendedEditor<T>): void {}\n\n /** Lifecycle hook called before the editor is opened. Available in advanced mode. */\n beforeOpen(\n editor: ExtendedEditor<T>,\n {\n row,\n col,\n prop,\n td,\n originalValue,\n cellProperties,\n }: {\n row: number;\n col: number;\n prop: string | number;\n td: HTMLTableCellElement;\n originalValue: any;\n cellProperties: CellProperties;\n }\n ): void {}\n}\n","import {\n ApplicationRef,\n ComponentRef,\n createComponent,\n EmbeddedViewRef,\n EnvironmentInjector,\n Injectable,\n TemplateRef,\n Type\n} from '@angular/core';\nimport { baseRenderer, BaseRenderer, registerRenderer, rendererFactory } from 'handsontable/renderers';\nimport Handsontable from 'handsontable/base';\nimport { HotCellRendererBase } from './hot-cell-renderer-base.directive';\nimport { HotCellRendererComponent } from './hot-cell-renderer.component';\nimport { HotCellRendererAdvancedComponent } from './hot-cell-renderer-advanced.component';\n\nexport const INVALID_RENDERER_WARNING =\n 'The provided renderer component was not recognized as a valid custom renderer. ' +\n 'It must either extend HotCellRendererComponent or be a valid TemplateRef. ' +\n 'Please ensure that your custom renderer is implemented correctly and imported from the proper source.';\n\nexport const INVALID_ADVANCED_RENDERER_WARNING =\n 'The provided renderer component was not recognized as a valid custom renderer. ' +\n 'It must either extend HotCellRendererAdvancedComponent. ' +\n 'Please ensure that your custom renderer is implemented correctly and imported from the proper source.';\n\n/**\n * An object representing the parameters passed to a Handsontable renderer.\n */\ninterface BaseRendererParametersObject {\n instance: Handsontable.Core;\n td: HTMLTableCellElement;\n row: number;\n col: number;\n prop: string | number;\n value: any;\n cellProperties: Handsontable.CellProperties;\n}\n\n// Renderer component inputs, listed once at module scope so the per-cell render path can set them\n// without allocating a fresh key array (via Object.keys) on every cell of every render frame.\nconst RENDERER_INPUT_KEYS: (keyof BaseRendererParametersObject)[] = [\n 'instance', 'td', 'row', 'col', 'prop', 'value', 'cellProperties',\n];\n\n/**\n * Type guard that checks if the given object is a TemplateRef.\n *\n * @param obj - The object to check.\n * @returns True if the object is a TemplateRef; otherwise, false.\n */\nexport function isTemplateRef<T>(obj: any): obj is TemplateRef<T> {\n return !!obj && typeof obj.createEmbeddedView === 'function';\n}\n\n/**\n * Type guard to check if an object is an instance of HotCellRendererComponent.\n *\n * @param obj - The object to check.\n * @returns True if the object is a HotCellRendererComponent, false otherwise.\n */\nexport function isHotCellRendererComponent(obj: any): obj is Type<HotCellRendererComponent> {\n return obj?.RENDERER_MARKER === HotCellRendererComponent.RENDERER_MARKER;\n}\n\n/**\n * Type guard to check if an object is an instance of HotCellRendererAdvancedComponent.\n *\n * @param obj - The object to check.\n * @returns True if the object is a HotCellRendererAdvancedComponent, false otherwise.\n */\nexport function isAdvancedHotCellRendererComponent(obj: any): obj is Type<HotCellRendererAdvancedComponent> {\n return obj?.RENDERER_MARKER === HotCellRendererAdvancedComponent.RENDERER_MARKER;\n}\n\n/**\n * Service for dynamically creating Angular components or templates as custom renderers for Handsontable.\n *\n * This service allows you to create a renderer function that wraps a given Angular component or TemplateRef\n * so that it can be used as a Handsontable renderer.\n *\n * @example\n * const customRenderer = dynamicComponentService.createRendererFromComponent(MyRendererComponent, { someProp: value });\n * // Use customRenderer in your Handsontable configuration\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DynamicComponentService {\n // Track Angular component refs and embedded views keyed by the TD element they are attached to.\n // When a cell is re-rendered the previous component is destroyed before a new one is created.\n private readonly _tdComponentRefs = new WeakMap<HTMLTableCellElement, ComponentRef<any>>();\n private readonly _tdEmbeddedViews = new WeakMap<HTMLTableCellElement, EmbeddedViewRef<any>>();\n\n // Per-instance registries of every renderer ref/view currently attached to the application.\n // The WeakMaps above only allow per-TD lookup; these sets let us sweep refs whose TD was dropped\n // from Handsontable's virtual viewport (scrolling, updateData), which would otherwise stay\n // attached to ApplicationRef forever and leak both memory and change-detection work.\n //\n // The registries are scoped per Handsontable instance (not one global set) because this service\n // is a root singleton shared by every <hot-table>. A global sweep would scan the cells of every\n // table on the page on each `afterViewRender`, i.e. on every scroll frame of any one of them.\n // Keying by instance bounds each sweep to the cells of the table that actually re-rendered.\n private readonly _instanceComponentRefs = new WeakMap<Handsontable.Core, Set<ComponentRef<any>>>();\n private readonly _instanceEmbeddedViews = new WeakMap<Handsontable.Core, Set<EmbeddedViewRef<any>>>();\n\n // Instances we already wired the sweep hook into, so each instance is hooked at most once.\n private readonly _hookedInstances = new WeakSet<Handsontable.Core>();\n\n constructor(private appRef: ApplicationRef, private environmentInjector: EnvironmentInjector) {}\n\n /**\n * Creates a custom renderer function for Handsontable from an Angular component or TemplateRef.\n * The generated renderer function will be used by Handsontable to render cell content.\n *\n * @param component - The Angular component type or TemplateRef to use as renderer.\n * @param componentProps - An object containing additional properties to use by the renderer.\n * @param register - If true, registers the renderer with Handsontable using the component's name.\n * @returns A renderer function that can be used in Handsontable's configuration.\n */\n createRendererFromComponent(\n component: Type<HotCellRendererComponent> | TemplateRef<any>,\n componentProps: Record<string, any> = {},\n register: boolean = false\n ) {\n let registered = false;\n\n return (\n instance: Handsontable.Core,\n td: HTMLTableCellElement,\n row: number,\n col: number,\n prop: string | number,\n value: any,\n cellProperties: Handsontable.CellProperties\n ) => {\n const properties: BaseRendererParametersObject = {\n value,\n instance,\n td,\n row,\n col,\n prop,\n cellProperties,\n };\n\n (cellProperties as any).rendererProps = componentProps;\n\n baseRenderer.call(this, instance, td, row, col, prop, value, cellProperties);\n\n this.registerSweepHook(instance);\n\n if (isTemplateRef(component)) {\n // Embedded views carry a per-render context, so they are always rebuilt.\n this.replaceCellContent(instance, td);\n const embeddedView = this.attachTemplateToElement(component, td, properties);\n this.trackEmbeddedView(instance, td, embeddedView);\n } else if (isHotCellRendererComponent(component)) {\n this.renderComponent(td, component, properties);\n } else {\n console.warn(INVALID_RENDERER_WARNING);\n }\n\n if (register && !registered && isHotCellRendererComponent(component)) {\n Handsontable.renderers.registerRenderer((component as Type<any>).name, component as any as BaseRenderer);\n registered = true;\n }\n\n return td;\n };\n }\n\n /**\n * Creates a custom renderer function using rendererFactory from Handsontable.\n * This is an alternative implementation that uses the factory pattern.\n *\n * @param component - The Angular component type to use as renderer.\n * @param componentProps - An object containing additional properties to use by the renderer.\n * @param register - If true, registers the renderer with Handsontable using the component's name.\n * @returns A renderer function that can be used in Handsontable's configuration.\n */\n createRendererWithFactory(\n component: Type<HotCellRendererAdvancedComponent>,\n componentProps: Record<string, any> = {},\n register: boolean = false\n ) {\n let registered = false;\n\n return rendererFactory(({\n instance,\n td,\n row,\n column,\n prop,\n value,\n cellProperties\n }) => {\n const properties: BaseRendererParametersObject = {\n value,\n instance,\n td,\n row,\n col: column,\n prop,\n cellProperties,\n };\n\n (cellProperties as any).rendererProps = componentProps;\n\n // Apply the base renderer so the TD gets the same base classes/attributes as the\n // createRendererFromComponent path (rendererFactory itself does not call it).\n baseRenderer.call(this, instance, td, row, column, prop, value, cellProperties);\n\n this.registerSweepHook(instance);\n\n if (isAdvancedHotCellRendererComponent(component)) {\n this.renderComponent(td, component, properties);\n } else {\n console.warn(INVALID_ADVANCED_RENDERER_WARNING);\n }\n\n if (register && !registered && isAdvancedHotCellRendererComponent(component)) {\n registerRenderer(component.name, component as any as BaseRenderer);\n registered = true;\n }\n });\n }\n\n /**\n * Destroys all renderer components and embedded views attached to cells within a container element.\n * Must be called before destroying the Handsontable instance to prevent Angular component leaks.\n *\n * @param container - The root DOM element of the Handsontable instance.\n * @param instance - The Handsontable instance whose registries should be torn down. When omitted\n * (e.g. test stubs), only refs reachable through TDs still in the container are destroyed.\n */\n cleanupContainer(container: HTMLElement, instance?: Handsontable.Core): void {\n const compRefs = instance ? this._instanceComponentRefs.get(instance) : undefined;\n const embViews = instance ? this._instanceEmbeddedViews.get(instance) : undefined;\n\n container.querySelectorAll<HTMLTableCellElement>('td').forEach((td) => {\n const compRef = this._tdComponentRefs.get(td);\n if (compRef) {\n this.destroyComponent(compRef);\n this._tdComponentRefs.delete(td);\n compRefs?.delete(compRef);\n }\n const embView = this._tdEmbeddedViews.get(td);\n if (embView) {\n this.destroyEmbeddedView(embView);\n this._tdEmbeddedViews.delete(td);\n embViews?.delete(embView);\n }\n });\n\n // The loop above only reaches TDs still present in the container. Refs for cells already\n // dropped from the viewport (but not yet swept) would otherwise be orphaned once this\n // instance's afterViewRender hook is gone after destroy. Tear down whatever is left and drop\n // the per-instance registries so a repeated cleanup call is a no-op. (Entries removed in the\n // loop above are already gone from these sets, so nothing is destroyed twice.)\n compRefs?.forEach((ref) => this.destroyComponent(ref));\n embViews?.forEach((view) => this.destroyEmbeddedView(view));\n\n if (instance) {\n this._instanceComponentRefs.delete(instance);\n this._instanceEmbeddedViews.delete(instance);\n }\n }\n\n /**\n * Registers a one-time `afterViewRender` hook on the given Handsontable instance that sweeps\n * renderer refs whose TD is no longer connected to the document. Handsontable recycles a pool of\n * TD elements while virtualizing rows; cells that leave the viewport are never re-rendered, so\n * without this sweep their Angular components stay attached to ApplicationRef and leak.\n *\n * Guarded against instances that do not expose `addHook` (e.g. test stubs).\n *\n * @param instance - The Handsontable instance whose render cycle drives the sweep.\n */\n private registerSweepHook(instance: Handsontable.Core): void {\n if (this._hookedInstances.has(instance) || typeof (instance as any)?.addHook !== 'function') {\n return;\n }\n\n this._hookedInstances.add(instance);\n instance.addHook('afterViewRender', () => this.sweepDetachedViews(instance));\n }\n\n /**\n * Destroys every renderer ref/view tracked for the given instance whose root node is no longer\n * attached to the document.\n *\n * @param instance - The Handsontable instance whose registries should be swept.\n */\n private sweepDetachedViews(instance: Handsontable.Core): void {\n const compRefs = this._instanceComponentRefs.get(instance);\n compRefs?.forEach((ref) => {\n if (!this.isViewConnected(ref.hostView as EmbeddedViewRef<any>)) {\n this.destroyComponent(ref);\n compRefs.delete(ref);\n }\n });\n\n const embViews = this._instanceEmbeddedViews.get(instance);\n embViews?.forEach((view) => {\n if (!this.isViewConnected(view)) {\n this.destroyEmbeddedView(view);\n embViews.delete(view);\n }\n });\n }\n\n /**\n * @returns True if any of the view's root nodes is still connected to the document.\n */\n private isViewConnected(view: EmbeddedViewRef<any>): boolean {\n return view.rootNodes.some((node: Node) => !!node?.isConnected);\n }\n\n /**\n * Destroys the renderer ref/view previously attached to a cell and clears the cell content,\n * so a fresh renderer can take over the TD without leaking the old one.\n *\n * @param instance - The Handsontable instance owning the cell, used to update its registries.\n * @param td - The table cell whose previous content should be torn down.\n */\n private replaceCellContent(instance: Handsontable.Core, td: HTMLTableCellElement): void {\n const prevRef = this._tdComponentRefs.get(td);\n if (prevRef) {\n this.destroyComponent(prevRef);\n this._tdComponentRefs.delete(td);\n this._instanceComponentRefs.get(instance)?.delete(prevRef);\n }\n\n const prevView = this._tdEmbeddedViews.get(td);\n if (prevView) {\n this.destroyEmbeddedView(prevView);\n this._tdEmbeddedViews.delete(td);\n this._instanceEmbeddedViews.get(instance)?.delete(prevView);\n }\n\n // Not `innerHTML = ''`: that reads as \"assign nothing\", but `innerHTML` is a Trusted\n // Types sink whatever the value, so under `require-trusted-types-for 'script'` an empty\n // string throws exactly like markup would.\n td.replaceChildren();\n }\n\n /**\n * Tracks a component ref both by its TD (for fast replacement) and in the instance registry\n * (for sweeping and full teardown).\n */\n private trackComponentRef(\n instance: Handsontable.Core, td: HTMLTableCellElement, ref: ComponentRef<any>\n ): void {\n this._tdComponentRefs.set(td, ref);\n this.registryFor(this._instanceComponentRefs, instance).add(ref);\n }\n\n /**\n * Tracks an embedded view both by its TD (for fast replacement) and in the instance registry\n * (for sweeping and full teardown).\n */\n private trackEmbeddedView(\n instance: Handsontable.Core, td: HTMLTableCellElement, view: EmbeddedViewRef<any>\n ): void {\n this._tdEmbeddedViews.set(td, view);\n this.registryFor(this._instanceEmbeddedViews, instance).add(view);\n }\n\n /**\n * Returns the per-instance registry set for the given instance, creating it on first use.\n */\n private registryFor<T>(registry: WeakMap<Handsontable.Core, Set<T>>, instance: Handsontable.Core): Set<T> {\n let set = registry.get(instance);\n if (!set) {\n set = new Set<T>();\n registry.set(instance, set);\n }\n return set;\n }\n\n /**\n * Attaches an embedded view created from a TemplateRef to a given DOM element.\n *\n * @param template - The TemplateRef to create an embedded view from.\n * @param tdEl - The target DOM element (a table cell) to which the view will be appended.\n * @param properties - Context object providing properties to be used within the template.\n * @returns The created EmbeddedViewRef so the caller can track and destroy it later.\n */\n private attachTemplateToElement(\n template: TemplateRef<any>, tdEl: HTMLTableCellElement, properties: BaseRendererParametersObject\n ): EmbeddedViewRef<any> {\n const embeddedView: EmbeddedViewRef<any> = template.createEmbeddedView({\n $implicit: properties.value,\n ...properties,\n });\n embeddedView.detectChanges();\n\n embeddedView.rootNodes.forEach((node) => {\n tdEl.appendChild(node);\n });\n\n return embeddedView;\n }\n\n /**\n * Dynamically creates an Angular component of the given type.\n *\n * @param component - The Angular component type to be created.\n * @param rendererParameters - An object containing input properties to assign to the component instance.\n * @returns The ComponentRef of the dynamically created component.\n */\n private createComponent<T extends HotCellRendererBase>(\n component: Type<T>,\n rendererParameters: BaseRendererParametersObject\n ): ComponentRef<T> {\n const componentRef = createComponent(component, {\n environmentInjector: this.environmentInjector,\n });\n\n this.applyInputs(componentRef, rendererParameters);\n componentRef.changeDetectorRef.detectChanges();\n\n this.appRef.attachView(componentRef.hostView);\n\n return componentRef;\n }\n\n /**\n * Renders an Angular component into the given cell, recycling the component already attached to\n * the TD when it is of the same type. Handsontable recycles its pool of TD elements heavily while\n * virtualizing rows, so recreating an Angular component on every re-render would cause needless\n * teardown/instantiation churn and GC pressure. When the type matches we only refresh the inputs.\n *\n * @param td - The target table cell.\n * @param component - The renderer component type to render.\n * @param properties - The renderer parameters to feed as component inputs.\n */\n private renderComponent<T extends HotCellRendererBase>(\n td: HTMLTableCellElement,\n component: Type<T>,\n properties: BaseRendererParametersObject\n ): void {\n const prevRef = this._tdComponentRefs.get(td);\n\n if (\n prevRef &&\n prevRef.componentType === component &&\n this.isViewConnected(prevRef.hostView as EmbeddedViewRef<any>)\n ) {\n this.applyInputs(prevRef, properties);\n prevRef.changeDetectorRef.detectChanges();\n return;\n }\n\n this.replaceCellContent(properties.instance, td);\n const componentRef = this.createComponent(component, properties);\n this.attachComponentToElement(componentRef, td);\n this.trackComponentRef(properties.instance, td, componentRef);\n }\n\n /**\n * Assigns every renderer parameter as an input on the given component ref.\n *\n * @param componentRef - The component ref whose inputs should be set.\n * @param rendererParameters - The renderer parameters to assign.\n */\n private applyInputs<T>(componentRef: ComponentRef<T>, rendererParameters: BaseRendererParametersObject): void {\n RENDERER_INPUT_KEYS.forEach((key) => {\n componentRef.setInput(key, rendererParameters[key]);\n });\n }\n\n /**\n * Attaches a dynamically created component's view to a specified DOM container element.\n *\n * @param componentRef - The reference to the dynamically created component.\n * @param container - The target DOM element to which the component's root node will be appended.\n */\n private attachComponentToElement<T>(componentRef: ComponentRef<T>, container: HTMLElement): void {\n (componentRef.hostView as EmbeddedViewRef<T>).rootNodes.forEach((node) => {\n container.appendChild(node);\n });\n }\n\n /**\n * Destroys a dynamically created component and detaches its view from the Angular application.\n *\n * Idempotent: a TD recycled after `sweepDetachedViews` already destroyed its ref still maps to that\n * stale ref in `_tdComponentRefs`, so the next render path may reach this with an already-destroyed\n * ref. Guarding on `destroyed` skips the redundant detach/destroy instead of relying on Angular's\n * internal no-op behavior.\n *\n * @param componentRef - The reference to the component to be destroyed.\n */\n destroyComponent<T>(componentRef: ComponentRef<T>): void {\n const hostView = componentRef.hostView as EmbeddedViewRef<T>;\n if (hostView.destroyed) {\n return;\n }\n this.appRef.detachView(hostView);\n componentRef.destroy();\n }\n\n /**\n * Destroys an embedded view. Idempotent for the same reason as {@link destroyComponent}: a recycled\n * TD can still map to an already-destroyed view in `_tdEmbeddedViews`.\n *\n * @param view - The embedded view to destroy.\n */\n private destroyEmbeddedView(view: EmbeddedViewRef<any>): void {\n if (view.destroyed) {\n return;\n }\n view.destroy();\n }\n}\n","import { ComponentRef, createComponent, EnvironmentInjector, Injectable, NgZone, TemplateRef, Type } from '@angular/core';\nimport { DynamicComponentService } from '../renderer/hot-dynamic-renderer-component.service';\nimport { BaseEditorAdapter } from '../editor/base-editor-adapter';\nimport { GridSettings, GridSettingsInternal } from '../models/grid-settings';\nimport { CustomValidatorFn, ColumnSettings, ColumnSettingsInternal } from '../models/column-settings';\nimport { HotCellRendererComponent } from '../renderer/hot-cell-renderer.component';\nimport { HotCellEditorComponent } from '../editor/hot-cell-editor.component';\nimport Handsontable from 'handsontable/base';\nimport { SettingsUpdate } from 'handsontable/settings';\nimport { FactoryEditorAdapter } from '../editor/editor-factory-adapter';\nimport { HotCellRendererAdvancedComponent } from '../renderer/hot-cell-renderer-advanced.component';\nimport { HotCellEditorAdvancedComponent } from '../editor/hot-cell-editor-advanced.component';\n\nconst AVAILABLE_HOOKS_SET = new Set<string>(Handsontable.hooks.getRegistered());\nconst HOT_ZONE_WRAPPED = Symbol('hotZoneWrapped');\n/**\n * The key under which a zone wrapper names the hook callback it runs. Core's hooks registry reads the same\n * `Symbol.for()` key, so it treats the wrapper and the callback as one listener: a callback the app also\n * registers with `addHook()` runs once, and `removeHook()` with the callback removes the wrapper.\n */\nconst FORWARDED_HOOK_CALLBACK = Symbol.for('handsontable.forwardedHookCallback');\n\n/**\n * Service to resolve and apply custom settings for Handsontable settings object.\n */\n@Injectable()\nexport class HotSettingsResolver {\n /**\n * The resolved copy of each column object `resolveAppliedSettings()` resolved, with a shallow copy of the\n * column as it was then, so a column the app edited in place and passes again is resolved again.\n */\n private readonly appliedColumns = new WeakMap<ColumnSettings, { source: ColumnSettings, resolved: ColumnSettings }>();\n /**\n * The editor components of the sheets' columns, by editor component type and then by the column they\n * serve: its `data` binding when that is a string or a number, or its position. Every column object that\n * names the same editor for the same column shares one component, so a sheet whose columns the host\n * declares again with new objects, a duplicated sheet, and `updateSheetSettings()` create no new one. The\n * ones a sheet of the `settings` input names are created by `applyCustomSettings()`, inside Angular's zone\n * and before any switch, so the settings filter never creates a component in the middle of a switch.\n */\n private readonly appliedEditorRefs = new Map<Type<unknown>, Map<unknown, ComponentRef<HotCellEditorComponent<any>>>>();\n /**\n * The zone wrapper of each hook callback.\n */\n private readonly zoneWrappers = new WeakMap<Function, Function>();\n /**\n * The last `settings` input, read by `isDeclaredHook()`. A hook callback counts as declared while the input,\n * at grid level or in a sheet's own `settings`, names it: `resolveAppliedSettings()` wraps only those. A\n * callback the app hands to the instance itself (`hotInstance.updateSettings()`, `updateSheetSettings()`) is\n * the app's own call and runs as given, and one the input no longer names stops counting. The sheets bar\n * writes a sheet added at runtime into the app's own `sheets` array, so that sheet's hooks count as declared\n * from then on, the way its rows count as the app's data.\n */\n private declaredSettings: GridSettings | null = null;\n\n constructor(\n private readonly dynamicComponentService: DynamicComponentService,\n private readonly environmentInjector: EnvironmentInjector,\n private readonly ngZone: NgZone,\n ) {}\n\n /**\n * Applies custom settings to the provided GridSettings.\n * @param settings The original grid settings.\n * @param previousColumns The previously resolved columns (from the prior settings cycle). When\n * supplied, an editor component already created for a column whose editor type is unchanged is\n * recycled instead of being recreated, avoiding needless Angular component teardown/rebuild.\n * @returns The merged grid settings with custom settings applied.\n */\n applyCustomSettings(settings: GridSettings, previousColumns?: ColumnSettings[]): GridSettingsInternal {\n // Shallow-clone the user settings (and each column) before mutating. Otherwise we would\n // write generated renderers/editors and `_editorComponentReference` straight onto the\n // caller's objects. When the same settings/columns are shared across two <hot-table>\n // instances, the second resolution would overwrite the first instance's editor refs,\n // leaking them and cross-wiring a single editor component between tables.\n const mergedSettings: GridSettings = { ...settings };\n\n this.declaredSettings = settings;\n this.createDeclaredSheetEditors(settings);\n\n if (Array.isArray(mergedSettings.columns)) {\n mergedSettings.columns = mergedSettings.columns.map((column, index) => {\n const resolved = { ...column };\n\n this.resolveColumnRenderer(resolved);\n this.resolveColumnEditor(resolved, previousColumns?.[index]);\n this.resolveColumnValidator(resolved);\n\n return resolved;\n });\n }\n\n this.wrapHooksInNgZone(mergedSettings);\n\n return mergedSettings as GridSettingsInternal;\n }\n\n /**\n * Resolves the settings core is about to apply without them passing `applyCustomSettings()`: a sheet's\n * own `settings`, which the sheets bar applies through `_applySettingsAndData()` on a switch, through\n * `_replaceInitPassSettings()` for the opening sheet, and through `updateSettings()` for\n * `updateSheetSettings()`. Registered on the grid with `_addSettingsFilter()`, so it reads every\n * `updateSettings()` payload too. A value already resolved is left as it is, so the settings of the\n * `settings` input pass unchanged.\n *\n * Component renderers, editors and boolean validators are resolved in any payload: core cannot use them\n * as they are. A hook callback is wrapped in Angular's zone only when the `settings` input declared it,\n * which keeps the rule of the input: a callback the app passes to the instance itself runs as given.\n *\n * The result for a column object, and the zone wrapper of a hook, is created once and reused on every\n * later payload holding the same object or function. The sheets bar compares a sheet's settings\n * function by function, and a sheet that shows again keeps the editor component it had.\n *\n * @param settings The payload core is about to apply.\n * @returns The payload to apply: `settings` itself when nothing needed resolving, a new object\n * otherwise. The caller's object is never changed.\n */\n resolveAppliedSettings(settings: SettingsUpdate): SettingsUpdate {\n const columns = settings.columns;\n const resolvedColumns = Array.isArray(columns) ? this.resolveAppliedColumns(columns) : columns;\n const hooks = this.zoneWrappedHooksOf(settings);\n\n if (resolvedColumns === columns && hooks === null) {\n return settings;\n }\n\n const resolved: SettingsUpdate = { ...settings, ...hooks };\n\n if (resolvedColumns !== columns) {\n resolved.columns = resolvedColumns as ColumnSettingsInternal[];\n }\n\n return resolved;\n }\n\n /**\n * Destroys every editor component `resolveAppliedSettings()` created.\n */\n destroyAppliedEditors(): void {\n this.appliedEditorRefs.forEach(byColumn => byColumn.forEach(ref => ref.destroy()));\n this.appliedEditorRefs.clear();\n }\n\n /**\n * Tells whether the last `settings` input names a hook callback, at grid level or in a sheet's own\n * `settings` (see `declaredSettings`).\n *\n * @param key The hook name.\n * @param callback The callback.\n * @returns `true` when the input declares it.\n */\n private isDeclaredHook(key: string, callback: Function): boolean {\n const declared = this.declaredSettings;\n\n if (declared === null) {\n return false;\n }\n\n return (declared as Record<string, unknown>)[key] === callback ||\n this.declaredSheetSettings(declared).some(own => own[key] === callback);\n }\n\n /**\n * Returns the own `settings` of every sheet the `settings` input declares.\n *\n * @param settings The `settings` input.\n * @returns The sheets' own settings objects.\n */\n private declaredSheetSettings(settings: GridSettings): Record<string, unknown>[] {\n const sheetsBar: unknown = settings.sheetsBar;\n const sheets: unknown = typeof sheetsBar === 'object' && sheetsBar !== null\n ? (sheetsBar as { sheets?: unknown }).sheets\n : undefined;\n\n if (!Array.isArray(sheets)) {\n return [];\n }\n\n return sheets\n .map((sheet: unknown) => (typeof sheet === 'object' && sheet !== null ? (sheet as { settings?: unknown }).settings : null))\n .filter((own): own is Record<string, unknown> => typeof own === 'object' && own !== null);\n }\n\n /**\n * Creates the editor components the columns of the declared sheets name, so the settings filter only looks\n * them up when the sheets bar shows a sheet.\n *\n * @param settings The `settings` input.\n */\n private createDeclaredSheetEditors(settings: GridSettings): void {\n this.declaredSheetSettings(settings).forEach((own) => {\n const columns = own.columns;\n\n if (!Array.isArray(columns)) {\n return;\n }\n\n columns.forEach((column: ColumnSettings, index: number) => {\n const editor = typeof column === 'object' && column !== null ? column.editor : undefined;\n\n if (this.isEditorComponentRefType(editor) || this.isAdvancedEditorComponentRefType(editor)) {\n this.appliedEditorRef(editor as Type<unknown>, this.editorColumnKey(column, index));\n }\n });\n });\n }\n\n /**\n * Returns the key the editor component of a column is shared by: the column's `data` binding when it is a\n * string or a number, else its position. A function binding is a new value whenever the app builds the\n * column again, so it would make a new component each time.\n *\n * @param column The column.\n * @param index The column's position.\n * @returns The key.\n */\n private editorColumnKey(column: ColumnSettings, index: number): unknown {\n const data = (column as Handsontable.ColumnSettings).data;\n\n return typeof data === 'string' || typeof data === 'number' ? data : index;\n }\n\n /**\n * Resolves each column of an applied payload.\n *\n * @param columns The columns of the payload.\n * @returns `columns` itself when no column needed resolving, a new array otherwise.\n */\n private resolveAppliedColumns(columns: ColumnSettings[]): ColumnSettings[] {\n const resolved = columns.map((column, index) => this.resolveAppliedColumn(column, index));\n\n return resolved.every((column, index) => column === columns[index]) ? columns : resolved;\n }\n\n /**\n * Resolves one column of an applied payload, once per column object.\n *\n * @param column The column.\n * @param index The column's position in the payload.\n * @returns The resolved column, or `column` itself when it holds nothing to resolve.\n */\n private resolveAppliedColumn(column: ColumnSettings, index: number): ColumnSettings {\n if (!this.needsResolution(column)) {\n return column;\n }\n\n const cached = this.appliedColumns.get(column);\n\n if (cached && this.isShallowEqual(cached.source, column)) {\n return cached.resolved;\n }\n\n const resolved = { ...column };\n const columnKey = this.editorColumnKey(column, index);\n\n this.resolveColumnRenderer(resolved);\n this.resolveColumnEditor(resolved, undefined, editorType => this.appliedEditorRef(editorType, columnKey));\n this.resolveColumnValidator(resolved);\n this.appliedColumns.set(column, { source: { ...column }, resolved });\n\n return resolved;\n }\n\n /**\n * Tells whether two column objects hold the same keys with the same values.\n *\n * @param a A column.\n * @param b Another column.\n * @returns `true` when no key differs.\n */\n private isShallowEqual(a: ColumnSettings, b: ColumnSettings): boolean {\n const aKeys = Object.keys(a);\n\n return aKeys.length === Object.keys(b).length &&\n aKeys.every(key => (a as Record<string, unknown>)[key] === (b as Record<string, unknown>)[key]);\n }\n\n /**\n * Returns the editor component kept for an editor type and a column, creating it the first time, in the\n * zone of the caller.\n *\n * @param editorType The editor component type.\n * @param columnKey The column's key (`editorColumnKey()`).\n * @returns The editor component.\n */\n private appliedEditorRef(editorType: Type<unknown>, columnKey: unknown): ComponentRef<HotCellEditorComponent<any>> {\n const byColumn = this.appliedEditorRefs.get(editorType) ?? new Map<unknown, ComponentRef<HotCellEditorComponent<any>>>();\n const known = byColumn.get(columnKey);\n\n if (known) {\n return known;\n }\n\n const created = createComponent(editorType, { environmentInjector: this.environmentInjector });\n\n byColumn.set(columnKey, created as ComponentRef<HotCellEditorComponent<any>>);\n this.appliedEditorRefs.set(editorType, byColumn);\n\n return created as ComponentRef<HotCellEditorComponent<any>>;\n }\n\n /**\n * Tells whether a column holds a renderer, an editor or a validator Handsontable cannot read as it is.\n *\n * @param column The column.\n * @returns `true` when the column needs resolving.\n */\n private needsResolution(column: ColumnSettings): boolean {\n return typeof column === 'object' && column !== null && (\n this.isCustomRenderer(column.renderer) ||\n this.isEditorComponentRefType(column.editor) ||\n this.isAdvancedEditorComponentRefType(column.editor) ||\n this.isCustomValidatorFn(column.validator)\n );\n }\n\n /**\n * Returns the zone wrappers of the hook callbacks a payload holds that the `settings` input declared and\n * that are not wrapped yet.\n *\n * @param settings The payload.\n * @returns The wrappers by hook name, or `null` when there is nothing to wrap.\n */\n private zoneWrappedHooksOf(settings: SettingsUpdate): Record<string, unknown> | null {\n let wrapped: Record<string, unknown> | null = null;\n\n Object.keys(settings).forEach((key) => {\n const option: unknown = settings[key as keyof SettingsUpdate];\n const zoned = AVAILABLE_HOOKS_SET.has(key)\n ? this.zonedHookValue(option, callback => this.isDeclaredHook(key, callback))\n : option;\n\n if (zoned !== option) {\n wrapped = { ...wrapped, [key]: zoned };\n }\n });\n\n return wrapped;\n }\n\n /**\n * Ensures that hook callbacks in the provided grid settings run inside Angular's zone.\n *\n * @param settings The original grid settings.\n */\n private wrapHooksInNgZone(settings: GridSettings): void {\n // Iterate only the keys actually present in settings instead of all ~100 registered HOT hooks.\n Object.keys(settings).forEach((key) => {\n if (AVAILABLE_HOOKS_SET.has(key)) {\n settings[key] = this.zonedHookValue(settings[key], () => true);\n }\n });\n }\n\n /**\n * Returns a hook value with its callback wrapped in Angular's zone. Only a function is wrapped: an array of\n * callbacks is kept as it is, so its callbacks run as given, outside the zone, which is the rule the\n * `settings` input has always had (a per-cell hook given as an array stays free of change detection). A\n * callback that is already a wrapper, or that `shouldWrap` rejects, is kept too.\n *\n * @param option The hook value.\n * @param shouldWrap Tells whether a callback is wrapped.\n * @returns The value to apply: `option` itself when nothing was wrapped.\n */\n private zonedHookValue(option: unknown, shouldWrap: (callback: Function) => boolean): unknown {\n return typeof option === 'function' && !(option as any)[HOT_ZONE_WRAPPED] && shouldWrap(option)\n ? this.zoneWrapped(option)\n : option;\n }\n\n /**\n * Returns the function that runs a hook callback inside Angular's zone, the same one for every call\n * with the same callback.\n *\n * @param callback The hook callback.\n * @returns The wrapper.\n */\n private zoneWrapped(callback: Function): Function {\n const known = this.zoneWrappers.get(callback);\n\n if (known) {\n return known;\n }\n\n const ngZone = this.ngZone;\n const wrapped = function (...args: any) {\n return ngZone.run(() => callback.apply(this, args));\n };\n\n (wrapped as any)[HOT_ZONE_WRAPPED] = true;\n (wrapped as any)[FORWARDED_HOOK_CALLBACK] = callback;\n this.zoneWrappers.set(callback, wrapped);\n\n return wrapped;\n }\n\n /**\n * Replaces a custom renderer of a column with a renderer function.\n *\n * @param cellSettings The column, a copy the caller owns.\n */\n private resolveColumnRenderer(cellSettings: ColumnSettings): void {\n const renderer = cellSettings.renderer;\n\n if (!this.isCustomRenderer(renderer)) {\n return;\n }\n\n const props: any = cellSettings.rendererProps ?? {};\n\n if (this.isAdvancedRendererComponentRefType(renderer)) {\n cellSettings.renderer = this.dynamicComponentService.createRendererWithFactory(renderer, props);\n } else {\n cellSettings.renderer = this.dynamicComponentService.createRendererFromComponent(renderer, props);\n }\n }\n\n /**\n * Replaces an editor component of a column with an editor class, and creates the component.\n *\n * @param cellSettings The column, a copy the caller owns.\n * @param previousColumn The column at the same index in the previous settings cycle, used to\n * recycle its editor component.\n * @param sharedEditorRef Returns the editor component to use for an editor type when the previous\n * column has none to recycle, instead of creating a new one.\n * @returns The editor component the column holds now, or `undefined` when it declares none.\n */\n private resolveColumnEditor(\n cellSettings: ColumnSettings,\n previousColumn?: ColumnSettings,\n sharedEditorRef?: (editorType: Type<unknown>) => ComponentRef<HotCellEditorComponent<any>>\n ): ComponentRef<HotCellEditorComponent<any>> | undefined {\n const isAdvanced = this.isAdvancedEditorComponentRefType(cellSettings.editor);\n const isBasic = this.isEditorComponentRefType(cellSettings.editor);\n\n if (!isAdvanced && !isBasic) {\n return undefined;\n }\n\n const editorType = cellSettings.editor as Type<HotCellEditorComponent<any>> | Type<HotCellEditorAdvancedComponent<any>>;\n const reusableRef = this.reusableEditorRef(previousColumn, cellSettings, editorType);\n const internalSettings = cellSettings as ColumnSettingsInternal;\n\n // Recycle the editor component from the previous settings cycle when the same editor type\n // sits at the same column index AND the same logical column (by `data`) still occupies it.\n // Recreating it on every settings change would tear down and rebuild an Angular component\n // (and its DOM/internal state) for no reason. The reused ref is carried into the new column;\n // HotTableComponent.ngOnChanges detects it by identity and skips destroying it.\n const component = reusableRef ?? sharedEditorRef?.(editorType) ?? createComponent(editorType as Type<any>, {\n environmentInjector: this.environmentInjector,\n });\n\n internalSettings._editorComponentReference = component as ComponentRef<HotCellEditorComponent<any>>;\n\n if (isAdvanced) {\n cellSettings.editor = FactoryEditorAdapter(component as ComponentRef<HotCellEditorAdvancedComponent<any>>);\n } else {\n internalSettings._environmentInjector = this.environmentInjector;\n cellSettings.editor = BaseEditorAdapter;\n }\n\n return internalSettings._editorComponentReference;\n }\n\n /**\n * Returns the previous column's editor component ref when it can be reused for the new column, or\n * `undefined` to signal a fresh component is needed.\n *\n * A ref is only recycled when, at the same index, both the editor component type AND the logical\n * column identity (its `data` binding) are unchanged. The component-type check alone would already\n * be functionally safe — a Handsontable editor is not per-cell rendered state but a single\n * on-demand component that `BaseEditorAdapter`/`FactoryEditorAdapter` re-prepare on every edit\n * (`prepare()` re-reads the ref from the *current* column meta and `applyPropsToEditor()` re-applies\n * the full cell context on each `open()`). The extra `data` check is a defensive guard: when columns\n * are reordered/shortened so a *different* logical column lands on an index, we build a fresh editor\n * rather than carry the previous column's instance over, so no custom editor that caches\n * column-specific config at construction can leak stale state into the new cell.\n *\n * @param previousColumn The column at the same index in the previous settings cycle.\n * @param currentColumn The column now occupying this index.\n * @param editorType The editor component type requested for the new column.\n */\n private reusableEditorRef(\n previousColumn: ColumnSettings | undefined,\n currentColumn: ColumnSettings,\n editorType: Type<unknown>\n ): ComponentRef<any> | undefined {\n const previousRef = (previousColumn as ColumnSettingsInternal | undefined)?._editorComponentReference;\n\n if (!previousRef || previousRef.componentType !== editorType) {\n return undefined;\n }\n\n // Same logical column still occupies this index. Columns without a `data` binding are identified\n // purely by position, so two `undefined` data values compare equal and recycle as before.\n const sameLogicalColumn =\n (previousColumn as Handsontable.ColumnSettings | undefined)?.data ===\n (currentColumn as Handsontable.ColumnSettings).data;\n\n return sameLogicalColumn ? previousRef : undefined;\n }\n\n /**\n * Replaces a validator that returns a boolean with one that answers through the callback.\n *\n * @param cellSettings The column, a copy the caller owns.\n */\n private resolveColumnValidator(cellSettings: ColumnSettings): void {\n const customValidatorFn = cellSettings.validator;\n\n if (!this.isCustomValidatorFn(customValidatorFn)) {\n return;\n }\n\n cellSettings.validator = (value: any, callback: (result: boolean) => void) => {\n callback(customValidatorFn(value));\n };\n }\n\n private isCustomValidatorFn(validator: unknown): validator is CustomValidatorFn<any> {\n return typeof validator === 'function' && validator.length === 1;\n }\n\n private isEditorComponentRefType(editor: any): editor is Type<HotCellEditorComponent<any>> {\n // ecmp - we need it to check if the editor is a component\n return typeof editor === 'function' &&\n !!(editor as any)?.ɵcmp &&\n (editor as any)?.EDITOR_MARKER === HotCellEditorComponent.EDITOR_MARKER;\n }\n\n private isAdvancedEditorComponentRefType(editor: any): editor is Type<HotCellEditorAdvancedComponent<any>> {\n // ecmp - we need it to check if the editor is a component\n return typeof editor === 'function' &&\n !!(editor as any)?.ɵcmp &&\n (editor as any)?.EDITOR_MARKER === HotCellEditorAdvancedComponent.EDITOR_MARKER;\n }\n\n private isRendererComponentRefType(renderer: any): renderer is Type<HotCellRendererComponent<any, any>> {\n // ecmp - we need it to check if the renderer is a component\n return typeof renderer === 'function' &&\n !!(renderer as any)?.ɵcmp &&\n (renderer as any)?.RENDERER_MARKER === HotCellRendererComponent.RENDERER_MARKER;\n }\n\n private isAdvancedRendererComponentRefType(renderer: any): renderer is Type<HotCellRendererAdvancedComponent<any, any>> {\n // ecmp - we need it to check if the renderer is a component\n return typeof renderer === 'function' &&\n !!(renderer as any)?.ɵcmp &&\n (renderer as any)?.RENDERER_MARKER === HotCellRendererAdvancedComponent.RENDERER_MARKER;\n }\n\n private isTemplateRef(renderer: any): renderer is TemplateRef<any> {\n return renderer && typeof renderer.createEmbeddedView === 'function';\n }\n\n private isCustomRenderer(renderer: any): renderer is Type<HotCellRendererComponent<any, any>> |\n TemplateRef<any> |\n Type<HotCellRendererAdvancedComponent<any, any>> {\n return this.isRendererComponentRefType(renderer) ||\n this.isTemplateRef(renderer) ||\n this.isAdvancedRendererComponentRefType(renderer);\n }\n}\n","import {Injectable, InjectionToken, Inject} from '@angular/core';\nimport {BehaviorSubject, Observable} from 'rxjs';\n\n/**\n * A constant representing the non-commercial and evaluation license.\n * */\nexport const NON_COMMERCIAL_LICENSE = 'non-commercial-and-evaluation';\n\n/**\n * Type representing a theme name.\n * Possible values include predefined themes and any custom string.\n */\nexport enum PredefinedTheme {\n Main = 'ht-theme-main',\n MainDark = 'ht-theme-main-dark',\n MainDarkAuto = 'ht-theme-main-dark-auto',\n Horizon = 'ht-theme-horizon',\n HorizonDark = 'ht-theme-horizon-dark',\n HorizonDarkAuto = 'ht-theme-horizon-dark-auto'\n}\n\nexport type ThemeName = PredefinedTheme | string;\n\n/**\n * Interface for the Handsontable global configuration.\n */\nexport interface HotGlobalConfig {\n /**\n * The license key for Handsontable.\n */\n license?: string;\n\n /**\n * The name of the theme to be used.\n */\n themeName?: ThemeName;\n\n /**\n * The theme to be used (ThemeBuilder instance or theme name string).\n * When set, takes precedence over `themeName` for Handsontable 17+.\n */\n theme?: object | string;\n\n /**\n * The language code to be used for localization.\n * For example, 'en-US', 'pl-PL', etc.\n * **Note:** The language must be chosen from the languages supported by Handsontable and registered in the application.\n */\n language?: string;\n\n /**\n * The layout direction for the Handsontable instance.\n * This property defines whether the layout should be left-to-right ('ltr'), right-to-left ('rtl'),\n * or inherit the direction from the parent element ('inherit').\n */\n layoutDirection?: 'ltr' | 'rtl' | 'inherit';\n}\n\n/**\n * Injection token for providing a global default configuration.\n */\nexport const HOT_GLOBAL_CONFIG = new InjectionToken<HotGlobalConfig>('HOT_GLOBAL_CONFIG', {\n providedIn: 'root',\n factory: () => ({})\n});\n\n/**\n * Service for configuring Handsontable settings.\n * This service allows setting and retrieving global configuration.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class HotGlobalConfigService {\n\n /**\n * The default configuration object for Handsontable.\n *\n * This object is used as the initial value for the configuration BehaviorSubject.\n * It can be overridden by a global configuration provided through the\n * {@link HOT_GLOBAL_CONFIG} injection token.\n *\n * @private\n * @type {HotGlobalConfig}\n */\n private defaultConfig: HotGlobalConfig = {};\n\n /**\n * A BehaviorSubject that holds the current Handsontable configuration.\n *\n * New configuration values can be emitted by calling next() on this subject.\n * This allows subscribers to react to configuration changes dynamically.\n *\n * @private\n * @type {BehaviorSubject<HotGlobalConfig>}\n */\n private configSubject = new BehaviorSubject<HotGlobalConfig>(this.defaultConfig);\n\n /**\n * An Observable stream of the current Handsontable configuration.\n *\n * Components can subscribe to this observable to receive updates whenever the configuration changes.\n *\n * @returns The configuration as an observable stream.\n */\n get config$(): Observable<HotGlobalConfig> {\n return this.configSubject.asObservable();\n }\n\n constructor(\n @Inject(HOT_GLOBAL_CONFIG) globalConfig: HotGlobalConfig\n ) {\n // Merge global configuration (if provided) into defaultConfig immutably.\n this.defaultConfig = { ...this.defaultConfig, ...globalConfig };\n this.configSubject.next(this.defaultConfig);\n }\n\n /**\n * Sets the global configuration for Handsontable.\n *\n * @param config - An object containing configuration options.\n * Each Handsontable instance can override this configuration by providing its own settings.\n */\n setConfig(config: HotGlobalConfig) {\n this.configSubject.next({ ...this.defaultConfig, ...config });\n }\n\n /**\n * Retrieves the current Handsontable configuration.\n *\n * @returns An object with the current settings.\n */\n getConfig(): HotGlobalConfig {\n return this.configSubject.value;\n }\n\n /**\n * Resets the configuration to the default settings.\n * This method updates the configuration BehaviorSubject with the default configuration.\n */\n resetConfig(): void {\n this.configSubject.next({ ...this.defaultConfig });\n }\n}\n","import {\n AfterViewInit,\n Component,\n DestroyRef,\n ElementRef,\n EnvironmentInjector,\n Input,\n NgZone,\n OnChanges,\n OnDestroy,\n PLATFORM_ID,\n SimpleChanges,\n ViewChild,\n ViewEncapsulation,\n inject\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport Handsontable from 'handsontable/base';\nimport { HotSettingsResolver } from './services/hot-settings-resolver.service';\nimport { HotGlobalConfigService } from './services/hot-global-config.service';\nimport { GridSettings } from './models/grid-settings';\nimport { DynamicComponentService } from './renderer/hot-dynamic-renderer-component.service';\nimport { HotInstanceWithAngularInjector } from './editor/models/factory-editor-properties';\nimport { ColumnSettingsInternal } from './models/column-settings';\nimport { skip } from 'rxjs/operators';\n\nexport const HOT_DESTROYED_WARNING = 'The Handsontable instance bound to this component was destroyed and cannot be' + ' used properly.';\n\n/**\n * The size options that discard the sizes stored by the manual resize plugins when they are passed\n * to `updateSettings()`.\n */\nconst SIZE_SETTING_KEYS = new Set<string>(['rowHeights', 'minRowHeights', 'colWidths']);\n\n/**\n * Checks whether a hook value holds a callback core registers: a function or an array of them.\n *\n * @param value The hook value.\n * @returns `true` for a function or an array.\n */\nfunction isHookCallback(value: unknown): boolean {\n return typeof value === 'function' || Array.isArray(value);\n}\n\n/**\n * Compares two size option values. Both hold a number, a string, a function or an array of numbers\n * or strings, so an element-wise walk is enough - and it is what makes a value written inline in a\n * template, which is a new array on every change detection run, compare as unchanged.\n *\n * A function is compared by reference only. It states no fixed size, and the core plugins ignore it\n * when deciding whether the sizes were re-declared, so forwarding it changes nothing either way.\n *\n * @param currentValue The value the grid currently holds.\n * @param newValue The value coming from the `settings` input.\n * @returns `true` when the two state the same sizes.\n */\nfunction isSameSizeSetting(currentValue: unknown, newValue: unknown): boolean {\n if (currentValue === newValue) {\n return true;\n }\n\n if (Array.isArray(currentValue) && Array.isArray(newValue)) {\n return currentValue.length === newValue.length &&\n currentValue.every((value, index) => value === newValue[index]);\n }\n\n return false;\n}\n\n/**\n * The class that makes the container and the host fill their parent. The component styles below\n * spell the same name, because decorator metadata must stay statically analyzable.\n */\nconst FILL_HEIGHT_CLASS_NAME = 'ht-fill-height';\n\n/**\n * A `height` that resolves against the container: a percentage, or a `var()` that may hold one.\n * The core treats the same two as container-driven in `utils/rootSize.ts`, together with units that\n * resolve against the viewport or a query container, which do not depend on the container here.\n */\nconst RELATIVE_HEIGHT_PATTERN = /%|\\bvar\\(/i;\n\n@Component({\n selector: 'hot-table',\n template: '<div #container></div>',\n encapsulation: ViewEncapsulation.None,\n providers: [HotSettingsResolver],\n styles: [\n `\n :host {\n display: block;\n }\n\n :where(hot-table.ht-fill-height, hot-table > div.ht-fill-height) {\n height: 100%;\n }\n `,\n ],\n})\nexport class HotTableComponent implements AfterViewInit, OnChanges, OnDestroy {\n // component inputs\n /** The data for the Handsontable instance. */\n @Input() data: Handsontable.GridSettings['data'] | null = null;\n /** The settings for the Handsontable instance. */\n @Input() settings: GridSettings = {};\n\n /** The container element for the Handsontable instance. */\n @ViewChild('container', { static: false })\n public container: ElementRef<HTMLDivElement>;\n\n /** The Handsontable instance. */\n private __hotInstance: Handsontable | null = null;\n private readonly _destroyRef = inject(DestroyRef);\n private readonly _host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly isBrowser = inject(PLATFORM_ID) === 'browser';\n /**\n * The grid-level `columns` resolved from the `settings` input on the last change that carried them.\n * They hold the editor components this component created for them. The grid's own `columns` is not\n * where to find them: while the sheets bar shows a sheet that declares its own `columns`, it holds that\n * sheet's.\n */\n private _gridColumns: ColumnSettingsInternal[] | undefined;\n /**\n * The hooks the last applied `settings` input passed a callback for. A hook in this set that the next\n * input leaves out is sent as `null`. It is read from what the component sent, not from the previous\n * input, because an app may delete the key from that object before passing a copy.\n */\n private _passedHookKeys = new Set<string>();\n\n constructor(\n private _hotSettingsResolver: HotSettingsResolver,\n private _hotConfig: HotGlobalConfigService,\n public ngZone: NgZone,\n private readonly environmentInjector: EnvironmentInjector,\n private readonly _dynamicComponentService: DynamicComponentService\n ) {}\n\n /**\n * Gets the Handsontable instance.\n * @returns The Handsontable instance, or `null` when it is not created yet, it has been\n * destroyed, or this component is rendering on the server.\n */\n public get hotInstance(): Handsontable | null {\n if (!this.__hotInstance || !this.__hotInstance.isDestroyed) {\n // Will return the Handsontable instance or `null` if it's not yet been created.\n return this.__hotInstance;\n } else {\n console.warn(HOT_DESTROYED_WARNING);\n return null;\n }\n }\n\n /**\n * Sets the Handsontable instance.\n * @param hotInstance The Handsontable instance to set.\n */\n private set hotInstance(hotInstance) {\n this.__hotInstance = hotInstance;\n }\n\n /**\n * Initializes the Handsontable instance after the view has been initialized.\n * The initial settings of the table are also prepared here\n */\n ngAfterViewInit(): void {\n // The server DOM has no `getRootNode`, and constructing the grid there throws on every\n // request. `afterNextRender` skips the server too, but it shipped in Angular 16.2 and this\n // wrapper still supports 16.0.\n if (!this.isBrowser) {\n return;\n }\n\n let options: Handsontable.GridSettings = this._hotSettingsResolver.applyCustomSettings(this.settings);\n\n if (Array.isArray(options.columns)) {\n this._gridColumns = options.columns;\n }\n\n this._passedHookKeys = this.collectHookKeys(options);\n\n const negotiatedSettings = this.getNegotiatedSettings(options);\n options = { ...options, ...negotiatedSettings, ...(this.data != null ? { data: this.data } : {}) };\n\n this.ngZone.runOutsideAngular(() => {\n this.hotInstance = new Handsontable.Core(this.container.nativeElement, options);\n\n (this.hotInstance as HotInstanceWithAngularInjector)._angularEnvironmentInjector = this.environmentInjector;\n\n this.hotInstance._addSettingsFilter?.(settings => this._hotSettingsResolver.resolveAppliedSettings(settings));\n\n // Registered before `init()`, so the hook also sees the initial `height`, before the first render.\n this.hotInstance.addHook('beforeHeightChange', (height) => {\n this.toggleFillHeight(height);\n\n return height;\n });\n\n this.hotInstance.init();\n });\n\n this._hotConfig.config$.pipe(skip(1), takeUntilDestroyed(this._destroyRef)).subscribe((config) => {\n if (this.hotInstance) {\n const negotiatedSettings = this.getNegotiatedSettings(this.settings);\n this.updateHotTable(negotiatedSettings);\n }\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (this.hotInstance === null) {\n return;\n }\n\n if (changes.settings && !changes.settings.firstChange) {\n // Capture old editor refs before applying new settings so HOT can close any active editor first.\n const prevColumnsArray = this._gridColumns;\n\n // Pass the previous columns so unchanged editor types recycle their existing component\n // instead of creating a fresh one on every settings change.\n const newOptions: Handsontable.GridSettings = this._hotSettingsResolver.applyCustomSettings(\n changes.settings.currentValue,\n prevColumnsArray\n );\n\n this.clearRemovedHooks(newOptions);\n this._passedHookKeys = this.collectHookKeys(newOptions);\n\n // updateHotTable closes any active editor via HOT.updateSettings before we destroy old refs.\n this.updateHotTable(newOptions);\n\n // Only destroy old editor refs when new settings actually replace columns.\n // If newOptions has no columns, HOT keeps the old column objects active — destroying\n // their refs would crash FactoryEditorAdapter / BaseEditorAdapter on next edit.\n if (prevColumnsArray && Array.isArray(newOptions.columns)) {\n // Refs recycled into the new columns must survive — destroy only the ones left behind.\n const reusedRefs = new Set(\n newOptions.columns\n .map((column) => column._editorComponentReference)\n .filter((ref): ref is NonNullable<typeof ref> => !!ref)\n );\n\n prevColumnsArray.forEach((column) => {\n if (column._editorComponentReference && !reusedRefs.has(column._editorComponentReference)) {\n column._editorComponentReference.destroy();\n }\n });\n }\n\n if (Array.isArray(newOptions.columns)) {\n this._gridColumns = newOptions.columns;\n }\n }\n\n if (changes.data && !changes.data.firstChange) {\n this.hotInstance?.updateData(changes.data.currentValue);\n }\n }\n\n /**\n * Destroys the Handsontable instance and clears the columns from custom editors.\n */\n ngOnDestroy(): void {\n this.ngZone.runOutsideAngular(() => {\n if (!this.__hotInstance) {\n return;\n }\n\n const isLive = !this.__hotInstance.isDestroyed;\n\n // Destroy renderer Angular components attached to table cells before HOT removes the DOM.\n if (isLive && this.container) {\n this._dynamicComponentService.cleanupContainer(this.container.nativeElement, this.__hotInstance);\n }\n\n this._gridColumns?.forEach((column) => {\n if (column._editorComponentReference) {\n column._editorComponentReference.destroy();\n }\n });\n this._gridColumns = undefined;\n this._hotSettingsResolver.destroyAppliedEditors();\n\n if (isLive) {\n this.__hotInstance.destroy();\n }\n });\n }\n\n /**\n * Makes the container and the `<hot-table>` host fill their parent when the grid `height` is\n * relative.\n *\n * The core puts its root wrapper inside the container, and the `height: 100%` of the grid content\n * resolves against the container. An auto-height container makes that `100%` collapse to `0px`, so\n * the container has to pass the height of its parent through. React and Vue always do. Here it\n * happens only for a relative `height` (`%` or `var()`), so grids with other heights keep their\n * layout. The rule is a zero-specificity `:where()`, so any CSS of the app overrides it.\n *\n * @param height The value the `beforeHeightChange` hook received. It is the result of a `height`\n * function, and it is `null` when the `height` is reset.\n */\n private toggleFillHeight(height: unknown): void {\n const fillHeight = typeof height === 'string' && RELATIVE_HEIGHT_PATTERN.test(height);\n\n this.container.nativeElement.classList.toggle(FILL_HEIGHT_CLASS_NAME, fillHeight);\n this._host.nativeElement.classList.toggle(FILL_HEIGHT_CLASS_NAME, fillHeight);\n }\n\n /**\n * Sets to `null` each hook the component last passed a callback for and the new settings do not, so\n * `updateSettings()` removes that callback. A key missing from the new object is otherwise left out of\n * the payload, and core keeps the callback.\n *\n * @param newOptions The settings about to be applied. Changed in place.\n */\n private clearRemovedHooks(newOptions: Handsontable.GridSettings): void {\n this._passedHookKeys.forEach((key) => {\n if (!isHookCallback(newOptions[key])) {\n newOptions[key] = null;\n }\n });\n }\n\n /**\n * Lists the hooks the settings pass a callback for. A key counts as a hook by the rule core's\n * `updateSettings()` uses in `core.ts`: a registered or a deprecated hook name. Only a function or an\n * array of them counts as a callback: core ignores any other value, such as `false`.\n *\n * @param settings The settings to read.\n * @returns The hook names.\n */\n private collectHookKeys(settings: Handsontable.GridSettings): Set<string> {\n return new Set(Object.keys(settings).filter(key => (\n isHookCallback(settings[key]) &&\n (Handsontable.hooks.isRegistered(key) || Handsontable.hooks.isDeprecated(key))\n )));\n }\n\n /**\n * Updates the Handsontable instance with new settings.\n * @param newSettings The new settings to apply to the Handsontable instance.\n */\n private updateHotTable(newSettings: Handsontable.GridSettings): void {\n if (!this.hotInstance) {\n return;\n }\n\n const currentSettings = this.hotInstance.getSettings();\n const initOnlySettingKeys = new Set<string>(\n (currentSettings as any)?._initOnlySettings ?? []\n );\n const filteredSettings: Handsontable.GridSettings = {};\n\n for (const key of Object.keys(newSettings)) {\n if (initOnlySettingKeys.has(key)) {\n continue;\n }\n\n // `ngOnChanges` fires for the whole settings object, so every key is re-passed whenever any\n // one of them changes. Passing `rowHeights` or `colWidths` re-declares the sizes and discards\n // the ones the user produced by dragging, so an unchanged value must not be forwarded.\n if (\n SIZE_SETTING_KEYS.has(key) &&\n isSameSizeSetting((currentSettings as any)?.[key], (newSettings as any)[key])\n ) {\n continue;\n }\n\n (filteredSettings as any)[key] = (newSettings as any)[key];\n }\n\n this.ngZone.runOutsideAngular(() => {\n this.hotInstance?.updateSettings(filteredSettings, false);\n });\n }\n\n /**\n * Merges the provided Handsontable grid settings with the global configuration.\n *\n * This method retrieves the global configuration from the HotGlobalConfigService and negotiates the final\n * Handsontable settings by giving precedence to the provided settings.\n * Additionally, the `layoutDirection` is only merged if the Handsontable instance has not yet been initialized.\n *\n * @param settings - The grid settings provided by the user or component.\n * @returns The final negotiated grid settings after merging with global defaults.\n */\n private getNegotiatedSettings(settings: GridSettings): Handsontable.GridSettings {\n const hotConfig = this._hotConfig.getConfig();\n const negotiatedSettings: Handsontable.GridSettings = {};\n\n negotiatedSettings.licenseKey = settings.licenseKey ?? hotConfig.license;\n negotiatedSettings.language = settings.language ?? hotConfig.language;\n\n const theme = settings.theme ?? hotConfig.theme;\n const themeName = settings.themeName ?? hotConfig.themeName;\n\n if (theme !== undefined) {\n negotiatedSettings.theme = theme as Handsontable.GridSettings['theme'];\n } else if (themeName) {\n negotiatedSettings.themeName = themeName;\n }\n\n // settings that can be set only before the Handsontable instance is initialized\n if (!this.__hotInstance) {\n negotiatedSettings.layoutDirection = settings.layoutDirection ?? hotConfig.layoutDirection;\n }\n\n return negotiatedSettings;\n }\n}\n","import { NgModule } from '@angular/core';\nimport { HotTableComponent } from './hot-table.component';\n\n@NgModule({\n imports: [HotTableComponent],\n exports: [HotTableComponent],\n})\nexport class HotTableModule {\n static readonly version = '0.0.0-next-0491dcb-20261103';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"handsontable-angular-wrapper.mjs","names":["i1.DynamicComponentService","i1.HotSettingsResolver","i2.HotGlobalConfigService","i3.DynamicComponentService"],"sources":["../../../projects/hot-table/src/lib/editor/custom-editor-placeholder.component.ts","../../../projects/hot-table/src/lib/editor/base-editor-adapter.ts","../../../projects/hot-table/src/lib/renderer/hot-cell-renderer-base.directive.ts","../../../projects/hot-table/src/lib/renderer/hot-cell-renderer.component.ts","../../../projects/hot-table/src/lib/editor/hot-cell-editor-base.directive.ts","../../../projects/hot-table/src/lib/editor/hot-cell-editor.component.ts","../../../projects/hot-table/src/lib/editor/editor-factory-adapter.ts","../../../projects/hot-table/src/lib/renderer/hot-cell-renderer-advanced.component.ts","../../../projects/hot-table/src/lib/editor/hot-cell-editor-advanced.component.ts","../../../projects/hot-table/src/lib/renderer/hot-dynamic-renderer-component.service.ts","../../../projects/hot-table/src/lib/services/hot-settings-resolver.service.ts","../../../projects/hot-table/src/lib/services/hot-global-config.service.ts","../../../projects/hot-table/src/lib/hot-table.component.ts","../../../projects/hot-table/src/lib/hot-table.module.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ComponentRef, Input, ViewChild, ViewContainerRef } from '@angular/core';\nimport { HotCellEditorComponent } from './hot-cell-editor.component';\nimport { HotCellEditorAdvancedComponent } from './hot-cell-editor-advanced.component';\n\n/**\n * Component representing a placeholder for a custom editor in Handsontable.\n * It is used only within the wrapper.\n */\n@Component({\n template: ` <div\n [class]=\"placeholderCustomClass\"\n [style.display]=\"display\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n [style.maxWidth.px]=\"width\"\n [style.maxHeight.px]=\"height\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\"\n >\n <ng-template #inputPlaceholder></ng-template>\n </div>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class CustomEditorPlaceholderComponent {\n /** The top position of the editor. */\n @Input() top: number;\n\n /** The left position of the editor. */\n @Input() left: number;\n\n /** The height of the editor. */\n @Input() height: number;\n\n /** The width of the editor. */\n @Input() width: number;\n\n @Input()\n set isVisible(value: boolean) {\n this._isVisible = value;\n }\n\n @Input() placeholderCustomClass = 'handsontableInputHolder ht_clone_master';\n\n /** The reference to the component instance of the editor. */\n @Input() set componentRef(\n hotEditorComponentRef: ComponentRef<HotCellEditorComponent<any>> |\n ComponentRef<HotCellEditorAdvancedComponent<any>>) {\n if (hotEditorComponentRef) {\n this.container.insert(hotEditorComponentRef.hostView);\n }\n }\n\n /** The container for the editor's input placeholder. */\n @ViewChild('inputPlaceholder', { read: ViewContainerRef, static: true }) container: ViewContainerRef;\n\n /** The display style of the editor. */\n get display(): string {\n return this._isVisible ? 'block' : 'none';\n }\n\n private _isVisible = false;\n\n /**\n * Detaches the container from the Handsontable.\n */\n detachEditor(): void {\n this.container.detach();\n }\n}\n","import Handsontable from 'handsontable/base';\nimport {\n ComponentRef,\n createComponent,\n EnvironmentInjector,\n} from '@angular/core';\nimport { CustomEditorPlaceholderComponent } from './custom-editor-placeholder.component';\nimport { ColumnSettingsInternal } from '../models/column-settings';\nimport { HotCellEditorComponent } from './hot-cell-editor.component';\nimport { Subscription } from 'rxjs';\nimport { take } from 'rxjs/operators';\n\n/**\n * Adapter for BaseEditor from Handsontable.\n */\nexport class BaseEditorAdapter extends Handsontable.editors.BaseEditor {\n /** Reference to the custom editor component. */\n private _componentRef?: ComponentRef<HotCellEditorComponent<any>>;\n\n /** Reference to the editor placeholder component. */\n private _editorPlaceHolderRef: ComponentRef<CustomEditorPlaceholderComponent>;\n\n /** Flag indicating whether the placeholder is ready. */\n private _isPlaceholderReady = false;\n\n /** Subscription for the finish edit event. */\n private _finishEditSubscription?: Subscription;\n\n /** Subscription for the cancel edit event. */\n private _cancelEditSubscription?: Subscription;\n\n /**\n * Creates an instance of BaseEditorAdapter.\n * @param instance The Handsontable instance.\n */\n constructor(instance: Handsontable.Core) {\n super(instance);\n\n this.hot.addHook('afterRowResize', this.onAfterRowResize.bind(this));\n this.hot.addHook('afterColumnResize', this.onAfterColumnResize.bind(this));\n this.hot.addHook('afterDestroy', this.onAfterDestroy.bind(this));\n }\n\n /**\n * Prepares the editor for editing. Parameters are passed from Handsontable.\n * @param row The row index.\n * @param column The column index.\n * @param prop The property name.\n * @param TD The table cell element.\n * @param originalValue The original value of the cell.\n * @param cellProperties The cell properties.\n */\n override prepare(\n row: number,\n column: number,\n prop: string | number,\n TD: HTMLTableCellElement,\n originalValue: any,\n cellProperties: Handsontable.CellProperties\n ): void {\n if (!this.isOpened()) {\n super.prepare(row, column, prop, TD, originalValue, cellProperties);\n const columnMeta: ColumnSettingsInternal = this.hot.getColumnMeta(\n column\n ) as ColumnSettingsInternal;\n\n if (!this._isPlaceholderReady) {\n this.createEditorPlaceholder(columnMeta._environmentInjector);\n this._isPlaceholderReady = true;\n }\n\n this._componentRef = columnMeta._editorComponentReference;\n\n this.cleanupSubscriptions();\n\n this._finishEditSubscription = this._componentRef.instance.finishEdit\n .pipe(take(1))\n .subscribe(() => {\n this.finishEditing();\n });\n\n this._cancelEditSubscription = this._componentRef.instance.cancelEdit\n .pipe(take(1))\n .subscribe(() => {\n this.cancelChanges();\n });\n }\n }\n\n /**\n * Closes the editor. This event is triggered by Handsontable.\n */\n close(): void {\n if (this.isOpened()) {\n this.resetEditorState();\n this._editorPlaceHolderRef?.changeDetectorRef.detectChanges();\n this._editorPlaceHolderRef?.instance.detachEditor();\n this._componentRef?.instance.onClose();\n }\n }\n\n /**\n * Focuses the editor. This event is triggered by Handsontable.\n */\n focus(): void {\n this._componentRef?.instance.onFocus();\n }\n\n /**\n * Gets the value from the editor.\n * @returns The value from the editor.\n */\n getValue(): any {\n return this._componentRef?.instance?.getValue();\n }\n\n /**\n * Opens the editor. This event is triggered by Handsontable.\n * When opening, we set the shortcut context to 'editor'.\n * This allows the built-in keyboard shortcuts to operate within the editor.\n * @param event The event that triggered the opening of the editor.\n * @remarks When entering edit mode using double-click, keyboard shortcuts do not work.\n */\n open(event?: Event): void {\n this.hot.getShortcutManager().setActiveContextName('editor');\n this.applyPropsToEditor();\n this._componentRef?.instance.onOpen(event);\n }\n\n /**\n * Sets the value for the custom editor.\n * @param newValue The value to set.\n */\n setValue(newValue?: any): void {\n this._componentRef?.instance?.setValue(newValue);\n this._componentRef?.changeDetectorRef.detectChanges();\n }\n\n /**\n * Applies properties to the custom editor and editor placeholder.\n */\n private applyPropsToEditor(): void {\n if (!this._componentRef || !this._editorPlaceHolderRef) {\n return;\n }\n\n const rect = this.getEditedCellRect();\n\n if (!this.isInFullEditMode()) {\n this._componentRef.instance.setValue(null);\n }\n\n this._componentRef.setInput('originalValue', this.originalValue);\n this._componentRef.setInput('row', this.row);\n this._componentRef.setInput('column', this.col);\n this._componentRef.setInput('prop', this.prop);\n this._componentRef.setInput('cellProperties', this.cellProperties);\n\n this._editorPlaceHolderRef.setInput('top', rect.top);\n this._editorPlaceHolderRef.setInput('left', rect.start);\n this._editorPlaceHolderRef.setInput('height', rect.height);\n this._editorPlaceHolderRef.setInput('width', rect.width);\n this._editorPlaceHolderRef.setInput('isVisible', true);\n this._editorPlaceHolderRef.setInput('componentRef', this._componentRef);\n this._editorPlaceHolderRef.changeDetectorRef.detectChanges();\n }\n\n /**\n * Creates the editor placeholder and append it to hot rootElement.\n * @param injector The environment injector.\n */\n private createEditorPlaceholder(injector: EnvironmentInjector): void {\n this._editorPlaceHolderRef = createComponent(\n CustomEditorPlaceholderComponent,\n {\n environmentInjector: injector as EnvironmentInjector,\n }\n );\n\n this.hot.rootElement.appendChild(\n this._editorPlaceHolderRef.location.nativeElement\n );\n }\n\n /**\n * Handles the after column resize event.\n * Helps adjust the editor size to the column size and update its position.\n */\n private onAfterColumnResize(): void {\n if (this.isOpened()) {\n this.applyPropsToEditor();\n }\n }\n\n /**\n * Handles the after row resize event.\n * Helps adjust the editor size to the column size and update its position.\n */\n private onAfterRowResize(): void {\n if (this.isOpened()) {\n this.applyPropsToEditor();\n }\n }\n\n /**\n * Handles the after destroy event.\n */\n private onAfterDestroy(): void {\n this.cleanupSubscriptions();\n this._editorPlaceHolderRef?.destroy();\n }\n\n /**\n * Unsubscribes the finish/cancel edit subscriptions if they are still active.\n * Without this, destroying the table while an editor was prepared but never\n * finished/canceled leaves the `take(1)` subscriptions hanging (they never emit).\n */\n private cleanupSubscriptions(): void {\n if (this._finishEditSubscription) {\n this._finishEditSubscription.unsubscribe();\n this._finishEditSubscription = undefined;\n }\n\n if (this._cancelEditSubscription) {\n this._cancelEditSubscription.unsubscribe();\n this._cancelEditSubscription = undefined;\n }\n }\n\n /**\n * Resets the editor placeholder state.\n * We need to reset the editor placeholder state because we use it\n * to store multiple references to the custom editor.\n */\n private resetEditorState(): void {\n if (!this._editorPlaceHolderRef) {\n return;\n }\n\n this._editorPlaceHolderRef.setInput('top', undefined);\n this._editorPlaceHolderRef.setInput('left', undefined);\n this._editorPlaceHolderRef.setInput('height', undefined);\n this._editorPlaceHolderRef.setInput('width', undefined);\n this._editorPlaceHolderRef.setInput('isVisible', false);\n this._editorPlaceHolderRef.setInput('componentRef', undefined);\n }\n}\n","import Handsontable from 'handsontable/base';\nimport { Directive, Input } from '@angular/core';\n\n/**\n * Shared base directive for HotCellRendererComponent and HotCellRendererAdvancedComponent.\n * Holds all @Input() properties and getProps() that both renderer variants share.\n *\n * @template TValue - The type of the rendered cell value.\n * @template TProps - The type of additional renderer properties.\n */\n@Directive()\nexport abstract class HotCellRendererBase<\n TValue extends string | number | boolean | Record<string, any> | Array<any> = string,\n TProps extends {} = any\n> {\n @Input() value: TValue = '' as TValue;\n\n @Input() instance: Handsontable;\n @Input() td: HTMLTableCellElement;\n @Input() row: number;\n @Input() col: number;\n @Input() prop: string | number;\n\n @Input() cellProperties: Handsontable.CellProperties & { rendererProps?: TProps };\n\n public getProps(): TProps {\n return this.cellProperties?.rendererProps ?? ({} as TProps);\n }\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { HotCellRendererBase } from './hot-cell-renderer-base.directive';\n\n/**\n * Abstract base component for creating custom cell renderer components for Handsontable.\n *\n * Extend this component and provide your own template to implement a custom renderer.\n * Value type is limited to primitives (`string | number | boolean`).\n * For object and array values use {@link HotCellRendererAdvancedComponent}.\n *\n * @template TValue - The type of the component renderer.\n * @template TProps - The type of additional renderer properties.\n */\n@Component({\n selector: 'hot-cell-renderer',\n template: `<!-- This is an abstract component. Extend this component and provide your own template. -->`,\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport abstract class HotCellRendererComponent<TValue extends string | number | boolean = string, TProps extends {} = any>\n extends HotCellRendererBase<TValue, TProps> {\n static readonly RENDERER_MARKER = Symbol('HotCellRendererComponent');\n}\n","import Handsontable from 'handsontable/base';\nimport { Directive, EventEmitter, HostBinding, Input, Output } from '@angular/core';\n\n/**\n * Shared base directive for HotCellEditorComponent and HotCellEditorAdvancedComponent.\n * Holds all @Input(), @Output() and @HostBinding() declarations that both editor variants share.\n *\n * @template T - The type of the edited cell value.\n */\n@Directive()\nexport abstract class HotCellEditorBase<\n T extends string | number | boolean | Record<string, any> | Array<any>\n> {\n @HostBinding('style.height.%') protected heightFitParentContainer = 100;\n @HostBinding('style.width.%') protected widthFitParentContainer = 100;\n\n @Input() row: number;\n @Input() column: number;\n @Input() prop: string | number;\n @Input() originalValue: T;\n @Input() cellProperties: Handsontable.CellProperties;\n\n @Output() finishEdit = new EventEmitter<void>();\n @Output() cancelEdit = new EventEmitter<void>();\n\n protected value: T;\n\n getValue(): T {\n return this.value;\n }\n\n setValue(value: T): void {\n this.value = value;\n }\n}\n","import { Directive, HostBinding } from '@angular/core';\nimport { HotCellEditorBase } from './hot-cell-editor-base.directive';\n\n/**\n * Abstract class representing a basic Handsontable cell editor in Angular.\n *\n * Extend this class and decorate the subclass with `@Component()` to implement a custom editor.\n * Value type is limited to primitives (`string | number | boolean`).\n * For object and array values use {@link HotCellEditorAdvancedComponent}.\n */\n@Directive()\nexport abstract class HotCellEditorComponent<T extends string | number | boolean> extends HotCellEditorBase<T> {\n static readonly EDITOR_MARKER = Symbol('HotCellEditorComponent');\n\n /** The tabindex attribute for the editor. */\n @HostBinding('attr.tabindex') protected tabindex = -1;\n\n /** The data-hot-input attribute for the editor. */\n @HostBinding('attr.data-hot-input') protected dataHotInput = '';\n\n /** The handsontableInput class for the editor. */\n @HostBinding('class.handsontableInput') protected handsontableInputClass = true;\n\n /** Event triggered by Handsontable on closing the editor. */\n onClose(): void {}\n\n /** Event triggered by Handsontable on opening the editor. */\n onOpen(event?: Event): void {}\n\n /**\n * Event triggered by Handsontable on focusing the editor.\n * Must be implemented by the subclass to move focus to the actual input element.\n * @example\n * ```typescript\n * @Component({ template: `<input #inputElement>` })\n * class CustomEditor extends HotCellEditorComponent<string> {\n * @ViewChild('inputElement') inputElement!: ElementRef;\n * onFocus(): void { this.inputElement.nativeElement.focus(); }\n * }\n * ```\n */\n abstract onFocus(): void;\n}\n","import { ComponentRef, createComponent, EnvironmentInjector } from '@angular/core';\nimport { CustomEditorPlaceholderComponent } from './custom-editor-placeholder.component';\nimport { AngularEditorProperties, HotInstanceWithAngularInjector } from './models/factory-editor-properties';\nimport { editorFactory, ExtendedEditor } from 'handsontable/editors/factory';\nimport { take } from 'rxjs/operators';\nimport { HotCellEditorAdvancedComponent } from './hot-cell-editor-advanced.component';\n\n/**\n * Combined type representing an extended editor with Angular component properties.\n * Used internally by the factory adapter to bridge Angular and Handsontable.\n */\ntype EditorInstance = ExtendedEditor<AngularEditorProperties & HotCellEditorAdvancedComponent<any>>;\n\n/**\n * Factory function to create a custom Handsontable editor adapter for Angular components.\n *\n * This adapter integrates Angular components with Handsontable's editor system using the new\n * editorFactory API, allowing you to use Angular components as custom cell editors while\n * maintaining full Angular lifecycle management and change detection.\n *\n * @returns A custom editor class that can be used in Handsontable column settings.\n *\n */\nexport const FactoryEditorAdapter = (componentRef: ComponentRef<HotCellEditorAdvancedComponent<any>>) =>\n editorFactory<ExtendedEditor<any>>({\n position: componentRef.instance.position,\n shortcuts: componentRef.instance.shortcuts,\n shortcutsGroup: componentRef.instance.shortcutsGroup,\n config: componentRef.instance.config,\n init(editor: EditorInstance): void {\n editor._componentRef = componentRef;\n editor._editorPlaceHolderRef = undefined;\n editor._finishEditSubscription = undefined;\n editor._cancelEditSubscription = undefined;\n\n createEditorPlaceholder(editor, (editor.hot as HotInstanceWithAngularInjector)._angularEnvironmentInjector);\n editor.input = editor._editorPlaceHolderRef?.location.nativeElement ?? document.createElement('div');\n\n editor._afterRowResizeCallback = (): void => {\n if (editor.isOpened()) {\n applyPropsToEditor(editor);\n }\n };\n\n editor._afterColumnResizeCallback = (): void => {\n if (editor.isOpened()) {\n applyPropsToEditor(editor);\n }\n };\n\n editor._afterDestroyCallback = (): void => {\n cleanupSubscriptions(editor);\n if (editor._editorPlaceHolderRef) {\n editor._editorPlaceHolderRef.destroy();\n }\n };\n\n // Hooks are automatically removed by Handsontable on table destroy\n editor.hot.addHook('afterRowResize', editor._afterRowResizeCallback);\n editor.hot.addHook('afterColumnResize', editor._afterColumnResizeCallback);\n editor.hot.addHook('afterDestroy', editor._afterDestroyCallback);\n },\n\n afterInit: (editor) => editor._componentRef.instance.afterInit?.(editor),\n beforeOpen: (editor: EditorInstance, context) => {\n cleanupSubscriptions(editor);\n\n applyPropsToEditor(editor);\n\n editor._finishEditSubscription = editor._componentRef.instance.finishEdit.pipe(take(1)).subscribe((): void => {\n editor.finishEditing();\n });\n\n editor._cancelEditSubscription = editor._componentRef.instance.cancelEdit.pipe(take(1)).subscribe((): void => {\n editor.cancelChanges();\n });\n editor._componentRef.instance.beforeOpen?.(editor, context);\n },\n afterOpen: (editor, event) => {\n editor._componentRef.instance.afterOpen?.(editor, event);\n },\n onFocus: (editor) => editor._componentRef.instance.onFocus?.(editor),\n afterClose: (editor: EditorInstance) => {\n cleanupSubscriptions(editor);\n resetEditorState(editor);\n editor._editorPlaceHolderRef?.changeDetectorRef.detectChanges();\n editor._editorPlaceHolderRef?.instance.detachEditor();\n editor._componentRef.instance.afterClose?.(editor);\n },\n getValue: (editor) => editor._componentRef.instance.getValue(),\n setValue: (editor: EditorInstance, value) => {\n editor.value = value;\n editor._componentRef.instance.setValue(value);\n editor._componentRef.changeDetectorRef.detectChanges();\n },\n });\n\n/**\n * Creates the editor placeholder component.\n * @param editor The editor instance.\n * @param injector The environment injector from Angular.\n */\nfunction createEditorPlaceholder(editor: EditorInstance, injector: EnvironmentInjector | undefined): void {\n if (!injector) {\n return;\n }\n\n editor._editorPlaceHolderRef = createComponent(CustomEditorPlaceholderComponent, {\n environmentInjector: injector,\n });\n}\n\n/**\n * Applies properties to the custom Angular editor and editor placeholder.\n * Updates position, size, and cell context information.\n * @param editor The editor instance.\n */\nfunction applyPropsToEditor(editor: EditorInstance): void {\n if (!editor._componentRef || !editor._editorPlaceHolderRef) {\n return;\n }\n\n editor._componentRef.setInput('originalValue', editor.originalValue);\n editor._componentRef.setInput('row', editor.row);\n editor._componentRef.setInput('column', editor.col);\n editor._componentRef.setInput('prop', editor.prop);\n editor._componentRef.setInput('cellProperties', editor.cellProperties);\n\n const rect = editor.hot.getCell(editor.row, editor.col)?.getBoundingClientRect();\n\n editor._editorPlaceHolderRef.setInput('placeholderCustomClass', '');\n editor._editorPlaceHolderRef.setInput('height', rect?.height ?? 0);\n editor._editorPlaceHolderRef.setInput('width', rect?.width ?? 0);\n editor._editorPlaceHolderRef.setInput('isVisible', true);\n editor._editorPlaceHolderRef.setInput('componentRef', editor._componentRef);\n\n editor._editorPlaceHolderRef.changeDetectorRef.detectChanges();\n}\n\n/**\n * Resets the editor placeholder state.\n * Clears all positioning and visibility settings.\n * @param editor The editor instance.\n */\nfunction resetEditorState(editor: EditorInstance): void {\n if (!editor._editorPlaceHolderRef) {\n return;\n }\n\n editor._editorPlaceHolderRef.setInput('top', undefined);\n editor._editorPlaceHolderRef.setInput('left', undefined);\n editor._editorPlaceHolderRef.setInput('height', undefined);\n editor._editorPlaceHolderRef.setInput('width', undefined);\n editor._editorPlaceHolderRef.setInput('isVisible', false);\n editor._editorPlaceHolderRef.setInput('componentRef', undefined);\n}\n\n/**\n * Cleans up existing subscriptions.\n * @param editor The editor instance.\n */\nfunction cleanupSubscriptions(editor: EditorInstance): void {\n if (editor._finishEditSubscription) {\n editor._finishEditSubscription.unsubscribe();\n editor._finishEditSubscription = undefined;\n }\n\n if (editor._cancelEditSubscription) {\n editor._cancelEditSubscription.unsubscribe();\n editor._cancelEditSubscription = undefined;\n }\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { HotCellRendererBase } from './hot-cell-renderer-base.directive';\n\n/**\n * Abstract base component for creating advanced custom cell renderer components for Handsontable.\n *\n * Extend this component and provide your own template to implement a custom renderer.\n * Unlike {@link HotCellRendererComponent}, this variant also accepts object and array values.\n *\n * @template TValue - The type of the component renderer.\n * @template TProps - The type of additional renderer properties.\n */\n@Component({\n selector: 'hot-cell-renderer-advanced',\n template: `<!-- This is an abstract component. Extend this component and provide your own template. -->`,\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport abstract class HotCellRendererAdvancedComponent<\n TValue extends string | number | boolean | Record<string, any> | Array<any> = string,\n TProps extends {} = any\n> extends HotCellRendererBase<TValue, TProps> {\n static readonly RENDERER_MARKER = Symbol('HotCellRendererAdvancedComponent');\n}\n","import { Directive } from '@angular/core';\nimport { ExtendedEditor } from 'handsontable/editors/factory';\nimport { CellProperties } from 'handsontable/settings';\nimport { KeyboardShortcutConfig } from './models/keyboard-shortcut-config';\nimport { HotCellEditorBase } from './hot-cell-editor-base.directive';\n\n/**\n * Abstract class representing an advanced Handsontable cell editor in Angular.\n *\n * Extend this class and decorate the subclass with `@Component()` to implement a custom editor.\n * Unlike {@link HotCellEditorComponent}, this variant also accepts object and array values\n * and provides additional lifecycle hooks and positioning options.\n */\n@Directive()\nexport abstract class HotCellEditorAdvancedComponent<\n T extends string | number | boolean | Record<string, any> | Array<any>\n> extends HotCellEditorBase<T> {\n static readonly EDITOR_MARKER = Symbol('HotCellEditorAdvancedComponent');\n\n /** Event triggered by Handsontable on focusing the editor. Available in advanced mode. */\n onFocus(editor?: ExtendedEditor<T>): void {}\n\n /** The position of the editor in the DOM. Available in advanced mode. */\n position: 'container' | 'portal' = 'container';\n\n /** The shortcuts available for the editor. Available in advanced mode. */\n shortcuts?: KeyboardShortcutConfig[];\n\n /** The group name for the shortcuts. Available in advanced mode. */\n shortcutsGroup?: string;\n\n /** Configuration object. Available in advanced mode. */\n config?: any;\n\n /** Lifecycle hook called after the editor is opened. Available in advanced mode. */\n afterOpen(editor: ExtendedEditor<T>, event?: Event): void {}\n\n /** Lifecycle hook called after the editor is closed. Available in advanced mode. */\n afterClose(editor: ExtendedEditor<T>): void {}\n\n /** Lifecycle hook called after the editor is initialized. Available in advanced mode. */\n afterInit(editor: ExtendedEditor<T>): void {}\n\n /** Lifecycle hook called before the editor is opened. Available in advanced mode. */\n beforeOpen(\n editor: ExtendedEditor<T>,\n {\n row,\n col,\n prop,\n td,\n originalValue,\n cellProperties,\n }: {\n row: number;\n col: number;\n prop: string | number;\n td: HTMLTableCellElement;\n originalValue: any;\n cellProperties: CellProperties;\n }\n ): void {}\n}\n","import {\n ApplicationRef,\n ComponentRef,\n createComponent,\n EmbeddedViewRef,\n EnvironmentInjector,\n Injectable,\n TemplateRef,\n Type\n} from '@angular/core';\nimport { baseRenderer, BaseRenderer, registerRenderer, rendererFactory } from 'handsontable/renderers';\nimport Handsontable from 'handsontable/base';\nimport { HotCellRendererBase } from './hot-cell-renderer-base.directive';\nimport { HotCellRendererComponent } from './hot-cell-renderer.component';\nimport { HotCellRendererAdvancedComponent } from './hot-cell-renderer-advanced.component';\n\nexport const INVALID_RENDERER_WARNING =\n 'The provided renderer component was not recognized as a valid custom renderer. ' +\n 'It must either extend HotCellRendererComponent or be a valid TemplateRef. ' +\n 'Please ensure that your custom renderer is implemented correctly and imported from the proper source.';\n\nexport const INVALID_ADVANCED_RENDERER_WARNING =\n 'The provided renderer component was not recognized as a valid custom renderer. ' +\n 'It must either extend HotCellRendererAdvancedComponent. ' +\n 'Please ensure that your custom renderer is implemented correctly and imported from the proper source.';\n\n/**\n * An object representing the parameters passed to a Handsontable renderer.\n */\ninterface BaseRendererParametersObject {\n instance: Handsontable.Core;\n td: HTMLTableCellElement;\n row: number;\n col: number;\n prop: string | number;\n value: any;\n cellProperties: Handsontable.CellProperties;\n}\n\n// Renderer component inputs, listed once at module scope so the per-cell render path can set them\n// without allocating a fresh key array (via Object.keys) on every cell of every render frame.\nconst RENDERER_INPUT_KEYS: (keyof BaseRendererParametersObject)[] = [\n 'instance', 'td', 'row', 'col', 'prop', 'value', 'cellProperties',\n];\n\n/**\n * Type guard that checks if the given object is a TemplateRef.\n *\n * @param obj - The object to check.\n * @returns True if the object is a TemplateRef; otherwise, false.\n */\nexport function isTemplateRef<T>(obj: any): obj is TemplateRef<T> {\n return !!obj && typeof obj.createEmbeddedView === 'function';\n}\n\n/**\n * Type guard to check if an object is an instance of HotCellRendererComponent.\n *\n * @param obj - The object to check.\n * @returns True if the object is a HotCellRendererComponent, false otherwise.\n */\nexport function isHotCellRendererComponent(obj: any): obj is Type<HotCellRendererComponent> {\n return obj?.RENDERER_MARKER === HotCellRendererComponent.RENDERER_MARKER;\n}\n\n/**\n * Type guard to check if an object is an instance of HotCellRendererAdvancedComponent.\n *\n * @param obj - The object to check.\n * @returns True if the object is a HotCellRendererAdvancedComponent, false otherwise.\n */\nexport function isAdvancedHotCellRendererComponent(obj: any): obj is Type<HotCellRendererAdvancedComponent> {\n return obj?.RENDERER_MARKER === HotCellRendererAdvancedComponent.RENDERER_MARKER;\n}\n\n/**\n * Service for dynamically creating Angular components or templates as custom renderers for Handsontable.\n *\n * This service allows you to create a renderer function that wraps a given Angular component or TemplateRef\n * so that it can be used as a Handsontable renderer.\n *\n * @example\n * const customRenderer = dynamicComponentService.createRendererFromComponent(MyRendererComponent, { someProp: value });\n * // Use customRenderer in your Handsontable configuration\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class DynamicComponentService {\n // Track Angular component refs and embedded views keyed by the TD element they are attached to.\n // When a cell is re-rendered the previous component is destroyed before a new one is created.\n private readonly _tdComponentRefs = new WeakMap<HTMLTableCellElement, ComponentRef<any>>();\n private readonly _tdEmbeddedViews = new WeakMap<HTMLTableCellElement, EmbeddedViewRef<any>>();\n\n // Per-instance registries of every renderer ref/view currently attached to the application.\n // The WeakMaps above only allow per-TD lookup; these sets let us sweep refs whose TD was dropped\n // from Handsontable's virtual viewport (scrolling, updateData), which would otherwise stay\n // attached to ApplicationRef forever and leak both memory and change-detection work.\n //\n // The registries are scoped per Handsontable instance (not one global set) because this service\n // is a root singleton shared by every <hot-table>. A global sweep would scan the cells of every\n // table on the page on each `afterViewRender`, i.e. on every scroll frame of any one of them.\n // Keying by instance bounds each sweep to the cells of the table that actually re-rendered.\n private readonly _instanceComponentRefs = new WeakMap<Handsontable.Core, Set<ComponentRef<any>>>();\n private readonly _instanceEmbeddedViews = new WeakMap<Handsontable.Core, Set<EmbeddedViewRef<any>>>();\n\n // Instances we already wired the sweep hook into, so each instance is hooked at most once.\n private readonly _hookedInstances = new WeakSet<Handsontable.Core>();\n\n constructor(private appRef: ApplicationRef, private environmentInjector: EnvironmentInjector) {}\n\n /**\n * Creates a custom renderer function for Handsontable from an Angular component or TemplateRef.\n * The generated renderer function will be used by Handsontable to render cell content.\n *\n * @param component - The Angular component type or TemplateRef to use as renderer.\n * @param componentProps - An object containing additional properties to use by the renderer.\n * @param register - If true, registers the renderer with Handsontable using the component's name.\n * @returns A renderer function that can be used in Handsontable's configuration.\n */\n createRendererFromComponent(\n component: Type<HotCellRendererComponent> | TemplateRef<any>,\n componentProps: Record<string, any> = {},\n register: boolean = false\n ) {\n let registered = false;\n\n return (\n instance: Handsontable.Core,\n td: HTMLTableCellElement,\n row: number,\n col: number,\n prop: string | number,\n value: any,\n cellProperties: Handsontable.CellProperties\n ) => {\n const properties: BaseRendererParametersObject = {\n value,\n instance,\n td,\n row,\n col,\n prop,\n cellProperties,\n };\n\n (cellProperties as any).rendererProps = componentProps;\n\n baseRenderer.call(this, instance, td, row, col, prop, value, cellProperties);\n\n this.registerSweepHook(instance);\n\n if (isTemplateRef(component)) {\n // Embedded views carry a per-render context, so they are always rebuilt.\n this.replaceCellContent(instance, td);\n const embeddedView = this.attachTemplateToElement(component, td, properties);\n this.trackEmbeddedView(instance, td, embeddedView);\n } else if (isHotCellRendererComponent(component)) {\n this.renderComponent(td, component, properties);\n } else {\n console.warn(INVALID_RENDERER_WARNING);\n }\n\n if (register && !registered && isHotCellRendererComponent(component)) {\n Handsontable.renderers.registerRenderer((component as Type<any>).name, component as any as BaseRenderer);\n registered = true;\n }\n\n return td;\n };\n }\n\n /**\n * Creates a custom renderer function using rendererFactory from Handsontable.\n * This is an alternative implementation that uses the factory pattern.\n *\n * @param component - The Angular component type to use as renderer.\n * @param componentProps - An object containing additional properties to use by the renderer.\n * @param register - If true, registers the renderer with Handsontable using the component's name.\n * @returns A renderer function that can be used in Handsontable's configuration.\n */\n createRendererWithFactory(\n component: Type<HotCellRendererAdvancedComponent>,\n componentProps: Record<string, any> = {},\n register: boolean = false\n ) {\n let registered = false;\n\n return rendererFactory(({\n instance,\n td,\n row,\n column,\n prop,\n value,\n cellProperties\n }) => {\n const properties: BaseRendererParametersObject = {\n value,\n instance,\n td,\n row,\n col: column,\n prop,\n cellProperties,\n };\n\n (cellProperties as any).rendererProps = componentProps;\n\n // Apply the base renderer so the TD gets the same base classes/attributes as the\n // createRendererFromComponent path (rendererFactory itself does not call it).\n baseRenderer.call(this, instance, td, row, column, prop, value, cellProperties);\n\n this.registerSweepHook(instance);\n\n if (isAdvancedHotCellRendererComponent(component)) {\n this.renderComponent(td, component, properties);\n } else {\n console.warn(INVALID_ADVANCED_RENDERER_WARNING);\n }\n\n if (register && !registered && isAdvancedHotCellRendererComponent(component)) {\n registerRenderer(component.name, component as any as BaseRenderer);\n registered = true;\n }\n });\n }\n\n /**\n * Destroys all renderer components and embedded views attached to cells within a container element.\n * Must be called before destroying the Handsontable instance to prevent Angular component leaks.\n *\n * @param container - The root DOM element of the Handsontable instance.\n * @param instance - The Handsontable instance whose registries should be torn down. When omitted\n * (e.g. test stubs), only refs reachable through TDs still in the container are destroyed.\n */\n cleanupContainer(container: HTMLElement, instance?: Handsontable.Core): void {\n const compRefs = instance ? this._instanceComponentRefs.get(instance) : undefined;\n const embViews = instance ? this._instanceEmbeddedViews.get(instance) : undefined;\n\n container.querySelectorAll<HTMLTableCellElement>('td').forEach((td) => {\n const compRef = this._tdComponentRefs.get(td);\n if (compRef) {\n this.destroyComponent(compRef);\n this._tdComponentRefs.delete(td);\n compRefs?.delete(compRef);\n }\n const embView = this._tdEmbeddedViews.get(td);\n if (embView) {\n this.destroyEmbeddedView(embView);\n this._tdEmbeddedViews.delete(td);\n embViews?.delete(embView);\n }\n });\n\n // The loop above only reaches TDs still present in the container. Refs for cells already\n // dropped from the viewport (but not yet swept) would otherwise be orphaned once this\n // instance's afterViewRender hook is gone after destroy. Tear down whatever is left and drop\n // the per-instance registries so a repeated cleanup call is a no-op. (Entries removed in the\n // loop above are already gone from these sets, so nothing is destroyed twice.)\n compRefs?.forEach((ref) => this.destroyComponent(ref));\n embViews?.forEach((view) => this.destroyEmbeddedView(view));\n\n if (instance) {\n this._instanceComponentRefs.delete(instance);\n this._instanceEmbeddedViews.delete(instance);\n }\n }\n\n /**\n * Registers a one-time `afterViewRender` hook on the given Handsontable instance that sweeps\n * renderer refs whose TD is no longer connected to the document. Handsontable recycles a pool of\n * TD elements while virtualizing rows; cells that leave the viewport are never re-rendered, so\n * without this sweep their Angular components stay attached to ApplicationRef and leak.\n *\n * Guarded against instances that do not expose `addHook` (e.g. test stubs).\n *\n * @param instance - The Handsontable instance whose render cycle drives the sweep.\n */\n private registerSweepHook(instance: Handsontable.Core): void {\n if (this._hookedInstances.has(instance) || typeof (instance as any)?.addHook !== 'function') {\n return;\n }\n\n this._hookedInstances.add(instance);\n instance.addHook('afterViewRender', () => this.sweepDetachedViews(instance));\n }\n\n /**\n * Destroys every renderer ref/view tracked for the given instance whose root node is no longer\n * attached to the document.\n *\n * @param instance - The Handsontable instance whose registries should be swept.\n */\n private sweepDetachedViews(instance: Handsontable.Core): void {\n const compRefs = this._instanceComponentRefs.get(instance);\n compRefs?.forEach((ref) => {\n if (!this.isViewConnected(ref.hostView as EmbeddedViewRef<any>)) {\n this.destroyComponent(ref);\n compRefs.delete(ref);\n }\n });\n\n const embViews = this._instanceEmbeddedViews.get(instance);\n embViews?.forEach((view) => {\n if (!this.isViewConnected(view)) {\n this.destroyEmbeddedView(view);\n embViews.delete(view);\n }\n });\n }\n\n /**\n * @returns True if any of the view's root nodes is still connected to the document.\n */\n private isViewConnected(view: EmbeddedViewRef<any>): boolean {\n return view.rootNodes.some((node: Node) => !!node?.isConnected);\n }\n\n /**\n * Destroys the renderer ref/view previously attached to a cell and clears the cell content,\n * so a fresh renderer can take over the TD without leaking the old one.\n *\n * @param instance - The Handsontable instance owning the cell, used to update its registries.\n * @param td - The table cell whose previous content should be torn down.\n */\n private replaceCellContent(instance: Handsontable.Core, td: HTMLTableCellElement): void {\n const prevRef = this._tdComponentRefs.get(td);\n if (prevRef) {\n this.destroyComponent(prevRef);\n this._tdComponentRefs.delete(td);\n this._instanceComponentRefs.get(instance)?.delete(prevRef);\n }\n\n const prevView = this._tdEmbeddedViews.get(td);\n if (prevView) {\n this.destroyEmbeddedView(prevView);\n this._tdEmbeddedViews.delete(td);\n this._instanceEmbeddedViews.get(instance)?.delete(prevView);\n }\n\n // Not `innerHTML = ''`: that reads as \"assign nothing\", but `innerHTML` is a Trusted\n // Types sink whatever the value, so under `require-trusted-types-for 'script'` an empty\n // string throws exactly like markup would.\n td.replaceChildren();\n }\n\n /**\n * Tracks a component ref both by its TD (for fast replacement) and in the instance registry\n * (for sweeping and full teardown).\n */\n private trackComponentRef(\n instance: Handsontable.Core, td: HTMLTableCellElement, ref: ComponentRef<any>\n ): void {\n this._tdComponentRefs.set(td, ref);\n this.registryFor(this._instanceComponentRefs, instance).add(ref);\n }\n\n /**\n * Tracks an embedded view both by its TD (for fast replacement) and in the instance registry\n * (for sweeping and full teardown).\n */\n private trackEmbeddedView(\n instance: Handsontable.Core, td: HTMLTableCellElement, view: EmbeddedViewRef<any>\n ): void {\n this._tdEmbeddedViews.set(td, view);\n this.registryFor(this._instanceEmbeddedViews, instance).add(view);\n }\n\n /**\n * Returns the per-instance registry set for the given instance, creating it on first use.\n */\n private registryFor<T>(registry: WeakMap<Handsontable.Core, Set<T>>, instance: Handsontable.Core): Set<T> {\n let set = registry.get(instance);\n if (!set) {\n set = new Set<T>();\n registry.set(instance, set);\n }\n return set;\n }\n\n /**\n * Attaches an embedded view created from a TemplateRef to a given DOM element.\n *\n * @param template - The TemplateRef to create an embedded view from.\n * @param tdEl - The target DOM element (a table cell) to which the view will be appended.\n * @param properties - Context object providing properties to be used within the template.\n * @returns The created EmbeddedViewRef so the caller can track and destroy it later.\n */\n private attachTemplateToElement(\n template: TemplateRef<any>, tdEl: HTMLTableCellElement, properties: BaseRendererParametersObject\n ): EmbeddedViewRef<any> {\n const embeddedView: EmbeddedViewRef<any> = template.createEmbeddedView({\n $implicit: properties.value,\n ...properties,\n });\n embeddedView.detectChanges();\n\n embeddedView.rootNodes.forEach((node) => {\n tdEl.appendChild(node);\n });\n\n return embeddedView;\n }\n\n /**\n * Dynamically creates an Angular component of the given type.\n *\n * @param component - The Angular component type to be created.\n * @param rendererParameters - An object containing input properties to assign to the component instance.\n * @returns The ComponentRef of the dynamically created component.\n */\n private createComponent<T extends HotCellRendererBase>(\n component: Type<T>,\n rendererParameters: BaseRendererParametersObject\n ): ComponentRef<T> {\n const componentRef = createComponent(component, {\n environmentInjector: this.environmentInjector,\n });\n\n this.applyInputs(componentRef, rendererParameters);\n componentRef.changeDetectorRef.detectChanges();\n\n this.appRef.attachView(componentRef.hostView);\n\n return componentRef;\n }\n\n /**\n * Renders an Angular component into the given cell, recycling the component already attached to\n * the TD when it is of the same type. Handsontable recycles its pool of TD elements heavily while\n * virtualizing rows, so recreating an Angular component on every re-render would cause needless\n * teardown/instantiation churn and GC pressure. When the type matches we only refresh the inputs.\n *\n * @param td - The target table cell.\n * @param component - The renderer component type to render.\n * @param properties - The renderer parameters to feed as component inputs.\n */\n private renderComponent<T extends HotCellRendererBase>(\n td: HTMLTableCellElement,\n component: Type<T>,\n properties: BaseRendererParametersObject\n ): void {\n const prevRef = this._tdComponentRefs.get(td);\n\n if (\n prevRef &&\n prevRef.componentType === component &&\n this.isViewConnected(prevRef.hostView as EmbeddedViewRef<any>)\n ) {\n this.applyInputs(prevRef, properties);\n prevRef.changeDetectorRef.detectChanges();\n return;\n }\n\n this.replaceCellContent(properties.instance, td);\n const componentRef = this.createComponent(component, properties);\n this.attachComponentToElement(componentRef, td);\n this.trackComponentRef(properties.instance, td, componentRef);\n }\n\n /**\n * Assigns every renderer parameter as an input on the given component ref.\n *\n * @param componentRef - The component ref whose inputs should be set.\n * @param rendererParameters - The renderer parameters to assign.\n */\n private applyInputs<T>(componentRef: ComponentRef<T>, rendererParameters: BaseRendererParametersObject): void {\n RENDERER_INPUT_KEYS.forEach((key) => {\n componentRef.setInput(key, rendererParameters[key]);\n });\n }\n\n /**\n * Attaches a dynamically created component's view to a specified DOM container element.\n *\n * @param componentRef - The reference to the dynamically created component.\n * @param container - The target DOM element to which the component's root node will be appended.\n */\n private attachComponentToElement<T>(componentRef: ComponentRef<T>, container: HTMLElement): void {\n (componentRef.hostView as EmbeddedViewRef<T>).rootNodes.forEach((node) => {\n container.appendChild(node);\n });\n }\n\n /**\n * Destroys a dynamically created component and detaches its view from the Angular application.\n *\n * Idempotent: a TD recycled after `sweepDetachedViews` already destroyed its ref still maps to that\n * stale ref in `_tdComponentRefs`, so the next render path may reach this with an already-destroyed\n * ref. Guarding on `destroyed` skips the redundant detach/destroy instead of relying on Angular's\n * internal no-op behavior.\n *\n * @param componentRef - The reference to the component to be destroyed.\n */\n destroyComponent<T>(componentRef: ComponentRef<T>): void {\n const hostView = componentRef.hostView as EmbeddedViewRef<T>;\n if (hostView.destroyed) {\n return;\n }\n this.appRef.detachView(hostView);\n componentRef.destroy();\n }\n\n /**\n * Destroys an embedded view. Idempotent for the same reason as {@link destroyComponent}: a recycled\n * TD can still map to an already-destroyed view in `_tdEmbeddedViews`.\n *\n * @param view - The embedded view to destroy.\n */\n private destroyEmbeddedView(view: EmbeddedViewRef<any>): void {\n if (view.destroyed) {\n return;\n }\n view.destroy();\n }\n}\n","import { ComponentRef, createComponent, EnvironmentInjector, Injectable, NgZone, TemplateRef, Type } from '@angular/core';\nimport { DynamicComponentService } from '../renderer/hot-dynamic-renderer-component.service';\nimport { BaseEditorAdapter } from '../editor/base-editor-adapter';\nimport { GridSettings, GridSettingsInternal } from '../models/grid-settings';\nimport { CustomValidatorFn, ColumnSettings, ColumnSettingsInternal } from '../models/column-settings';\nimport { HotCellRendererComponent } from '../renderer/hot-cell-renderer.component';\nimport { HotCellEditorComponent } from '../editor/hot-cell-editor.component';\nimport Handsontable from 'handsontable/base';\nimport { SettingsUpdate } from 'handsontable/settings';\nimport { FactoryEditorAdapter } from '../editor/editor-factory-adapter';\nimport { HotCellRendererAdvancedComponent } from '../renderer/hot-cell-renderer-advanced.component';\nimport { HotCellEditorAdvancedComponent } from '../editor/hot-cell-editor-advanced.component';\n\nconst AVAILABLE_HOOKS_SET = new Set<string>(Handsontable.hooks.getRegistered());\nconst HOT_ZONE_WRAPPED = Symbol('hotZoneWrapped');\n/**\n * The key under which a zone wrapper names the hook callback it runs. Core's hooks registry reads the same\n * `Symbol.for()` key, so it treats the wrapper and the callback as one listener: a callback the app also\n * registers with `addHook()` runs once, and `removeHook()` with the callback removes the wrapper.\n */\nconst FORWARDED_HOOK_CALLBACK = Symbol.for('handsontable.forwardedHookCallback');\n\n/**\n * Service to resolve and apply custom settings for Handsontable settings object.\n */\n@Injectable()\nexport class HotSettingsResolver {\n /**\n * The resolved copy of each column object `resolveAppliedSettings()` resolved, with a shallow copy of the\n * column as it was then, so a column the app edited in place and passes again is resolved again.\n */\n private readonly appliedColumns = new WeakMap<ColumnSettings, { source: ColumnSettings, resolved: ColumnSettings }>();\n /**\n * The editor components of the sheets' columns, by editor component type and then by the column they\n * serve: its `data` binding when that is a string or a number, or its position. Every column object that\n * names the same editor for the same column shares one component, so a sheet whose columns the host\n * declares again with new objects, a duplicated sheet, and `updateSheetSettings()` create no new one. The\n * ones a sheet of the `settings` input names are created by `applyCustomSettings()`, inside Angular's zone\n * and before any switch, so the settings filter never creates a component in the middle of a switch.\n */\n private readonly appliedEditorRefs = new Map<Type<unknown>, Map<unknown, ComponentRef<HotCellEditorComponent<any>>>>();\n /**\n * The zone wrapper of each hook callback.\n */\n private readonly zoneWrappers = new WeakMap<Function, Function>();\n /**\n * The last `settings` input, read by `isDeclaredHook()`. A hook callback counts as declared while the input,\n * at grid level or in a sheet's own `settings`, names it: `resolveAppliedSettings()` wraps only those. A\n * callback the app hands to the instance itself (`hotInstance.updateSettings()`, `updateSheetSettings()`) is\n * the app's own call and runs as given, and one the input no longer names stops counting. The sheets bar\n * writes a sheet added at runtime into the app's own `sheets` array, so that sheet's hooks count as declared\n * from then on, the way its rows count as the app's data.\n */\n private declaredSettings: GridSettings | null = null;\n\n constructor(\n private readonly dynamicComponentService: DynamicComponentService,\n private readonly environmentInjector: EnvironmentInjector,\n private readonly ngZone: NgZone,\n ) {}\n\n /**\n * Applies custom settings to the provided GridSettings.\n * @param settings The original grid settings.\n * @param previousColumns The previously resolved columns (from the prior settings cycle). When\n * supplied, an editor component already created for a column whose editor type is unchanged is\n * recycled instead of being recreated, avoiding needless Angular component teardown/rebuild.\n * @returns The merged grid settings with custom settings applied.\n */\n applyCustomSettings(settings: GridSettings, previousColumns?: ColumnSettings[]): GridSettingsInternal {\n // Shallow-clone the user settings (and each column) before mutating. Otherwise we would\n // write generated renderers/editors and `_editorComponentReference` straight onto the\n // caller's objects. When the same settings/columns are shared across two <hot-table>\n // instances, the second resolution would overwrite the first instance's editor refs,\n // leaking them and cross-wiring a single editor component between tables.\n const mergedSettings: GridSettings = { ...settings };\n\n this.declaredSettings = settings;\n this.createDeclaredSheetEditors(settings);\n\n if (Array.isArray(mergedSettings.columns)) {\n mergedSettings.columns = mergedSettings.columns.map((column, index) => {\n const resolved = { ...column };\n\n this.resolveColumnRenderer(resolved);\n this.resolveColumnEditor(resolved, previousColumns?.[index]);\n this.resolveColumnValidator(resolved);\n\n return resolved;\n });\n }\n\n this.wrapHooksInNgZone(mergedSettings);\n\n return mergedSettings as GridSettingsInternal;\n }\n\n /**\n * Resolves the settings core is about to apply without them passing `applyCustomSettings()`: a sheet's\n * own `settings`, which the sheets bar applies through `_applySettingsAndData()` on a switch, through\n * `_replaceInitPassSettings()` for the opening sheet, and through `updateSettings()` for\n * `updateSheetSettings()`. Registered on the grid with `_addSettingsFilter()`, so it reads every\n * `updateSettings()` payload too. A value already resolved is left as it is, so the settings of the\n * `settings` input pass unchanged.\n *\n * Component renderers, editors and boolean validators are resolved in any payload: core cannot use them\n * as they are. A hook callback is wrapped in Angular's zone only when the `settings` input declared it,\n * which keeps the rule of the input: a callback the app passes to the instance itself runs as given.\n *\n * The result for a column object, and the zone wrapper of a hook, is created once and reused on every\n * later payload holding the same object or function. The sheets bar compares a sheet's settings\n * function by function, and a sheet that shows again keeps the editor component it had.\n *\n * @param settings The payload core is about to apply.\n * @returns The payload to apply: `settings` itself when nothing needed resolving, a new object\n * otherwise. The caller's object is never changed.\n */\n resolveAppliedSettings(settings: SettingsUpdate): SettingsUpdate {\n const columns = settings.columns;\n const resolvedColumns = Array.isArray(columns) ? this.resolveAppliedColumns(columns) : columns;\n const hooks = this.zoneWrappedHooksOf(settings);\n\n if (resolvedColumns === columns && hooks === null) {\n return settings;\n }\n\n const resolved: SettingsUpdate = { ...settings, ...hooks };\n\n if (resolvedColumns !== columns) {\n resolved.columns = resolvedColumns as ColumnSettingsInternal[];\n }\n\n return resolved;\n }\n\n /**\n * Destroys every editor component `resolveAppliedSettings()` created.\n */\n destroyAppliedEditors(): void {\n this.appliedEditorRefs.forEach(byColumn => byColumn.forEach(ref => ref.destroy()));\n this.appliedEditorRefs.clear();\n }\n\n /**\n * Tells whether the last `settings` input names a hook callback, at grid level or in a sheet's own\n * `settings` (see `declaredSettings`).\n *\n * @param key The hook name.\n * @param callback The callback.\n * @returns `true` when the input declares it.\n */\n private isDeclaredHook(key: string, callback: Function): boolean {\n const declared = this.declaredSettings;\n\n if (declared === null) {\n return false;\n }\n\n return (declared as Record<string, unknown>)[key] === callback ||\n this.declaredSheetSettings(declared).some(own => own[key] === callback);\n }\n\n /**\n * Returns the own `settings` of every sheet the `settings` input declares.\n *\n * @param settings The `settings` input.\n * @returns The sheets' own settings objects.\n */\n private declaredSheetSettings(settings: GridSettings): Record<string, unknown>[] {\n const sheetsBar: unknown = settings.sheetsBar;\n const sheets: unknown = typeof sheetsBar === 'object' && sheetsBar !== null\n ? (sheetsBar as { sheets?: unknown }).sheets\n : undefined;\n\n if (!Array.isArray(sheets)) {\n return [];\n }\n\n return sheets\n .map((sheet: unknown) => (typeof sheet === 'object' && sheet !== null ? (sheet as { settings?: unknown }).settings : null))\n .filter((own): own is Record<string, unknown> => typeof own === 'object' && own !== null);\n }\n\n /**\n * Creates the editor components the columns of the declared sheets name, so the settings filter only looks\n * them up when the sheets bar shows a sheet.\n *\n * @param settings The `settings` input.\n */\n private createDeclaredSheetEditors(settings: GridSettings): void {\n this.declaredSheetSettings(settings).forEach((own) => {\n const columns = own.columns;\n\n if (!Array.isArray(columns)) {\n return;\n }\n\n columns.forEach((column: ColumnSettings, index: number) => {\n const editor = typeof column === 'object' && column !== null ? column.editor : undefined;\n\n if (this.isEditorComponentRefType(editor) || this.isAdvancedEditorComponentRefType(editor)) {\n this.appliedEditorRef(editor as Type<unknown>, this.editorColumnKey(column, index));\n }\n });\n });\n }\n\n /**\n * Returns the key the editor component of a column is shared by: the column's `data` binding when it is a\n * string or a number, else its position. A function binding is a new value whenever the app builds the\n * column again, so it would make a new component each time.\n *\n * @param column The column.\n * @param index The column's position.\n * @returns The key.\n */\n private editorColumnKey(column: ColumnSettings, index: number): unknown {\n const data = (column as Handsontable.ColumnSettings).data;\n\n return typeof data === 'string' || typeof data === 'number' ? data : index;\n }\n\n /**\n * Resolves each column of an applied payload.\n *\n * @param columns The columns of the payload.\n * @returns `columns` itself when no column needed resolving, a new array otherwise.\n */\n private resolveAppliedColumns(columns: ColumnSettings[]): ColumnSettings[] {\n const resolved = columns.map((column, index) => this.resolveAppliedColumn(column, index));\n\n return resolved.every((column, index) => column === columns[index]) ? columns : resolved;\n }\n\n /**\n * Resolves one column of an applied payload, once per column object.\n *\n * @param column The column.\n * @param index The column's position in the payload.\n * @returns The resolved column, or `column` itself when it holds nothing to resolve.\n */\n private resolveAppliedColumn(column: ColumnSettings, index: number): ColumnSettings {\n if (!this.needsResolution(column)) {\n return column;\n }\n\n const cached = this.appliedColumns.get(column);\n\n if (cached && this.isShallowEqual(cached.source, column)) {\n return cached.resolved;\n }\n\n const resolved = { ...column };\n const columnKey = this.editorColumnKey(column, index);\n\n this.resolveColumnRenderer(resolved);\n this.resolveColumnEditor(resolved, undefined, editorType => this.appliedEditorRef(editorType, columnKey));\n this.resolveColumnValidator(resolved);\n this.appliedColumns.set(column, { source: { ...column }, resolved });\n\n return resolved;\n }\n\n /**\n * Tells whether two column objects hold the same keys with the same values.\n *\n * @param a A column.\n * @param b Another column.\n * @returns `true` when no key differs.\n */\n private isShallowEqual(a: ColumnSettings, b: ColumnSettings): boolean {\n const aKeys = Object.keys(a);\n\n return aKeys.length === Object.keys(b).length &&\n aKeys.every(key => (a as Record<string, unknown>)[key] === (b as Record<string, unknown>)[key]);\n }\n\n /**\n * Returns the editor component kept for an editor type and a column, creating it the first time, in the\n * zone of the caller.\n *\n * @param editorType The editor component type.\n * @param columnKey The column's key (`editorColumnKey()`).\n * @returns The editor component.\n */\n private appliedEditorRef(editorType: Type<unknown>, columnKey: unknown): ComponentRef<HotCellEditorComponent<any>> {\n const byColumn = this.appliedEditorRefs.get(editorType) ?? new Map<unknown, ComponentRef<HotCellEditorComponent<any>>>();\n const known = byColumn.get(columnKey);\n\n if (known) {\n return known;\n }\n\n const created = createComponent(editorType, { environmentInjector: this.environmentInjector });\n\n byColumn.set(columnKey, created as ComponentRef<HotCellEditorComponent<any>>);\n this.appliedEditorRefs.set(editorType, byColumn);\n\n return created as ComponentRef<HotCellEditorComponent<any>>;\n }\n\n /**\n * Tells whether a column holds a renderer, an editor or a validator Handsontable cannot read as it is.\n *\n * @param column The column.\n * @returns `true` when the column needs resolving.\n */\n private needsResolution(column: ColumnSettings): boolean {\n return typeof column === 'object' && column !== null && (\n this.isCustomRenderer(column.renderer) ||\n this.isEditorComponentRefType(column.editor) ||\n this.isAdvancedEditorComponentRefType(column.editor) ||\n this.isCustomValidatorFn(column.validator)\n );\n }\n\n /**\n * Returns the zone wrappers of the hook callbacks a payload holds that the `settings` input declared and\n * that are not wrapped yet.\n *\n * @param settings The payload.\n * @returns The wrappers by hook name, or `null` when there is nothing to wrap.\n */\n private zoneWrappedHooksOf(settings: SettingsUpdate): Record<string, unknown> | null {\n let wrapped: Record<string, unknown> | null = null;\n\n Object.keys(settings).forEach((key) => {\n const option: unknown = settings[key as keyof SettingsUpdate];\n const zoned = AVAILABLE_HOOKS_SET.has(key)\n ? this.zonedHookValue(option, callback => this.isDeclaredHook(key, callback))\n : option;\n\n if (zoned !== option) {\n wrapped = { ...wrapped, [key]: zoned };\n }\n });\n\n return wrapped;\n }\n\n /**\n * Ensures that hook callbacks in the provided grid settings run inside Angular's zone.\n *\n * @param settings The original grid settings.\n */\n private wrapHooksInNgZone(settings: GridSettings): void {\n // Iterate only the keys actually present in settings instead of all ~100 registered HOT hooks.\n Object.keys(settings).forEach((key) => {\n if (AVAILABLE_HOOKS_SET.has(key)) {\n settings[key] = this.zonedHookValue(settings[key], () => true);\n }\n });\n }\n\n /**\n * Returns a hook value with its callback wrapped in Angular's zone. Only a function is wrapped: an array of\n * callbacks is kept as it is, so its callbacks run as given, outside the zone, which is the rule the\n * `settings` input has always had (a per-cell hook given as an array stays free of change detection). A\n * callback that is already a wrapper, or that `shouldWrap` rejects, is kept too.\n *\n * @param option The hook value.\n * @param shouldWrap Tells whether a callback is wrapped.\n * @returns The value to apply: `option` itself when nothing was wrapped.\n */\n private zonedHookValue(option: unknown, shouldWrap: (callback: Function) => boolean): unknown {\n return typeof option === 'function' && !(option as any)[HOT_ZONE_WRAPPED] && shouldWrap(option)\n ? this.zoneWrapped(option)\n : option;\n }\n\n /**\n * Returns the function that runs a hook callback inside Angular's zone, the same one for every call\n * with the same callback.\n *\n * @param callback The hook callback.\n * @returns The wrapper.\n */\n private zoneWrapped(callback: Function): Function {\n const known = this.zoneWrappers.get(callback);\n\n if (known) {\n return known;\n }\n\n const ngZone = this.ngZone;\n const wrapped = function (...args: any) {\n return ngZone.run(() => callback.apply(this, args));\n };\n\n (wrapped as any)[HOT_ZONE_WRAPPED] = true;\n (wrapped as any)[FORWARDED_HOOK_CALLBACK] = callback;\n this.zoneWrappers.set(callback, wrapped);\n\n return wrapped;\n }\n\n /**\n * Replaces a custom renderer of a column with a renderer function.\n *\n * @param cellSettings The column, a copy the caller owns.\n */\n private resolveColumnRenderer(cellSettings: ColumnSettings): void {\n const renderer = cellSettings.renderer;\n\n if (!this.isCustomRenderer(renderer)) {\n return;\n }\n\n const props: any = cellSettings.rendererProps ?? {};\n\n if (this.isAdvancedRendererComponentRefType(renderer)) {\n cellSettings.renderer = this.dynamicComponentService.createRendererWithFactory(renderer, props);\n } else {\n cellSettings.renderer = this.dynamicComponentService.createRendererFromComponent(renderer, props);\n }\n }\n\n /**\n * Replaces an editor component of a column with an editor class, and creates the component.\n *\n * @param cellSettings The column, a copy the caller owns.\n * @param previousColumn The column at the same index in the previous settings cycle, used to\n * recycle its editor component.\n * @param sharedEditorRef Returns the editor component to use for an editor type when the previous\n * column has none to recycle, instead of creating a new one.\n * @returns The editor component the column holds now, or `undefined` when it declares none.\n */\n private resolveColumnEditor(\n cellSettings: ColumnSettings,\n previousColumn?: ColumnSettings,\n sharedEditorRef?: (editorType: Type<unknown>) => ComponentRef<HotCellEditorComponent<any>>\n ): ComponentRef<HotCellEditorComponent<any>> | undefined {\n const isAdvanced = this.isAdvancedEditorComponentRefType(cellSettings.editor);\n const isBasic = this.isEditorComponentRefType(cellSettings.editor);\n\n if (!isAdvanced && !isBasic) {\n return undefined;\n }\n\n const editorType = cellSettings.editor as Type<HotCellEditorComponent<any>> | Type<HotCellEditorAdvancedComponent<any>>;\n const reusableRef = this.reusableEditorRef(previousColumn, cellSettings, editorType);\n const internalSettings = cellSettings as ColumnSettingsInternal;\n\n // Recycle the editor component from the previous settings cycle when the same editor type\n // sits at the same column index AND the same logical column (by `data`) still occupies it.\n // Recreating it on every settings change would tear down and rebuild an Angular component\n // (and its DOM/internal state) for no reason. The reused ref is carried into the new column;\n // HotTableComponent.ngOnChanges detects it by identity and skips destroying it.\n const component = reusableRef ?? sharedEditorRef?.(editorType) ?? createComponent(editorType as Type<any>, {\n environmentInjector: this.environmentInjector,\n });\n\n internalSettings._editorComponentReference = component as ComponentRef<HotCellEditorComponent<any>>;\n\n if (isAdvanced) {\n cellSettings.editor = FactoryEditorAdapter(component as ComponentRef<HotCellEditorAdvancedComponent<any>>);\n } else {\n internalSettings._environmentInjector = this.environmentInjector;\n cellSettings.editor = BaseEditorAdapter;\n }\n\n return internalSettings._editorComponentReference;\n }\n\n /**\n * Returns the previous column's editor component ref when it can be reused for the new column, or\n * `undefined` to signal a fresh component is needed.\n *\n * A ref is only recycled when, at the same index, both the editor component type AND the logical\n * column identity (its `data` binding) are unchanged. The component-type check alone would already\n * be functionally safe — a Handsontable editor is not per-cell rendered state but a single\n * on-demand component that `BaseEditorAdapter`/`FactoryEditorAdapter` re-prepare on every edit\n * (`prepare()` re-reads the ref from the *current* column meta and `applyPropsToEditor()` re-applies\n * the full cell context on each `open()`). The extra `data` check is a defensive guard: when columns\n * are reordered/shortened so a *different* logical column lands on an index, we build a fresh editor\n * rather than carry the previous column's instance over, so no custom editor that caches\n * column-specific config at construction can leak stale state into the new cell.\n *\n * @param previousColumn The column at the same index in the previous settings cycle.\n * @param currentColumn The column now occupying this index.\n * @param editorType The editor component type requested for the new column.\n */\n private reusableEditorRef(\n previousColumn: ColumnSettings | undefined,\n currentColumn: ColumnSettings,\n editorType: Type<unknown>\n ): ComponentRef<any> | undefined {\n const previousRef = (previousColumn as ColumnSettingsInternal | undefined)?._editorComponentReference;\n\n if (!previousRef || previousRef.componentType !== editorType) {\n return undefined;\n }\n\n // Same logical column still occupies this index. Columns without a `data` binding are identified\n // purely by position, so two `undefined` data values compare equal and recycle as before.\n const sameLogicalColumn =\n (previousColumn as Handsontable.ColumnSettings | undefined)?.data ===\n (currentColumn as Handsontable.ColumnSettings).data;\n\n return sameLogicalColumn ? previousRef : undefined;\n }\n\n /**\n * Replaces a validator that returns a boolean with one that answers through the callback.\n *\n * @param cellSettings The column, a copy the caller owns.\n */\n private resolveColumnValidator(cellSettings: ColumnSettings): void {\n const customValidatorFn = cellSettings.validator;\n\n if (!this.isCustomValidatorFn(customValidatorFn)) {\n return;\n }\n\n cellSettings.validator = (value: any, callback: (result: boolean) => void) => {\n callback(customValidatorFn(value));\n };\n }\n\n private isCustomValidatorFn(validator: unknown): validator is CustomValidatorFn<any> {\n return typeof validator === 'function' && validator.length === 1;\n }\n\n private isEditorComponentRefType(editor: any): editor is Type<HotCellEditorComponent<any>> {\n // ecmp - we need it to check if the editor is a component\n return typeof editor === 'function' &&\n !!(editor as any)?.ɵcmp &&\n (editor as any)?.EDITOR_MARKER === HotCellEditorComponent.EDITOR_MARKER;\n }\n\n private isAdvancedEditorComponentRefType(editor: any): editor is Type<HotCellEditorAdvancedComponent<any>> {\n // ecmp - we need it to check if the editor is a component\n return typeof editor === 'function' &&\n !!(editor as any)?.ɵcmp &&\n (editor as any)?.EDITOR_MARKER === HotCellEditorAdvancedComponent.EDITOR_MARKER;\n }\n\n private isRendererComponentRefType(renderer: any): renderer is Type<HotCellRendererComponent<any, any>> {\n // ecmp - we need it to check if the renderer is a component\n return typeof renderer === 'function' &&\n !!(renderer as any)?.ɵcmp &&\n (renderer as any)?.RENDERER_MARKER === HotCellRendererComponent.RENDERER_MARKER;\n }\n\n private isAdvancedRendererComponentRefType(renderer: any): renderer is Type<HotCellRendererAdvancedComponent<any, any>> {\n // ecmp - we need it to check if the renderer is a component\n return typeof renderer === 'function' &&\n !!(renderer as any)?.ɵcmp &&\n (renderer as any)?.RENDERER_MARKER === HotCellRendererAdvancedComponent.RENDERER_MARKER;\n }\n\n private isTemplateRef(renderer: any): renderer is TemplateRef<any> {\n return renderer && typeof renderer.createEmbeddedView === 'function';\n }\n\n private isCustomRenderer(renderer: any): renderer is Type<HotCellRendererComponent<any, any>> |\n TemplateRef<any> |\n Type<HotCellRendererAdvancedComponent<any, any>> {\n return this.isRendererComponentRefType(renderer) ||\n this.isTemplateRef(renderer) ||\n this.isAdvancedRendererComponentRefType(renderer);\n }\n}\n","import {Injectable, InjectionToken, Inject} from '@angular/core';\nimport {BehaviorSubject, Observable} from 'rxjs';\n\n/**\n * A constant representing the non-commercial and evaluation license.\n * */\nexport const NON_COMMERCIAL_LICENSE = 'non-commercial-and-evaluation';\n\n/**\n * Type representing a theme name.\n * Possible values include predefined themes and any custom string.\n */\nexport enum PredefinedTheme {\n Main = 'ht-theme-main',\n MainDark = 'ht-theme-main-dark',\n MainDarkAuto = 'ht-theme-main-dark-auto',\n Horizon = 'ht-theme-horizon',\n HorizonDark = 'ht-theme-horizon-dark',\n HorizonDarkAuto = 'ht-theme-horizon-dark-auto'\n}\n\nexport type ThemeName = PredefinedTheme | string;\n\n/**\n * Interface for the Handsontable global configuration.\n */\nexport interface HotGlobalConfig {\n /**\n * The license key for Handsontable.\n */\n license?: string;\n\n /**\n * The name of the theme to be used.\n */\n themeName?: ThemeName;\n\n /**\n * The theme to be used (ThemeBuilder instance or theme name string).\n * When set, takes precedence over `themeName` for Handsontable 17+.\n */\n theme?: object | string;\n\n /**\n * The language code to be used for localization.\n * For example, 'en-US', 'pl-PL', etc.\n * **Note:** The language must be chosen from the languages supported by Handsontable and registered in the application.\n */\n language?: string;\n\n /**\n * The layout direction for the Handsontable instance.\n * This property defines whether the layout should be left-to-right ('ltr'), right-to-left ('rtl'),\n * or inherit the direction from the parent element ('inherit').\n */\n layoutDirection?: 'ltr' | 'rtl' | 'inherit';\n}\n\n/**\n * Injection token for providing a global default configuration.\n */\nexport const HOT_GLOBAL_CONFIG = new InjectionToken<HotGlobalConfig>('HOT_GLOBAL_CONFIG', {\n providedIn: 'root',\n factory: () => ({})\n});\n\n/**\n * Service for configuring Handsontable settings.\n * This service allows setting and retrieving global configuration.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class HotGlobalConfigService {\n\n /**\n * The default configuration object for Handsontable.\n *\n * This object is used as the initial value for the configuration BehaviorSubject.\n * It can be overridden by a global configuration provided through the\n * {@link HOT_GLOBAL_CONFIG} injection token.\n *\n * @private\n * @type {HotGlobalConfig}\n */\n private defaultConfig: HotGlobalConfig = {};\n\n /**\n * A BehaviorSubject that holds the current Handsontable configuration.\n *\n * New configuration values can be emitted by calling next() on this subject.\n * This allows subscribers to react to configuration changes dynamically.\n *\n * @private\n * @type {BehaviorSubject<HotGlobalConfig>}\n */\n private configSubject = new BehaviorSubject<HotGlobalConfig>(this.defaultConfig);\n\n /**\n * An Observable stream of the current Handsontable configuration.\n *\n * Components can subscribe to this observable to receive updates whenever the configuration changes.\n *\n * @returns The configuration as an observable stream.\n */\n get config$(): Observable<HotGlobalConfig> {\n return this.configSubject.asObservable();\n }\n\n constructor(\n @Inject(HOT_GLOBAL_CONFIG) globalConfig: HotGlobalConfig\n ) {\n // Merge global configuration (if provided) into defaultConfig immutably.\n this.defaultConfig = { ...this.defaultConfig, ...globalConfig };\n this.configSubject.next(this.defaultConfig);\n }\n\n /**\n * Sets the global configuration for Handsontable.\n *\n * @param config - An object containing configuration options.\n * Each Handsontable instance can override this configuration by providing its own settings.\n */\n setConfig(config: HotGlobalConfig) {\n this.configSubject.next({ ...this.defaultConfig, ...config });\n }\n\n /**\n * Retrieves the current Handsontable configuration.\n *\n * @returns An object with the current settings.\n */\n getConfig(): HotGlobalConfig {\n return this.configSubject.value;\n }\n\n /**\n * Resets the configuration to the default settings.\n * This method updates the configuration BehaviorSubject with the default configuration.\n */\n resetConfig(): void {\n this.configSubject.next({ ...this.defaultConfig });\n }\n}\n","import {\n AfterViewInit,\n Component,\n DestroyRef,\n ElementRef,\n EnvironmentInjector,\n Input,\n NgZone,\n OnChanges,\n OnDestroy,\n PLATFORM_ID,\n SimpleChanges,\n ViewChild,\n ViewEncapsulation,\n inject\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport Handsontable from 'handsontable/base';\nimport { HotSettingsResolver } from './services/hot-settings-resolver.service';\nimport { HotGlobalConfigService } from './services/hot-global-config.service';\nimport { GridSettings } from './models/grid-settings';\nimport { DynamicComponentService } from './renderer/hot-dynamic-renderer-component.service';\nimport { HotInstanceWithAngularInjector } from './editor/models/factory-editor-properties';\nimport { ColumnSettingsInternal } from './models/column-settings';\nimport { skip } from 'rxjs/operators';\n\nexport const HOT_DESTROYED_WARNING = 'The Handsontable instance bound to this component was destroyed and cannot be' + ' used properly.';\n\n/**\n * The size options that discard the sizes stored by the manual resize plugins when they are passed\n * to `updateSettings()`.\n */\nconst SIZE_SETTING_KEYS = new Set<string>(['rowHeights', 'minRowHeights', 'colWidths']);\n\n/**\n * Settings that core resets only on `null`. Core reads `undefined` as \"leave the current size\", so a\n * `height` or `width` that goes from a value to `undefined` is forwarded as `null`, which restores the\n * root element's initial inline size.\n */\nconst CLEARED_BY_NULL_SETTINGS = ['height', 'width'] as const;\n\n/**\n * Checks whether a hook value holds a callback core registers: a function or an array of them.\n *\n * @param value The hook value.\n * @returns `true` for a function or an array.\n */\nfunction isHookCallback(value: unknown): boolean {\n return typeof value === 'function' || Array.isArray(value);\n}\n\n/**\n * Compares two size option values. Both hold a number, a string, a function or an array of numbers\n * or strings, so an element-wise walk is enough - and it is what makes a value written inline in a\n * template, which is a new array on every change detection run, compare as unchanged.\n *\n * A function is compared by reference only. It states no fixed size, and the core plugins ignore it\n * when deciding whether the sizes were re-declared, so forwarding it changes nothing either way.\n *\n * @param currentValue The value the grid currently holds.\n * @param newValue The value coming from the `settings` input.\n * @returns `true` when the two state the same sizes.\n */\nfunction isSameSizeSetting(currentValue: unknown, newValue: unknown): boolean {\n if (currentValue === newValue) {\n return true;\n }\n\n if (Array.isArray(currentValue) && Array.isArray(newValue)) {\n return currentValue.length === newValue.length &&\n currentValue.every((value, index) => value === newValue[index]);\n }\n\n return false;\n}\n\n/**\n * The class that makes the container and the host fill their parent. The component styles below\n * spell the same name, because decorator metadata must stay statically analyzable.\n */\nconst FILL_HEIGHT_CLASS_NAME = 'ht-fill-height';\n\n/**\n * A `height` that resolves against the container: a percentage, or a `var()` that may hold one.\n * The core treats the same two as container-driven in `utils/rootSize.ts`, together with units that\n * resolve against the viewport or a query container, which do not depend on the container here.\n */\nconst RELATIVE_HEIGHT_PATTERN = /%|\\bvar\\(/i;\n\n@Component({\n selector: 'hot-table',\n template: '<div #container></div>',\n encapsulation: ViewEncapsulation.None,\n providers: [HotSettingsResolver],\n styles: [\n `\n :host {\n display: block;\n }\n\n :where(hot-table.ht-fill-height, hot-table > div.ht-fill-height) {\n height: 100%;\n }\n `,\n ],\n})\nexport class HotTableComponent implements AfterViewInit, OnChanges, OnDestroy {\n // component inputs\n /** The data for the Handsontable instance. */\n @Input() data: Handsontable.GridSettings['data'] | null = null;\n /** The settings for the Handsontable instance. */\n @Input() settings: GridSettings = {};\n\n /** The container element for the Handsontable instance. */\n @ViewChild('container', { static: false })\n public container: ElementRef<HTMLDivElement>;\n\n /** The Handsontable instance. */\n private __hotInstance: Handsontable | null = null;\n private readonly _destroyRef = inject(DestroyRef);\n private readonly _host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly isBrowser = inject(PLATFORM_ID) === 'browser';\n /**\n * The grid-level `columns` resolved from the `settings` input on the last change that carried them.\n * They hold the editor components this component created for them. The grid's own `columns` is not\n * where to find them: while the sheets bar shows a sheet that declares its own `columns`, it holds that\n * sheet's.\n */\n private _gridColumns: ColumnSettingsInternal[] | undefined;\n /**\n * The hooks the last applied `settings` input passed a callback for. A hook in this set that the next\n * input leaves out is sent as `null`. It is read from what the component sent, not from the previous\n * input, because an app may delete the key from that object before passing a copy.\n */\n private _passedHookKeys = new Set<string>();\n /**\n * The `height` and `width` keys whose size the grid holds from a `settings` input: passed a value, and\n * not cleared since (a key left out of a later input keeps its size, so it stays listed). Only these\n * are sent as `null` when an input sets them to `undefined`, so a size the app set through\n * `hotInstance.updateSettings()` stays when the input never passed one.\n */\n private _passedClearedByNullKeys = new Set<string>();\n\n constructor(\n private _hotSettingsResolver: HotSettingsResolver,\n private _hotConfig: HotGlobalConfigService,\n public ngZone: NgZone,\n private readonly environmentInjector: EnvironmentInjector,\n private readonly _dynamicComponentService: DynamicComponentService\n ) {}\n\n /**\n * Gets the Handsontable instance.\n * @returns The Handsontable instance, or `null` when it is not created yet, it has been\n * destroyed, or this component is rendering on the server.\n */\n public get hotInstance(): Handsontable | null {\n if (!this.__hotInstance || !this.__hotInstance.isDestroyed) {\n // Will return the Handsontable instance or `null` if it's not yet been created.\n return this.__hotInstance;\n } else {\n console.warn(HOT_DESTROYED_WARNING);\n return null;\n }\n }\n\n /**\n * Sets the Handsontable instance.\n * @param hotInstance The Handsontable instance to set.\n */\n private set hotInstance(hotInstance) {\n this.__hotInstance = hotInstance;\n }\n\n /**\n * Initializes the Handsontable instance after the view has been initialized.\n * The initial settings of the table are also prepared here\n */\n ngAfterViewInit(): void {\n // The server DOM has no `getRootNode`, and constructing the grid there throws on every\n // request. `afterNextRender` skips the server too, but it shipped in Angular 16.2 and this\n // wrapper still supports 16.0.\n if (!this.isBrowser) {\n return;\n }\n\n let options: Handsontable.GridSettings = this._hotSettingsResolver.applyCustomSettings(this.settings);\n\n if (Array.isArray(options.columns)) {\n this._gridColumns = options.columns;\n }\n\n this._passedHookKeys = this.collectHookKeys(options);\n this._passedClearedByNullKeys = this.collectClearedByNullKeys(options);\n\n const negotiatedSettings = this.getNegotiatedSettings(options);\n options = { ...options, ...negotiatedSettings, ...(this.data != null ? { data: this.data } : {}) };\n\n this.ngZone.runOutsideAngular(() => {\n this.hotInstance = new Handsontable.Core(this.container.nativeElement, options);\n\n (this.hotInstance as HotInstanceWithAngularInjector)._angularEnvironmentInjector = this.environmentInjector;\n\n this.hotInstance._addSettingsFilter?.(settings => this._hotSettingsResolver.resolveAppliedSettings(settings));\n\n // Registered before `init()`, so the hook also sees the initial `height`, before the first render.\n this.hotInstance.addHook('beforeHeightChange', (height) => {\n this.toggleFillHeight(height);\n\n return height;\n });\n\n this.hotInstance.init();\n });\n\n this._hotConfig.config$.pipe(skip(1), takeUntilDestroyed(this._destroyRef)).subscribe((config) => {\n if (this.hotInstance) {\n const negotiatedSettings = this.getNegotiatedSettings(this.settings);\n this.updateHotTable(negotiatedSettings);\n }\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (this.hotInstance === null) {\n return;\n }\n\n if (changes.settings && !changes.settings.firstChange) {\n // Capture old editor refs before applying new settings so HOT can close any active editor first.\n const prevColumnsArray = this._gridColumns;\n\n // Pass the previous columns so unchanged editor types recycle their existing component\n // instead of creating a fresh one on every settings change.\n const newOptions: Handsontable.GridSettings = this._hotSettingsResolver.applyCustomSettings(\n changes.settings.currentValue,\n prevColumnsArray\n );\n\n this.clearRemovedHooks(newOptions);\n this._passedHookKeys = this.collectHookKeys(newOptions);\n this.clearUnsetSizes(newOptions);\n this._passedClearedByNullKeys = this.collectClearedByNullKeys(newOptions, this._passedClearedByNullKeys);\n\n // updateHotTable closes any active editor via HOT.updateSettings before we destroy old refs.\n this.updateHotTable(newOptions);\n\n // Only destroy old editor refs when new settings actually replace columns.\n // If newOptions has no columns, HOT keeps the old column objects active — destroying\n // their refs would crash FactoryEditorAdapter / BaseEditorAdapter on next edit.\n if (prevColumnsArray && Array.isArray(newOptions.columns)) {\n // Refs recycled into the new columns must survive — destroy only the ones left behind.\n const reusedRefs = new Set(\n newOptions.columns\n .map((column) => column._editorComponentReference)\n .filter((ref): ref is NonNullable<typeof ref> => !!ref)\n );\n\n prevColumnsArray.forEach((column) => {\n if (column._editorComponentReference && !reusedRefs.has(column._editorComponentReference)) {\n column._editorComponentReference.destroy();\n }\n });\n }\n\n if (Array.isArray(newOptions.columns)) {\n this._gridColumns = newOptions.columns;\n }\n }\n\n if (changes.data && !changes.data.firstChange) {\n this.hotInstance?.updateData(changes.data.currentValue);\n }\n }\n\n /**\n * Destroys the Handsontable instance and clears the columns from custom editors.\n */\n ngOnDestroy(): void {\n this.ngZone.runOutsideAngular(() => {\n if (!this.__hotInstance) {\n return;\n }\n\n const isLive = !this.__hotInstance.isDestroyed;\n\n // Destroy renderer Angular components attached to table cells before HOT removes the DOM.\n if (isLive && this.container) {\n this._dynamicComponentService.cleanupContainer(this.container.nativeElement, this.__hotInstance);\n }\n\n this._gridColumns?.forEach((column) => {\n if (column._editorComponentReference) {\n column._editorComponentReference.destroy();\n }\n });\n this._gridColumns = undefined;\n this._hotSettingsResolver.destroyAppliedEditors();\n\n if (isLive) {\n this.__hotInstance.destroy();\n }\n });\n }\n\n /**\n * Makes the container and the `<hot-table>` host fill their parent when the grid `height` is\n * relative.\n *\n * The core puts its root wrapper inside the container, and the `height: 100%` of the grid content\n * resolves against the container. An auto-height container makes that `100%` collapse to `0px`, so\n * the container has to pass the height of its parent through. React and Vue always do. Here it\n * happens only for a relative `height` (`%` or `var()`), so grids with other heights keep their\n * layout. The rule is a zero-specificity `:where()`, so any CSS of the app overrides it.\n *\n * @param height The value the `beforeHeightChange` hook received. It is the result of a `height`\n * function, and it is `null` when the `height` is reset.\n */\n private toggleFillHeight(height: unknown): void {\n const fillHeight = typeof height === 'string' && RELATIVE_HEIGHT_PATTERN.test(height);\n\n this.container.nativeElement.classList.toggle(FILL_HEIGHT_CLASS_NAME, fillHeight);\n this._host.nativeElement.classList.toggle(FILL_HEIGHT_CLASS_NAME, fillHeight);\n }\n\n /**\n * Sets to `null` each hook the component last passed a callback for and the new settings do not, so\n * `updateSettings()` removes that callback. A key missing from the new object is otherwise left out of\n * the payload, and core keeps the callback.\n *\n * @param newOptions The settings about to be applied. Changed in place.\n */\n private clearRemovedHooks(newOptions: Handsontable.GridSettings): void {\n this._passedHookKeys.forEach((key) => {\n if (!isHookCallback(newOptions[key])) {\n newOptions[key] = null;\n }\n });\n }\n\n /**\n * Sets to `null` each of `height` and `width` that the component last passed a value for and the new\n * settings set to `undefined`, so `updateSettings()` resets the root element's size. A key missing from\n * the new object is left out of the payload, and the grid keeps its size.\n *\n * @param newOptions The settings about to be applied. Changed in place.\n */\n private clearUnsetSizes(newOptions: Handsontable.GridSettings): void {\n Object.keys(newOptions).forEach((key) => {\n if (this._passedClearedByNullKeys.has(key) && newOptions[key] === undefined) {\n newOptions[key] = null;\n }\n });\n }\n\n /**\n * Lists which of `height` and `width` hold a size the component applied: the keys the settings pass a\n * value for, and the previously listed keys the settings leave out, because the grid keeps that size.\n *\n * @param settings The settings to read.\n * @param previousKeys The keys listed for the previous settings.\n * @returns The setting names.\n */\n private collectClearedByNullKeys(\n settings: Handsontable.GridSettings,\n previousKeys: Set<string> = new Set()\n ): Set<string> {\n const ownKeys = new Set(Object.keys(settings));\n\n return new Set(CLEARED_BY_NULL_SETTINGS.filter(key => (\n ownKeys.has(key) ? settings[key] !== undefined && settings[key] !== null : previousKeys.has(key)\n )));\n }\n\n /**\n * Lists the hooks the settings pass a callback for. A key counts as a hook by the rule core's\n * `updateSettings()` uses in `core.ts`: a registered or a deprecated hook name. Only a function or an\n * array of them counts as a callback: core ignores any other value, such as `false`.\n *\n * @param settings The settings to read.\n * @returns The hook names.\n */\n private collectHookKeys(settings: Handsontable.GridSettings): Set<string> {\n return new Set(Object.keys(settings).filter(key => (\n isHookCallback(settings[key]) &&\n (Handsontable.hooks.isRegistered(key) || Handsontable.hooks.isDeprecated(key))\n )));\n }\n\n /**\n * Updates the Handsontable instance with new settings.\n * @param newSettings The new settings to apply to the Handsontable instance.\n */\n private updateHotTable(newSettings: Handsontable.GridSettings): void {\n if (!this.hotInstance) {\n return;\n }\n\n const currentSettings = this.hotInstance.getSettings();\n const initOnlySettingKeys = new Set<string>(\n (currentSettings as any)?._initOnlySettings ?? []\n );\n const filteredSettings: Handsontable.GridSettings = {};\n\n for (const key of Object.keys(newSettings)) {\n if (initOnlySettingKeys.has(key)) {\n continue;\n }\n\n // `ngOnChanges` fires for the whole settings object, so every key is re-passed whenever any\n // one of them changes. Passing `rowHeights` or `colWidths` re-declares the sizes and discards\n // the ones the user produced by dragging, so an unchanged value must not be forwarded.\n if (\n SIZE_SETTING_KEYS.has(key) &&\n isSameSizeSetting((currentSettings as any)?.[key], (newSettings as any)[key])\n ) {\n continue;\n }\n\n (filteredSettings as any)[key] = (newSettings as any)[key];\n }\n\n this.ngZone.runOutsideAngular(() => {\n this.hotInstance?.updateSettings(filteredSettings, false);\n });\n }\n\n /**\n * Merges the provided Handsontable grid settings with the global configuration.\n *\n * This method retrieves the global configuration from the HotGlobalConfigService and negotiates the final\n * Handsontable settings by giving precedence to the provided settings.\n * Additionally, the `layoutDirection` is only merged if the Handsontable instance has not yet been initialized.\n *\n * @param settings - The grid settings provided by the user or component.\n * @returns The final negotiated grid settings after merging with global defaults.\n */\n private getNegotiatedSettings(settings: GridSettings): Handsontable.GridSettings {\n const hotConfig = this._hotConfig.getConfig();\n const negotiatedSettings: Handsontable.GridSettings = {};\n\n negotiatedSettings.licenseKey = settings.licenseKey ?? hotConfig.license;\n negotiatedSettings.language = settings.language ?? hotConfig.language;\n\n const theme = settings.theme ?? hotConfig.theme;\n const themeName = settings.themeName ?? hotConfig.themeName;\n\n if (theme !== undefined) {\n negotiatedSettings.theme = theme as Handsontable.GridSettings['theme'];\n } else if (themeName) {\n negotiatedSettings.themeName = themeName;\n }\n\n // settings that can be set only before the Handsontable instance is initialized\n if (!this.__hotInstance) {\n negotiatedSettings.layoutDirection = settings.layoutDirection ?? hotConfig.layoutDirection;\n }\n\n return negotiatedSettings;\n }\n}\n","import { NgModule } from '@angular/core';\nimport { HotTableComponent } from './hot-table.component';\n\n@NgModule({\n imports: [HotTableComponent],\n exports: [HotTableComponent],\n})\nexport class HotTableModule {\n static readonly version = '0.0.0-next-dddc256-20261103';\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@handsontable/angular-wrapper","version":"0.0.0-next-0491dcb-20261103","description":"Handsontable DataGrid for Angular with a spreadsheet look and feel.","author":"Handsoncode <hello@handsoncode.net> (https://handsoncode.net)","license":"SEE LICENSE IN LICENSE.txt","homepage":"https://handsontable.com","keywords":["handsontable","component","data","table","grid","data table","data grid","spreadsheet","sheet","excel","angular","angular component","angular grid","wrapper","pro","enterprise","sort","formulas","filter","search","conditional formatting","csv"],"repository":{"type":"git","url":"https://github.com/handsontable/handsontable.git"},"bugs":{"url":"https://github.com/handsontable/handsontable/issues"},"peerDependencies":{"@angular/core":">=16.0.0 <23.0.0","handsontable":"0.0.0-next-0491dcb-20261103","rxjs":"^7.0.0"},"publishConfig":{"directory":"dist/hot-table","linkDirectory":true},"module":"fesm2022/handsontable-angular-wrapper.mjs","typings":"types/handsontable-angular-wrapper.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./types/handsontable-angular-wrapper.d.ts","default":"./fesm2022/handsontable-angular-wrapper.mjs"}},"sideEffects":false,"optionalDependencies":{"tslib":"^2.3.0"}}
1
+ {"name":"@handsontable/angular-wrapper","version":"0.0.0-next-dddc256-20261103","description":"Handsontable DataGrid for Angular with a spreadsheet look and feel.","author":"Handsoncode <hello@handsoncode.net> (https://handsoncode.net)","license":"SEE LICENSE IN LICENSE.txt","homepage":"https://handsontable.com","keywords":["handsontable","component","data","table","grid","data table","data grid","spreadsheet","sheet","excel","angular","angular component","angular grid","wrapper","pro","enterprise","sort","formulas","filter","search","conditional formatting","csv"],"repository":{"type":"git","url":"https://github.com/handsontable/handsontable.git"},"bugs":{"url":"https://github.com/handsontable/handsontable/issues"},"peerDependencies":{"@angular/core":">=16.0.0 <23.0.0","handsontable":"0.0.0-next-dddc256-20261103","rxjs":"^7.0.0"},"publishConfig":{"directory":"dist/hot-table","linkDirectory":true},"module":"fesm2022/handsontable-angular-wrapper.mjs","typings":"types/handsontable-angular-wrapper.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./types/handsontable-angular-wrapper.d.ts","default":"./fesm2022/handsontable-angular-wrapper.mjs"}},"sideEffects":false,"optionalDependencies":{"tslib":"^2.3.0"}}
@@ -779,6 +779,13 @@ export declare class HotTableComponent implements AfterViewInit, OnChanges, OnDe
779
779
  * input, because an app may delete the key from that object before passing a copy.
780
780
  */
781
781
  private _passedHookKeys;
782
+ /**
783
+ * The `height` and `width` keys whose size the grid holds from a `settings` input: passed a value, and
784
+ * not cleared since (a key left out of a later input keeps its size, so it stays listed). Only these
785
+ * are sent as `null` when an input sets them to `undefined`, so a size the app set through
786
+ * `hotInstance.updateSettings()` stays when the input never passed one.
787
+ */
788
+ private _passedClearedByNullKeys;
782
789
  constructor(_hotSettingsResolver: HotSettingsResolver, _hotConfig: HotGlobalConfigService, ngZone: NgZone, environmentInjector: EnvironmentInjector, _dynamicComponentService: DynamicComponentService);
783
790
  /**
784
791
  * Gets the Handsontable instance.
@@ -823,6 +830,23 @@ export declare class HotTableComponent implements AfterViewInit, OnChanges, OnDe
823
830
  * @param newOptions The settings about to be applied. Changed in place.
824
831
  */
825
832
  private clearRemovedHooks;
833
+ /**
834
+ * Sets to `null` each of `height` and `width` that the component last passed a value for and the new
835
+ * settings set to `undefined`, so `updateSettings()` resets the root element's size. A key missing from
836
+ * the new object is left out of the payload, and the grid keeps its size.
837
+ *
838
+ * @param newOptions The settings about to be applied. Changed in place.
839
+ */
840
+ private clearUnsetSizes;
841
+ /**
842
+ * Lists which of `height` and `width` hold a size the component applied: the keys the settings pass a
843
+ * value for, and the previously listed keys the settings leave out, because the grid keeps that size.
844
+ *
845
+ * @param settings The settings to read.
846
+ * @param previousKeys The keys listed for the previous settings.
847
+ * @returns The setting names.
848
+ */
849
+ private collectClearedByNullKeys;
826
850
  /**
827
851
  * Lists the hooks the settings pass a callback for. A key counts as a hook by the rule core's
828
852
  * `updateSettings()` uses in `core.ts`: a registered or a deprecated hook name. Only a function or an
@@ -861,7 +885,7 @@ export declare class HotTableComponent implements AfterViewInit, OnChanges, OnDe
861
885
  }, {}, never, never, true, never>;
862
886
  }
863
887
  export declare class HotTableModule {
864
- static readonly version = "0.0.0-next-0491dcb-20261103";
888
+ static readonly version = "0.0.0-next-dddc256-20261103";
865
889
  static ɵfac: i0.ɵɵFactoryDeclaration<HotTableModule, never>;
866
890
  static ɵmod: i0.ɵɵNgModuleDeclaration<HotTableModule, never, [typeof HotTableComponent], [typeof HotTableComponent]>;
867
891
  static ɵinj: i0.ɵɵInjectorDeclaration<HotTableModule>;