@ethlete/components 0.1.0-next.6 → 0.1.0-next.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-next.8
4
+
5
+ ### Minor Changes
6
+
7
+ - [`7dcbb8e`](https://github.com/ethlete-io/ethdk/commit/7dcbb8e3f3823728bc370fb89d1a89ee831e779b) Thanks [@TomTomB](https://github.com/TomTomB)! - Support surface theming in grid
8
+
9
+ ## 0.1.0-next.7
10
+
11
+ ### Patch Changes
12
+
13
+ - [`256b1b0`](https://github.com/ethlete-io/ethdk/commit/256b1b02d7598a0a6540af55447799a8ced469c4) Thanks [@TomTomB](https://github.com/TomTomB)! - Fix grid overlapping items with invalid base config
14
+
3
15
  ## 0.1.0-next.6
4
16
 
5
17
  ### Patch Changes
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { ChangeDetectionStrategy, ViewEncapsulation, Component, Directive, input, booleanAttribute, signal, effect, numberAttribute, computed, inject, ElementRef, InjectionToken, afterNextRender, untracked, DestroyRef, model, viewChild, Injector, output, ApplicationRef, EnvironmentInjector, DOCUMENT, createEnvironmentInjector, createComponent, TemplateRef, linkedSignal, afterRenderEffect, contentChild, inputBinding, PLATFORM_ID, isDevMode, contentChildren } from '@angular/core';
3
3
  import * as i2 from '@ethlete/core';
4
- import { injectStyleManager, createCanAnimateSignal, ColorInteractiveDirective, ProvideColorDirective, RuntimeError, injectErrorTheme, signalElementDimensions, createProvider, AnimatableDirective, ColorInteractiveContainerDirective, ColorInteractiveExcludeDirective, ProvideSurfaceDirective, SURFACE_PROVIDER, injectSurfaceThemes, resolveSurfaceByElevation, ColorInteractiveHasFocusDirective, createStaticRootProvider, signalHostElementDimensions, signalHostStyles, DragHandleDirective, injectRenderer, injectLocale, ResizeHandlesComponent, ANIMATED_LIFECYCLE_TOKEN, injectSurfaceContextTracker, AnimatedLifecycleDirective, createRootProvider, injectOverlayRuntime, typedBreakpointTransform, signalElementChildren, signalElementScrollState, signalElementIntersection, signalHostAttributes, signalHostClasses, getScrollContainerTarget, getScrollItemTarget, getElementScrollCoordinates, provideBreakpointInstance, signalClasses, useCursorDragScroll, signalStyles, getScrollSnapTarget, ScrollObserverDirective, ScrollObserverStartDirective, ScrollObserverEndDirective, injectViewportSize, createFlipAnimation, signalHostElementIntersection, injectHostElement, setInputSignal, SurfaceInteractiveDirective, injectRouterEvent, canUseSessionMemory, createAutoSessionMemoryKey, createSessionMemory, COLOR_PROVIDER, injectFocusVisibleTracker } from '@ethlete/core';
5
- import { NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
4
+ import { injectStyleManager, createCanAnimateSignal, ColorInteractiveDirective, ProvideColorDirective, RuntimeError, injectErrorTheme, signalElementDimensions, createProvider, AnimatableDirective, ColorInteractiveContainerDirective, ColorInteractiveExcludeDirective, ProvideSurfaceDirective, SURFACE_PROVIDER, injectSurfaceThemes, resolveSurfaceByElevation, ColorInteractiveHasFocusDirective, createStaticRootProvider, signalHostElementDimensions, DragHandleDirective, injectRenderer, injectLocale, ResizeHandlesComponent, ANIMATED_LIFECYCLE_TOKEN, injectSurfaceContextTracker, AnimatedLifecycleDirective, createRootProvider, injectOverlayRuntime, typedBreakpointTransform, signalElementChildren, signalElementScrollState, signalElementIntersection, signalHostAttributes, signalHostClasses, signalHostStyles, getScrollContainerTarget, getScrollItemTarget, getElementScrollCoordinates, provideBreakpointInstance, signalClasses, useCursorDragScroll, signalStyles, getScrollSnapTarget, ScrollObserverDirective, ScrollObserverStartDirective, ScrollObserverEndDirective, injectViewportSize, createFlipAnimation, signalHostElementIntersection, injectHostElement, setInputSignal, SurfaceInteractiveDirective, injectRouterEvent, canUseSessionMemory, createAutoSessionMemoryKey, createSessionMemory, COLOR_PROVIDER, injectFocusVisibleTracker } from '@ethlete/core';
5
+ import { NgTemplateOutlet, NgComponentOutlet, isPlatformBrowser } from '@angular/common';
6
6
  import { toObservable, takeUntilDestroyed, outputToObservable, outputFromObservable, rxResource } from '@angular/core/rxjs-interop';
7
7
  import { switchMap, EMPTY, filter, tap, timer, take, of, animationFrameScheduler, Subject, fromEvent, debounceTime, map, exhaustMap, takeUntil, finalize, distinctUntilChanged, Observable, shareReplay, catchError, interval } from 'rxjs';
8
8
  import { tap as tap$1 } from 'rxjs/operators';
@@ -2385,14 +2385,38 @@ const itemsCollide = (a, b) => {
2385
2385
  * Returns the first item that collides with the given position, or undefined if none.
2386
2386
  */
2387
2387
  const findCollision = (options) => options.entries.find((entry) => entry.id !== options.excludeId && itemsCollide(entry.position, options.position));
2388
+ /**
2389
+ * Clamps a position so it fits horizontally within the given column count.
2390
+ * Reduces an over-wide span and slides an out-of-bounds column back in range.
2391
+ */
2392
+ const clampToColumns = (position, columns) => {
2393
+ const colSpan = Math.max(1, Math.min(position.colSpan, columns));
2394
+ const col = Math.max(0, Math.min(position.col, columns - colSpan));
2395
+ return { ...position, col, colSpan };
2396
+ };
2388
2397
  /**
2389
2398
  * Compacts the layout vertically (moves items up as far as possible without collision).
2399
+ *
2400
+ * Also acts as a self-healing normaliser: positions that overflow the grid horizontally
2401
+ * (e.g. stale data from a wider breakpoint clamped into a narrower one — a colSpan of 12
2402
+ * or a col of 8 in a 6-column grid) are first clamped back into bounds, then any items
2403
+ * left overlapping are pushed down before the upward compaction runs. This guarantees the
2404
+ * returned layout is always in-bounds and overlap-free regardless of the input — clamping
2405
+ * a column alone is not enough, because it can drop an item on top of an existing one.
2390
2406
  */
2391
- const compactLayout = (entries, _columns) => {
2392
- const sorted = [...entries].sort((a, b) => a.position.row - b.position.row || a.position.col - b.position.col);
2407
+ const compactLayout = (entries, columns) => {
2408
+ const sorted = [...entries]
2409
+ .map((entry) => ({ ...entry, position: clampToColumns(entry.position, columns) }))
2410
+ .sort((a, b) => a.position.row - b.position.row || a.position.col - b.position.col);
2393
2411
  const compacted = [];
2394
2412
  for (const entry of sorted) {
2395
2413
  const candidate = { ...entry, position: { ...entry.position } };
2414
+ // Push down past any already-placed item it overlaps. This resolves overlaps introduced
2415
+ // by clamping out-of-bounds columns (which the upward pass below cannot fix on its own).
2416
+ while (findCollision({ entries: compacted, position: candidate.position, excludeId: candidate.id })) {
2417
+ candidate.position.row += 1;
2418
+ }
2419
+ // Then pull up as far as possible without colliding.
2396
2420
  while (candidate.position.row > 0) {
2397
2421
  const moved = { ...candidate, position: { ...candidate.position, row: candidate.position.row - 1 } };
2398
2422
  if (findCollision({ entries: compacted, position: moved.position, excludeId: candidate.id })) {
@@ -3302,10 +3326,8 @@ class GridItemDirective {
3302
3326
  this.currentRow = computed(() => this.renderPosition()?.row ?? 0, ...(ngDevMode ? [{ debugName: "currentRow" }] : /* istanbul ignore next */ []));
3303
3327
  this.currentColSpan = computed(() => this.renderPosition()?.colSpan ?? 1, ...(ngDevMode ? [{ debugName: "currentColSpan" }] : /* istanbul ignore next */ []));
3304
3328
  this.currentRowSpan = computed(() => this.renderPosition()?.rowSpan ?? 1, ...(ngDevMode ? [{ debugName: "currentRowSpan" }] : /* istanbul ignore next */ []));
3305
- this.hostStyles = signalHostStyles({
3306
- 'grid-column': computed(() => `${this.currentCol() + 1} / span ${this.currentColSpan()}`),
3307
- 'grid-row': computed(() => `${this.currentRow() + 1} / span ${this.currentRowSpan()}`),
3308
- });
3329
+ this.gridColumn = computed(() => `${this.currentCol() + 1} / span ${this.currentColSpan()}`, ...(ngDevMode ? [{ debugName: "gridColumn" }] : /* istanbul ignore next */ []));
3330
+ this.gridRow = computed(() => `${this.currentRow() + 1} / span ${this.currentRowSpan()}`, ...(ngDevMode ? [{ debugName: "gridRow" }] : /* istanbul ignore next */ []));
3309
3331
  effect((onCleanup) => {
3310
3332
  const id = this.itemId();
3311
3333
  const el = this.hostElement.nativeElement;
@@ -3336,7 +3358,7 @@ class GridItemDirective {
3336
3358
  });
3337
3359
  }
3338
3360
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3339
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: GridItemDirective, isStandalone: true, selector: "[etGridItem]", inputs: { itemId: { classPropertyName: "itemId", publicName: "itemId", isSignal: true, isRequired: true, transformFunction: null }, minColSpan: { classPropertyName: "minColSpan", publicName: "minColSpan", isSignal: true, isRequired: false, transformFunction: null }, maxColSpan: { classPropertyName: "maxColSpan", publicName: "maxColSpan", isSignal: true, isRequired: false, transformFunction: null }, minRowSpan: { classPropertyName: "minRowSpan", publicName: "minRowSpan", isSignal: true, isRequired: false, transformFunction: null }, maxRowSpan: { classPropertyName: "maxRowSpan", publicName: "maxRowSpan", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-grid-item" }, exportAs: ["etGridItem"], ngImport: i0 }); }
3361
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.13", type: GridItemDirective, isStandalone: true, selector: "[etGridItem]", inputs: { itemId: { classPropertyName: "itemId", publicName: "itemId", isSignal: true, isRequired: true, transformFunction: null }, minColSpan: { classPropertyName: "minColSpan", publicName: "minColSpan", isSignal: true, isRequired: false, transformFunction: null }, maxColSpan: { classPropertyName: "maxColSpan", publicName: "maxColSpan", isSignal: true, isRequired: false, transformFunction: null }, minRowSpan: { classPropertyName: "minRowSpan", publicName: "minRowSpan", isSignal: true, isRequired: false, transformFunction: null }, maxRowSpan: { classPropertyName: "maxRowSpan", publicName: "maxRowSpan", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.grid-column": "gridColumn()", "style.grid-row": "gridRow()" }, classAttribute: "et-grid-item" }, exportAs: ["etGridItem"], ngImport: i0 }); }
3340
3362
  }
3341
3363
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridItemDirective, decorators: [{
3342
3364
  type: Directive,
@@ -3345,6 +3367,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
3345
3367
  exportAs: 'etGridItem',
3346
3368
  host: {
3347
3369
  class: 'et-grid-item',
3370
+ '[style.grid-column]': 'gridColumn()',
3371
+ '[style.grid-row]': 'gridRow()',
3348
3372
  },
3349
3373
  }]
3350
3374
  }], ctorParameters: () => [], propDecorators: { itemId: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemId", required: true }] }], minColSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "minColSpan", required: false }] }], maxColSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxColSpan", required: false }] }], minRowSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRowSpan", required: false }] }], maxRowSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRowSpan", required: false }] }] } });
