@ethlete/components 0.1.0-next.7 → 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,11 @@
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
+
3
9
  ## 0.1.0-next.7
4
10
 
5
11
  ### Patch Changes
@@ -2,7 +2,7 @@ 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
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, isPlatformBrowser } from '@angular/common';
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';
@@ -3636,76 +3636,37 @@ const fromGridPosition = (pos) => ({
3636
3636
  rows: pos.rowSpan,
3637
3637
  });
3638
3638
 
3639
- class GridComponent {
3640
- constructor() {
3641
- this.grid = inject(GridDirective);
3642
- this.ghostRef = viewChild('ghostRef', ...(ngDevMode ? [{ debugName: "ghostRef" }] : /* istanbul ignore next */ []));
3643
- this.gridConfig = injectGridConfig();
3644
- this.locale = injectLocale();
3645
- this.ariaLabel = computed(() => {
3646
- const label = this.grid.readOnly() ? this.gridConfig.readonlyAriaLabel : this.gridConfig.interactiveAriaLabel;
3647
- return this.gridConfig.transformer(label, this.locale.currentLocale());
3648
- }, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3649
- this.gridColumns = computed(() => this.grid.activeColumns(), ...(ngDevMode ? [{ debugName: "gridColumns" }] : /* istanbul ignore next */ []));
3650
- this.gridGap = computed(() => `${this.grid.gap()}px`, ...(ngDevMode ? [{ debugName: "gridGap" }] : /* istanbul ignore next */ []));
3651
- this.gridRowHeight = computed(() => `${this.grid.rowHeight()}px`, ...(ngDevMode ? [{ debugName: "gridRowHeight" }] : /* istanbul ignore next */ []));
3652
- effect(() => {
3653
- this.grid.setGhostElement(this.ghostRef()?.nativeElement ?? null);
3654
- });
3655
- }
3656
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3657
- 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: `
3658
- <ng-content />
3659
- @if (grid.ghostPosition(); as ghost) {
3660
- <div
3661
- #ghostRef
3662
- [style.grid-column]="ghost.col + 1 + ' / span ' + ghost.colSpan"
3663
- [style.grid-row]="ghost.row + 1 + ' / span ' + ghost.rowSpan"
3664
- class="et-grid-ghost"
3665
- ></div>
3666
- }
3667
- `, 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 }); }
3668
- }
3669
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridComponent, decorators: [{
3670
- type: Component,
3671
- args: [{ selector: 'et-grid, [et-grid]', template: `
3672
- <ng-content />
3673
- @if (grid.ghostPosition(); as ghost) {
3674
- <div
3675
- #ghostRef
3676
- [style.grid-column]="ghost.col + 1 + ' / span ' + ghost.colSpan"
3677
- [style.grid-row]="ghost.row + 1 + ' / span ' + ghost.rowSpan"
3678
- class="et-grid-ghost"
3679
- ></div>
3680
- }
3681
- `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [
3682
- {
3683
- directive: GridDirective,
3684
- inputs: ['breakpoints', 'rowHeight', 'gap', 'initialItems', 'readOnly'],
3685
- outputs: ['layoutChange'],
3686
- },
3687
- ], host: {
3688
- class: 'et-grid',
3689
- role: 'region',
3690
- '[attr.aria-label]': 'ariaLabel()',
3691
- '[style.--_et-grid-columns]': 'gridColumns()',
3692
- '[style.--et-grid-gap]': 'gridGap()',
3693
- '[style.--et-grid-row-height]': 'gridRowHeight()',
3694
- }, 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"] }]
3695
- }], ctorParameters: () => [], propDecorators: { ghostRef: [{ type: i0.ViewChild, args: ['ghostRef', { isSignal: true }] }] } });
3696
-
3697
3639
  class GridItemComponent {
3698
3640
  constructor() {
3699
3641
  this.grid = inject(GRID_TOKEN);
3700
3642
  this.gridItem = inject(GridItemDirective);
3643
+ this.provideSurface = inject(ProvideSurfaceDirective);
3644
+ this.parentSurfaceProvider = inject(SURFACE_PROVIDER, { optional: true, skipSelf: true });
3701
3645
  this.gridDrag = inject(GridDragDirective);
3702
3646
  this.gridResize = inject(GridResizeDirective);
3703
3647
  this.ariaLabel = input('Grid item', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3704
3648
  this.removed = output();
3649
+ this.surfaceThemes = injectSurfaceThemes({ optional: true });
3705
3650
  this.gridConfig = injectGridConfig();
3706
3651
  this.locale = injectLocale();
3707
3652
  this.isReadOnly = computed(() => this.grid.readOnly(), ...(ngDevMode ? [{ debugName: "isReadOnly" }] : /* istanbul ignore next */ []));
3708
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
+ });
3709
3670
  }
3710
3671
  applyKeyboardShortcut(event) {
3711
3672
  if (this.isReadOnly())
@@ -3769,7 +3730,7 @@ class GridItemComponent {
3769
3730
  }
3770
3731
  }
3771
3732
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3772
- 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: `
3773
3734
  <div [attr.aria-label]="dragHandleAriaLabel()" class="et-grid-item__drag-handle">
3774
3735
  <ng-content select="[etGridItemDragHandle]" />
3775
3736
  </div>
@@ -3790,7 +3751,7 @@ class GridItemComponent {
3790
3751
  <div (pointerdown)="$event.stopPropagation()" class="et-grid-item__actions">
3791
3752
  <ng-content select="[etGridItemAction]" />
3792
3753
  </div>
3793
- `, 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 }); }
3794
3755
  }
3795
3756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: GridItemComponent, decorators: [{
3796
3757
  type: Component,
@@ -3822,6 +3783,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
3822
3783
  },
3823
3784
  GridDragDirective,
3824
3785
  GridResizeDirective,
3786
+ ProvideSurfaceDirective,
3825
3787
  ], host: {
3826
3788
  class: 'et-grid-item',
3827
3789
  '[class.et-grid-item--dragging]': '!isReadOnly() && gridDrag.dragHandle.isDragging()',
@@ -3830,8 +3792,138 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
3830
3792
  '[attr.aria-label]': 'ariaLabel()',
3831
3793
  '[attr.tabindex]': '"0"',
3832
3794
  '(keydown)': 'applyKeyboardShortcut($event)',
3833
- }, 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"] }]
3834
- }], 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 }] }] } });
3835
3927
 
3836
3928
  const posEq = (a, b) => {
3837
3929
  if (!a && !b)