@@ -3359,12 +3383,10 @@ class GridDragDirective {
3359
3383
  this.renderer = injectRenderer();
3360
3384
  this.dragStartClient = signal(null, ...(ngDevMode ? [{ debugName: "dragStartClient" }] : /* istanbul ignore next */ []));
3361
3385
  this.dragPixelOffset = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "dragPixelOffset" }] : /* istanbul ignore next */ []));
3362
- this.hostStyles = signalHostStyles({
3363
- transform: computed(() => {
3364
- const offset = this.dragPixelOffset();
3365
- return `translate(${offset.x}px, ${offset.y}px)`;
3366
- }),
3367
- });
3386
+ this.dragTransform = computed(() => {
3387
+ const offset = this.dragPixelOffset();
3388
+ return `translate(${offset.x}px, ${offset.y}px)`;
3389
+ }, ...(ngDevMode ? [{ debugName: "dragTransform" }] : /* istanbul ignore next */ []));
3368
3390
  outputToObservable(this.dragHandle.dragStarted)
3369
3391
  .pipe(filter(() => !this.grid.readOnly()), tap(() => {
3370
3392
  this.dragPixelOffset.set({ x: 0, y: 0 });
@@ -3478,7 +3500,7 @@ class GridDragDirective {
3478
3500
  this.renderer.removeStyles(el, 'position', 'left', 'top', 'width', 'height');
3479
3501
  }
3480
3502
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridDragDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3481
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.13", type: GridDragDirective, isStandalone: true, selector: "[etGridDrag]", host: { properties: { "class.et-grid-drag--active": "!grid.readOnly() && dragHandle.isDragging()", "attr.aria-grabbed": "!grid.readOnly() && dragHandle.isDragging()" }, classAttribute: "et-grid-drag" }, hostDirectives: [{ directive: i2.DragHandleDirective, outputs: ["dragStarted", "dragStarted", "dragMoved", "dragMoved", "dragEnded", "dragEnded"] }], ngImport: i0 }); }
3503
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.13", type: GridDragDirective, isStandalone: true, selector: "[etGridDrag]", host: { properties: { "class.et-grid-drag--active": "!grid.readOnly() && dragHandle.isDragging()", "attr.aria-grabbed": "!grid.readOnly() && dragHandle.isDragging()", "style.transform": "dragTransform()" }, classAttribute: "et-grid-drag" }, hostDirectives: [{ directive: i2.DragHandleDirective, outputs: ["dragStarted", "dragStarted", "dragMoved", "dragMoved", "dragEnded", "dragEnded"] }], ngImport: i0 }); }
3482
3504
  }
3483
3505
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridDragDirective, decorators: [{
3484
3506
  type: Directive,
@@ -3494,6 +3516,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
3494
3516
  class: 'et-grid-drag',
3495
3517
  '[class.et-grid-drag--active]': '!grid.readOnly() && dragHandle.isDragging()',
3496
3518
  '[attr.aria-grabbed]': '!grid.readOnly() && dragHandle.isDragging()',
3519
+ '[style.transform]': 'dragTransform()',
3497
3520
  },
3498
3521
  }]
3499
3522
  }], ctorParameters: () => [] });
@@ -3613,75 +3636,37 @@ const fromGridPosition = (pos) => ({
3613
3636
  rows: pos.rowSpan,
3614
3637
  });
3615
3638
 
3616
- class GridComponent {
3617
- constructor() {
3618
- this.grid = inject(GridDirective);
3619
- this.ghostRef = viewChild('ghostRef', ...(ngDevMode ? [{ debugName: "ghostRef" }] : /* istanbul ignore next */ []));
3620
- this.gridConfig = injectGridConfig();
3621
- this.locale = injectLocale();
3622
- this.ariaLabel = computed(() => {
3623
- const label = this.grid.readOnly() ? this.gridConfig.readonlyAriaLabel : this.gridConfig.interactiveAriaLabel;
3624
- return this.gridConfig.transformer(label, this.locale.currentLocale());
3625
- }, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3626
- this.hostStyles = signalHostStyles({
3627
- '--_et-grid-columns': computed(() => `${this.grid.activeColumns()}`),
3628
- '--et-grid-gap': computed(() => `${this.grid.gap()}px`),
3629
- '--et-grid-row-height': computed(() => `${this.grid.rowHeight()}px`),
3630
- });
3631
- effect(() => {
3632
- this.grid.setGhostElement(this.ghostRef()?.nativeElement ?? null);
3633
- });
3634
- }
3635
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3636
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: GridComponent, isStandalone: true, selector: "et-grid, [et-grid]", host: { attributes: { "role": "region" }, properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "et-grid" }, viewQueries: [{ propertyName: "ghostRef", first: true, predicate: ["ghostRef"], descendants: true, isSignal: true }], hostDirectives: [{ directive: GridDirective, inputs: ["breakpoints", "breakpoints", "rowHeight", "rowHeight", "gap", "gap", "initialItems", "initialItems", "readOnly", "readOnly"], outputs: ["layoutChange", "layoutChange"] }], ngImport: i0, template: `
3637
- <ng-content />
3638
- @if (grid.ghostPosition(); as ghost) {
3639
- <div
3640
- #ghostRef
3641
- [style.grid-column]="ghost.col + 1 + ' / span ' + ghost.colSpan"
3642
- [style.grid-row]="ghost.row + 1 + ' / span ' + ghost.rowSpan"
3643
- class="et-grid-ghost"
3644
- ></div>
3645
- }
3646
- `, isInline: true, styles: ["@property --et-grid-gap{syntax: \"<length>\"; inherits: false; initial-value: 16px;}@property --et-grid-row-height{syntax: \"<length>\"; inherits: false; initial-value: 100px;}@property --et-grid-padding{syntax: \"<length>\"; inherits: false; initial-value: 0px;}.et-grid{display:grid;grid-template-columns:repeat(var(--_et-grid-columns, 12),1fr);grid-auto-rows:var(--et-grid-row-height);gap:var(--et-grid-gap);padding:var(--et-grid-padding);position:relative;min-height:0}.et-grid:has(.et-grid-item--dragging,.et-grid-item--resizing){-webkit-user-select:none;user-select:none;cursor:grabbing}.et-grid:has(.et-grid-item--resizing){cursor:nwse-resize}.et-grid-ghost{border-radius:8px;background:rgb(var(--et-surface-color, 23 23 23) / .08);border:2px dashed rgb(var(--et-surface-color, 23 23 23) / .2);pointer-events:none;transition:grid-column 0s,grid-row 0s}.et-grid--readonly .et-grid-item__drag-handle{cursor:default;pointer-events:none}.et-grid--readonly .et-grid-item__actions{display:none}.et-grid--readonly .et-grid-item:hover .et-resize-handle--e:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--s:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--w:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--n:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--se:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--sw:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--ne:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--nw:after{content:unset}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3647
- }
3648
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridComponent, decorators: [{
3649
- type: Component,
3650
- args: [{ selector: 'et-grid, [et-grid]', template: `
3651
- <ng-content />
3652
- @if (grid.ghostPosition(); as ghost) {
3653
- <div
3654
- #ghostRef
3655
- [style.grid-column]="ghost.col + 1 + ' / span ' + ghost.colSpan"
3656
- [style.grid-row]="ghost.row + 1 + ' / span ' + ghost.rowSpan"
3657
- class="et-grid-ghost"
3658
- ></div>
3659
- }
3660
- `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [
3661
- {
3662
- directive: GridDirective,
3663
- inputs: ['breakpoints', 'rowHeight', 'gap', 'initialItems', 'readOnly'],
3664
- outputs: ['layoutChange'],
3665
- },
3666
- ], host: {
3667
- class: 'et-grid',
3668
- role: 'region',
3669
- '[attr.aria-label]': 'ariaLabel()',
3670
- }, styles: ["@property --et-grid-gap{syntax: \"<length>\"; inherits: false; initial-value: 16px;}@property --et-grid-row-height{syntax: \"<length>\"; inherits: false; initial-value: 100px;}@property --et-grid-padding{syntax: \"<length>\"; inherits: false; initial-value: 0px;}.et-grid{display:grid;grid-template-columns:repeat(var(--_et-grid-columns, 12),1fr);grid-auto-rows:var(--et-grid-row-height);gap:var(--et-grid-gap);padding:var(--et-grid-padding);position:relative;min-height:0}.et-grid:has(.et-grid-item--dragging,.et-grid-item--resizing){-webkit-user-select:none;user-select:none;cursor:grabbing}.et-grid:has(.et-grid-item--resizing){cursor:nwse-resize}.et-grid-ghost{border-radius:8px;background:rgb(var(--et-surface-color, 23 23 23) / .08);border:2px dashed rgb(var(--et-surface-color, 23 23 23) / .2);pointer-events:none;transition:grid-column 0s,grid-row 0s}.et-grid--readonly .et-grid-item__drag-handle{cursor:default;pointer-events:none}.et-grid--readonly .et-grid-item__actions{display:none}.et-grid--readonly .et-grid-item:hover .et-resize-handle--e:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--s:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--w:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--n:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--se:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--sw:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--ne:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--nw:after{content:unset}\n"] }]
3671
- }], ctorParameters: () => [], propDecorators: { ghostRef: [{ type: i0.ViewChild, args: ['ghostRef', { isSignal: true }] }] } });
3672
-
3673
3639
  class GridItemComponent {
3674
3640
  constructor() {
3675
3641
  this.grid = inject(GRID_TOKEN);
3676
3642
  this.gridItem = inject(GridItemDirective);
3643
+ this.provideSurface = inject(ProvideSurfaceDirective);
3644
+ this.parentSurfaceProvider = inject(SURFACE_PROVIDER, { optional: true, skipSelf: true });
3677
3645
  this.gridDrag = inject(GridDragDirective);
3678
3646
  this.gridResize = inject(GridResizeDirective);
3679
3647
  this.ariaLabel = input('Grid item', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3680
3648
  this.removed = output();
3649
+ this.surfaceThemes = injectSurfaceThemes({ optional: true });
3681
3650
  this.gridConfig = injectGridConfig();
3682
3651
  this.locale = injectLocale();
3683
3652
  this.isReadOnly = computed(() => this.grid.readOnly(), ...(ngDevMode ? [{ debugName: "isReadOnly" }] : /* istanbul ignore next */ []));
3684
3653
  this.dragHandleAriaLabel = computed(() => this.gridConfig.transformer(this.gridConfig.dragHandleAriaLabel, this.locale.currentLocale()), ...(ngDevMode ? [{ debugName: "dragHandleAriaLabel" }] : /* istanbul ignore next */ []));
3654
+ this.resolvedSurface = computed(() => {
3655
+ const themes = this.surfaceThemes;
3656
+ const parent = this.parentSurfaceProvider;
3657
+ if (!themes || !parent)
3658
+ return null;
3659
+ return resolveSurfaceByElevation(themes, parent.surfaceType() ?? 'dark', parent.elevation() + 1);
3660
+ }, ...(ngDevMode ? [{ debugName: "resolvedSurface" }] : /* istanbul ignore next */ []));
3661
+ effect(() => {
3662
+ const surface = this.resolvedSurface();
3663
+ if (surface) {
3664
+ this.provideSurface.forceSurface(surface.name);
3665
+ }
3666
+ else {
3667
+ this.provideSurface.clearForcedSurface();
3668
+ }
3669
+ });
3685
3670
  }
3686
3671
  applyKeyboardShortcut(event) {
3687
3672
  if (this.isReadOnly())
@@ -3745,7 +3730,7 @@ class GridItemComponent {
3745
3730
  }
3746
3731
  }
3747
3732
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3748
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: GridItemComponent, isStandalone: true, selector: "et-grid-item, [et-grid-item]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { listeners: { "keydown": "applyKeyboardShortcut($event)" }, properties: { "class.et-grid-item--dragging": "!isReadOnly() && gridDrag.dragHandle.isDragging()", "class.et-grid-item--resizing": "gridResize.isResizing()", "attr.role": "\"group\"", "attr.aria-label": "ariaLabel()", "attr.tabindex": "\"0\"" }, classAttribute: "et-grid-item" }, hostDirectives: [{ directive: GridItemDirective, inputs: ["itemId", "itemId", "minColSpan", "minColSpan", "maxColSpan", "maxColSpan", "minRowSpan", "minRowSpan", "maxRowSpan", "maxRowSpan"] }, { directive: GridDragDirective }, { directive: GridResizeDirective }], ngImport: i0, template: `
3733
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: GridItemComponent, isStandalone: true, selector: "et-grid-item, [et-grid-item]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { listeners: { "keydown": "applyKeyboardShortcut($event)" }, properties: { "class.et-grid-item--dragging": "!isReadOnly() && gridDrag.dragHandle.isDragging()", "class.et-grid-item--resizing": "gridResize.isResizing()", "attr.role": "\"group\"", "attr.aria-label": "ariaLabel()", "attr.tabindex": "\"0\"" }, classAttribute: "et-grid-item" }, hostDirectives: [{ directive: GridItemDirective, inputs: ["itemId", "itemId", "minColSpan", "minColSpan", "maxColSpan", "maxColSpan", "minRowSpan", "minRowSpan", "maxRowSpan", "maxRowSpan"] }, { directive: GridDragDirective }, { directive: GridResizeDirective }, { directive: i2.ProvideSurfaceDirective }], ngImport: i0, template: `
3749
3734
  <div [attr.aria-label]="dragHandleAriaLabel()" class="et-grid-item__drag-handle">
3750
3735
  <ng-content select="[etGridItemDragHandle]" />
3751
3736
  </div>
@@ -3766,7 +3751,7 @@ class GridItemComponent {
3766
3751
  <div (pointerdown)="$event.stopPropagation()" class="et-grid-item__actions">
3767
3752
  <ng-content select="[etGridItemAction]" />
3768
3753
  </div>
3769
- `, isInline: true, styles: ["@property --et-grid-item-border-radius{syntax: \"<length>\"; inherits: false; initial-value: 8px;}@property --et-grid-item-bg{syntax: \"<color>\"; inherits: false; initial-value: rgb(var(--et-surface-background, 255 255 255));}@property --et-grid-item-shadow{syntax: \"*\"; inherits: false; initial-value: 0 1px 3px rgba(0,0,0,.12);}@property --et-grid-item-drag-handle-height{syntax: \"<length>\"; inherits: false; initial-value: 32px;}.et-grid-item{position:relative;border-radius:var(--et-grid-item-border-radius);background:var(--et-grid-item-bg);box-shadow:var(--et-grid-item-shadow);border:1px solid rgb(var(--et-surface-border, 229 229 229));color:rgb(var(--et-surface-color, 23 23 23));overflow:hidden;display:flex;flex-direction:column;outline:none;will-change:transform}.et-grid-item:focus-visible{box-shadow:0 0 0 2px var(--et-grid-item-focus-ring-color, #2563eb)}.et-grid-item:is(.et-grid-item--dragging){z-index:100;box-shadow:0 12px 32px #0003;opacity:.95;cursor:grabbing;-webkit-user-select:none;user-select:none}.et-grid-item:is(.et-grid-item--resizing){z-index:100;-webkit-user-select:none;user-select:none}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--nw:after{content:\"\";position:absolute;border-radius:2px;background:rgb(var(--et-surface-color, 23 23 23) / .2);transition:opacity .15s ease}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--e:after{right:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--w:after{left:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--s:after{bottom:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--n:after{top:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--se:after{bottom:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--sw:after{bottom:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--ne:after{top:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--nw:after{top:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item__drag-handle{height:var(--et-grid-item-drag-handle-height);cursor:grab;display:flex;align-items:center;padding-inline:8px;-webkit-user-select:none;user-select:none;touch-action:none}.et-grid-item--dragging .et-grid-item__drag-handle{cursor:grabbing}.et-grid-item__content{flex:1;overflow:hidden;min-height:0}.et-grid-item__actions{position:absolute;top:4px;right:4px;display:flex;gap:4px}\n"], dependencies: [{ kind: "component", type: ResizeHandlesComponent, selector: "et-resize-handles", inputs: ["edges", "disabled"], outputs: ["resizeStarted", "resizeMoved", "resizeEnded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3754
+ `, isInline: true, styles: [".et-grid-item{position:relative;display:flex;flex-direction:column;outline:none;will-change:transform;border-radius:var(--et-grid-item-radius, 0);background:var(--et-grid-item-bg, var(--et-surface-background-solid))}.et-grid-item:is(.et-grid-item--dragging){z-index:100;cursor:grabbing;-webkit-user-select:none;user-select:none}.et-grid-item:is(.et-grid-item--resizing){z-index:100;-webkit-user-select:none;user-select:none}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--nw:after{content:\"\";position:absolute;border-radius:2px;background:var(--et-grid-item-resize-handle-color, var(--et-surface-color-solid));opacity:.2}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--e:after{right:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--w:after{left:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--s:after{bottom:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--n:after{top:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--se:after{bottom:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--sw:after{bottom:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--ne:after{top:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--nw:after{top:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item__drag-handle{cursor:grab;display:flex;align-items:center;-webkit-user-select:none;user-select:none;touch-action:none}.et-grid-item--dragging .et-grid-item__drag-handle{cursor:grabbing}.et-grid-item__content{flex:1;min-height:0}.et-grid-item__actions{position:absolute;top:4px;right:4px;display:flex;gap:4px}\n"], dependencies: [{ kind: "component", type: ResizeHandlesComponent, selector: "et-resize-handles", inputs: ["edges", "disabled"], outputs: ["resizeStarted", "resizeMoved", "resizeEnded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3770
3755
  }
3771
3756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridItemComponent, decorators: [{
3772
3757
  type: Component,
@@ -3798,6 +3783,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
3798
3783
  },
3799
3784
  GridDragDirective,
3800
3785
  GridResizeDirective,
3786
+ ProvideSurfaceDirective,
3801
3787
  ], host: {
3802
3788
  class: 'et-grid-item',
3803
3789
  '[class.et-grid-item--dragging]': '!isReadOnly() && gridDrag.dragHandle.isDragging()',
@@ -3806,8 +3792,138 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
3806
3792
  '[attr.aria-label]': 'ariaLabel()',
3807
3793
  '[attr.tabindex]': '"0"',
3808
3794
  '(keydown)': 'applyKeyboardShortcut($event)',
3809
- }, styles: ["@property --et-grid-item-border-radius{syntax: \"<length>\"; inherits: false; initial-value: 8px;}@property --et-grid-item-bg{syntax: \"<color>\"; inherits: false; initial-value: rgb(var(--et-surface-background, 255 255 255));}@property --et-grid-item-shadow{syntax: \"*\"; inherits: false; initial-value: 0 1px 3px rgba(0,0,0,.12);}@property --et-grid-item-drag-handle-height{syntax: \"<length>\"; inherits: false; initial-value: 32px;}.et-grid-item{position:relative;border-radius:var(--et-grid-item-border-radius);background:var(--et-grid-item-bg);box-shadow:var(--et-grid-item-shadow);border:1px solid rgb(var(--et-surface-border, 229 229 229));color:rgb(var(--et-surface-color, 23 23 23));overflow:hidden;display:flex;flex-direction:column;outline:none;will-change:transform}.et-grid-item:focus-visible{box-shadow:0 0 0 2px var(--et-grid-item-focus-ring-color, #2563eb)}.et-grid-item:is(.et-grid-item--dragging){z-index:100;box-shadow:0 12px 32px #0003;opacity:.95;cursor:grabbing;-webkit-user-select:none;user-select:none}.et-grid-item:is(.et-grid-item--resizing){z-index:100;-webkit-user-select:none;user-select:none}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--nw:after{content:\"\";position:absolute;border-radius:2px;background:rgb(var(--et-surface-color, 23 23 23) / .2);transition:opacity .15s ease}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--e:after{right:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--w:after{left:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--s:after{bottom:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--n:after{top:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--se:after{bottom:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--sw:after{bottom:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--ne:after{top:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--nw:after{top:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item__drag-handle{height:var(--et-grid-item-drag-handle-height);cursor:grab;display:flex;align-items:center;padding-inline:8px;-webkit-user-select:none;user-select:none;touch-action:none}.et-grid-item--dragging .et-grid-item__drag-handle{cursor:grabbing}.et-grid-item__content{flex:1;overflow:hidden;min-height:0}.et-grid-item__actions{position:absolute;top:4px;right:4px;display:flex;gap:4px}\n"] }]
3810
- }], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
3795
+ }, styles: [".et-grid-item{position:relative;display:flex;flex-direction:column;outline:none;will-change:transform;border-radius:var(--et-grid-item-radius, 0);background:var(--et-grid-item-bg, var(--et-surface-background-solid))}.et-grid-item:is(.et-grid-item--dragging){z-index:100;cursor:grabbing;-webkit-user-select:none;user-select:none}.et-grid-item:is(.et-grid-item--resizing){z-index:100;-webkit-user-select:none;user-select:none}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--nw:after{content:\"\";position:absolute;border-radius:2px;background:var(--et-grid-item-resize-handle-color, var(--et-surface-color-solid));opacity:.2}.et-grid-item:hover .et-resize-handle--e:after,.et-grid-item--resizing .et-resize-handle--e:after{right:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--w:after,.et-grid-item--resizing .et-resize-handle--w:after{left:2px;top:50%;transform:translateY(-50%);width:3px;height:24px}.et-grid-item:hover .et-resize-handle--s:after,.et-grid-item--resizing .et-resize-handle--s:after{bottom:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--n:after,.et-grid-item--resizing .et-resize-handle--n:after{top:2px;left:50%;transform:translate(-50%);height:3px;width:24px}.et-grid-item:hover .et-resize-handle--se:after,.et-grid-item--resizing .et-resize-handle--se:after{bottom:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--sw:after,.et-grid-item--resizing .et-resize-handle--sw:after{bottom:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--ne:after,.et-grid-item--resizing .et-resize-handle--ne:after{top:3px;right:3px;width:8px;height:8px;border-radius:1px}.et-grid-item:hover .et-resize-handle--nw:after,.et-grid-item--resizing .et-resize-handle--nw:after{top:3px;left:3px;width:8px;height:8px;border-radius:1px}.et-grid-item__drag-handle{cursor:grab;display:flex;align-items:center;-webkit-user-select:none;user-select:none;touch-action:none}.et-grid-item--dragging .et-grid-item__drag-handle{cursor:grabbing}.et-grid-item__content{flex:1;min-height:0}.et-grid-item__actions{position:absolute;top:4px;right:4px;display:flex;gap:4px}\n"] }]
3796
+ }], ctorParameters: () => [], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
3797
+
3798
+ class GridComponent {
3799
+ constructor() {
3800
+ this.grid = inject(GridDirective);
3801
+ this.ghostRef = viewChild('ghostRef', ...(ngDevMode ? [{ debugName: "ghostRef" }] : /* istanbul ignore next */ []));
3802
+ this.gridConfig = injectGridConfig();
3803
+ this.locale = injectLocale();
3804
+ this.isReadOnly = computed(() => this.grid.readOnly(), ...(ngDevMode ? [{ debugName: "isReadOnly" }] : /* istanbul ignore next */ []));
3805
+ this.dragHandleComponent = computed(() => this.gridConfig.dragHandleComponent, ...(ngDevMode ? [{ debugName: "dragHandleComponent" }] : /* istanbul ignore next */ []));
3806
+ this.actionsComponent = computed(() => this.gridConfig.actionsComponent, ...(ngDevMode ? [{ debugName: "actionsComponent" }] : /* istanbul ignore next */ []));
3807
+ this.registeredItems = computed(() => {
3808
+ const registrations = this.gridConfig.registrations;
3809
+ return this.grid.items().flatMap((item) => {
3810
+ const reg = registrations.find((r) => r.type === item.type);
3811
+ return reg ? [{ item, reg }] : [];
3812
+ });
3813
+ }, ...(ngDevMode ? [{ debugName: "registeredItems" }] : /* istanbul ignore next */ []));
3814
+ this.ariaLabel = computed(() => {
3815
+ const label = this.grid.readOnly() ? this.gridConfig.readonlyAriaLabel : this.gridConfig.interactiveAriaLabel;
3816
+ return this.gridConfig.transformer(label, this.locale.currentLocale());
3817
+ }, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3818
+ this.gridColumns = computed(() => this.grid.activeColumns(), ...(ngDevMode ? [{ debugName: "gridColumns" }] : /* istanbul ignore next */ []));
3819
+ this.gridGap = computed(() => `${this.grid.gap()}px`, ...(ngDevMode ? [{ debugName: "gridGap" }] : /* istanbul ignore next */ []));
3820
+ this.gridRowHeight = computed(() => `${this.grid.rowHeight()}px`, ...(ngDevMode ? [{ debugName: "gridRowHeight" }] : /* istanbul ignore next */ []));
3821
+ effect(() => {
3822
+ this.grid.setGhostElement(this.ghostRef()?.nativeElement ?? null);
3823
+ });
3824
+ }
3825
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3826
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: GridComponent, isStandalone: true, selector: "et-grid, [et-grid]", host: { attributes: { "role": "region" }, properties: { "attr.aria-label": "ariaLabel()", "style.--_et-grid-columns": "gridColumns()", "style.--et-grid-gap": "gridGap()", "style.--et-grid-row-height": "gridRowHeight()" }, classAttribute: "et-grid" }, viewQueries: [{ propertyName: "ghostRef", first: true, predicate: ["ghostRef"], descendants: true, isSignal: true }], hostDirectives: [{ directive: GridDirective, inputs: ["breakpoints", "breakpoints", "rowHeight", "rowHeight", "gap", "gap", "initialItems", "initialItems", "readOnly", "readOnly"], outputs: ["layoutChange", "layoutChange"] }], ngImport: i0, template: `
3827
+ @for (entry of registeredItems(); track entry.item.id) {
3828
+ <et-grid-item
3829
+ [itemId]="entry.item.id"
3830
+ [minColSpan]="entry.reg.constraints?.minColSpan ?? 1"
3831
+ [maxColSpan]="entry.reg.constraints?.maxColSpan ?? 12"
3832
+ [minRowSpan]="entry.reg.constraints?.minRowSpan ?? 1"
3833
+ [maxRowSpan]="entry.reg.constraints?.maxRowSpan ?? 4"
3834
+ >
3835
+ @if (dragHandleComponent()) {
3836
+ <div etGridItemDragHandle>
3837
+ <ng-container
3838
+ [ngComponentOutlet]="dragHandleComponent()!"
3839
+ [ngComponentOutletInputs]="{ data: entry.item.data, itemId: entry.item.id }"
3840
+ />
3841
+ </div>
3842
+ } @else {
3843
+ <div etGridItemDragHandle></div>
3844
+ }
3845
+ <ng-container [ngComponentOutlet]="entry.reg.component" [ngComponentOutletInputs]="{ data: entry.item.data }" />
3846
+ @if (actionsComponent()) {
3847
+ <div etGridItemAction>
3848
+ <ng-container
3849
+ [ngComponentOutlet]="actionsComponent()!"
3850
+ [ngComponentOutletInputs]="{ data: entry.item.data, itemId: entry.item.id }"
3851
+ />
3852
+ </div>
3853
+ } @else if (!isReadOnly()) {
3854
+ <button (click)="grid.removeItem(entry.item.id)" etGridItemAction>✕</button>
3855
+ }
3856
+ </et-grid-item>
3857
+ }
3858
+ <ng-content />
3859
+ @if (grid.ghostPosition(); as ghost) {
3860
+ <div
3861
+ #ghostRef
3862
+ [style.grid-column]="ghost.col + 1 + ' / span ' + ghost.colSpan"
3863
+ [style.grid-row]="ghost.row + 1 + ' / span ' + ghost.rowSpan"
3864
+ class="et-grid-ghost"
3865
+ ></div>
3866
+ }
3867
+ `, isInline: true, styles: ["@property --et-grid-gap{syntax: \"<length>\"; inherits: false; initial-value: 16px;}@property --et-grid-row-height{syntax: \"<length>\"; inherits: false; initial-value: 100px;}@property --et-grid-padding{syntax: \"<length>\"; inherits: false; initial-value: 0px;}.et-grid{display:grid;grid-template-columns:repeat(var(--_et-grid-columns, 12),1fr);grid-auto-rows:var(--et-grid-row-height);gap:var(--et-grid-gap);padding:var(--et-grid-padding);position:relative;min-height:0}.et-grid:has(.et-grid-item--dragging,.et-grid-item--resizing){-webkit-user-select:none;user-select:none;cursor:grabbing}.et-grid:has(.et-grid-item--resizing){cursor:nwse-resize}.et-grid-ghost{border-radius:8px;background:rgb(var(--et-surface-color, 23 23 23) / .08);border:2px dashed rgb(var(--et-surface-color, 23 23 23) / .2);pointer-events:none;transition:grid-column 0s,grid-row 0s}.et-grid--readonly .et-grid-item__drag-handle{cursor:default;pointer-events:none}.et-grid--readonly .et-grid-item__actions{display:none}.et-grid--readonly .et-grid-item:hover .et-resize-handle--e:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--s:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--w:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--n:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--se:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--sw:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--ne:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--nw:after{content:unset}\n"], dependencies: [{ kind: "component", type: GridItemComponent, selector: "et-grid-item, [et-grid-item]", inputs: ["ariaLabel"], outputs: ["removed"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3868
+ }
3869
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridComponent, decorators: [{
3870
+ type: Component,
3871
+ args: [{ selector: 'et-grid, [et-grid]', template: `
3872
+ @for (entry of registeredItems(); track entry.item.id) {
3873
+ <et-grid-item
3874
+ [itemId]="entry.item.id"
3875
+ [minColSpan]="entry.reg.constraints?.minColSpan ?? 1"
3876
+ [maxColSpan]="entry.reg.constraints?.maxColSpan ?? 12"
3877
+ [minRowSpan]="entry.reg.constraints?.minRowSpan ?? 1"
3878
+ [maxRowSpan]="entry.reg.constraints?.maxRowSpan ?? 4"
3879
+ >
3880
+ @if (dragHandleComponent()) {
3881
+ <div etGridItemDragHandle>
3882
+ <ng-container
3883
+ [ngComponentOutlet]="dragHandleComponent()!"
3884
+ [ngComponentOutletInputs]="{ data: entry.item.data, itemId: entry.item.id }"
3885
+ />
3886
+ </div>
3887
+ } @else {
3888
+ <div etGridItemDragHandle></div>
3889
+ }
3890
+ <ng-container [ngComponentOutlet]="entry.reg.component" [ngComponentOutletInputs]="{ data: entry.item.data }" />
3891
+ @if (actionsComponent()) {
3892
+ <div etGridItemAction>
3893
+ <ng-container
3894
+ [ngComponentOutlet]="actionsComponent()!"
3895
+ [ngComponentOutletInputs]="{ data: entry.item.data, itemId: entry.item.id }"
3896
+ />
3897
+ </div>
3898
+ } @else if (!isReadOnly()) {
3899
+ <button (click)="grid.removeItem(entry.item.id)" etGridItemAction>✕</button>
3900
+ }
3901
+ </et-grid-item>
3902
+ }
3903
+ <ng-content />
3904
+ @if (grid.ghostPosition(); as ghost) {
3905
+ <div
3906
+ #ghostRef
3907
+ [style.grid-column]="ghost.col + 1 + ' / span ' + ghost.colSpan"
3908
+ [style.grid-row]="ghost.row + 1 + ' / span ' + ghost.rowSpan"
3909
+ class="et-grid-ghost"
3910
+ ></div>
3911
+ }
3912
+ `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [GridItemComponent, NgComponentOutlet], hostDirectives: [
3913
+ {
3914
+ directive: GridDirective,
3915
+ inputs: ['breakpoints', 'rowHeight', 'gap', 'initialItems', 'readOnly'],
3916
+ outputs: ['layoutChange'],
3917
+ },
3918
+ ], host: {
3919
+ class: 'et-grid',
3920
+ role: 'region',
3921
+ '[attr.aria-label]': 'ariaLabel()',
3922
+ '[style.--_et-grid-columns]': 'gridColumns()',
3923
+ '[style.--et-grid-gap]': 'gridGap()',
3924
+ '[style.--et-grid-row-height]': 'gridRowHeight()',
3925
+ }, styles: ["@property --et-grid-gap{syntax: \"<length>\"; inherits: false; initial-value: 16px;}@property --et-grid-row-height{syntax: \"<length>\"; inherits: false; initial-value: 100px;}@property --et-grid-padding{syntax: \"<length>\"; inherits: false; initial-value: 0px;}.et-grid{display:grid;grid-template-columns:repeat(var(--_et-grid-columns, 12),1fr);grid-auto-rows:var(--et-grid-row-height);gap:var(--et-grid-gap);padding:var(--et-grid-padding);position:relative;min-height:0}.et-grid:has(.et-grid-item--dragging,.et-grid-item--resizing){-webkit-user-select:none;user-select:none;cursor:grabbing}.et-grid:has(.et-grid-item--resizing){cursor:nwse-resize}.et-grid-ghost{border-radius:8px;background:rgb(var(--et-surface-color, 23 23 23) / .08);border:2px dashed rgb(var(--et-surface-color, 23 23 23) / .2);pointer-events:none;transition:grid-column 0s,grid-row 0s}.et-grid--readonly .et-grid-item__drag-handle{cursor:default;pointer-events:none}.et-grid--readonly .et-grid-item__actions{display:none}.et-grid--readonly .et-grid-item:hover .et-resize-handle--e:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--s:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--w:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--n:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--se:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--sw:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--ne:after,.et-grid--readonly .et-grid-item:hover .et-resize-handle--nw:after{content:unset}\n"] }]
3926
+ }], ctorParameters: () => [], propDecorators: { ghostRef: [{ type: i0.ViewChild, args: ['ghostRef', { isSignal: true }] }] } });
3811
3927
 
3812
3928
  const posEq = (a, b) => {
3813
3929
  if (!a && !b)