From 37fda13f7ecd2d7245510a020eafafb58edfe658 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Wed, 11 Jun 2025 15:34:31 +0300 Subject: [PATCH 1/8] initial commit --- .../components/grid/_grid-component.scss | 80 +++++++++---------- .../styles/components/grid/_grid-theme.scss | 11 +-- .../src/lib/grids/grid/grid.component.scss | 4 + .../src/lib/grids/grid/grid.component.ts | 5 +- .../src/lib/grids/themes/_base.scss | 40 ++++++++++ .../src/lib/grids/themes/dark/_index.scss | 6 ++ .../src/lib/grids/themes/dark/_tokens.scss | 7 ++ .../src/lib/grids/themes/light/_index.scss | 6 ++ .../src/lib/grids/themes/light/_tokens.scss | 8 ++ .../src/lib/grids/themes/shared/_index.scss | 1 + .../src/lib/grids/themes/shared/indigo.scss | 5 ++ 11 files changed, 127 insertions(+), 46 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/grids/grid/grid.component.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/_base.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/dark/_tokens.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/light/_index.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/light/_tokens.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/shared/indigo.scss diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index f446ffbe128..ffb7e87430f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -215,46 +215,46 @@ @extend %igx-grid__tr-container--active !optional; } - @include e(td) { - @extend %grid-cell-display !optional; - } - - @include e(td, $m: active) { - @extend %grid-cell--active !optional; - } - - @include e(td, $m: selected) { - @extend %grid-cell--selected !optional; - } - - @include e(td, $m: invalid) { - @extend %grid-cell--invalid !optional; - } - - @include e(td, $m: valid) { - @extend %grid-cell--valid !optional; - } - - @include e(td, $m: column-selected) { - @extend %grid-cell--column-selected !optional; - } - - @include e(td, $mods: (selected, column-selected)) { - @extend %grid-cell--cross-selected !optional; - } - - @include e(td, $m: bool) { - @extend %igx-grid__td--centered !optional; - @extend %igx-grid__td--bool !optional; - } - - @include e(td, $m: bool-true) { - @extend %igx-grid__td--bool-true !optional; - } - - @include e(td, $m: image) { - @extend %igx-grid__td--centered !optional; - } + // @include e(td) { + // @extend %grid-cell-display !optional; + // } + // + // @include e(td, $m: active) { + // @extend %grid-cell--active !optional; + // } + // + // @include e(td, $m: selected) { + // @extend %grid-cell--selected !optional; + // } + // + // @include e(td, $m: invalid) { + // @extend %grid-cell--invalid !optional; + // } + // + // @include e(td, $m: valid) { + // @extend %grid-cell--valid !optional; + // } + // + // @include e(td, $m: column-selected) { + // @extend %grid-cell--column-selected !optional; + // } + // + // @include e(td, $mods: (selected, column-selected)) { + // @extend %grid-cell--cross-selected !optional; + // } + // + // @include e(td, $m: bool) { + // @extend %igx-grid__td--centered !optional; + // @extend %igx-grid__td--bool !optional; + // } + // + // @include e(td, $m: bool-true) { + // @extend %igx-grid__td--bool-true !optional; + // } + // + // @include e(td, $m: image) { + // @extend %igx-grid__td--centered !optional; + // } @include e(tr, $mods: (selected, filtered)) { @extend %grid-row--selected--filtered !optional; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 0166b635863..cd6f5979c4c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -1,3 +1,4 @@ +/* stylelint-disable max-nesting-depth */ @use 'sass:map'; @use 'sass:meta'; @use 'sass:color'; @@ -2084,7 +2085,7 @@ .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + ::after { background: var-get($theme, 'header-selected-background'); } @@ -2112,7 +2113,7 @@ &%igx-grid-th--sorted { .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2120,7 +2121,7 @@ &:focus, &:hover { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2177,14 +2178,14 @@ .sort-icon { opacity: 1; color: var-get($theme, 'sorted-header-icon-color'); - + > igx-icon { color: inherit; } &:hover { color: var-get($theme, 'sortable-header-icon-hover-color'); - + > igx-icon { color: inherit; } diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.scss b/projects/igniteui-angular/src/lib/grids/grid/grid.component.scss new file mode 100644 index 00000000000..2b68dd9a803 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.scss @@ -0,0 +1,4 @@ +@use '../themes/base'; +@use '../themes/shared'; +@use '../themes/light'; +@use '../themes/dark'; diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts index dbc7171abdd..94b7f4eb4fe 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts @@ -1,7 +1,8 @@ import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter, ContentChild, ViewChildren, QueryList, ViewChild, TemplateRef, DoCheck, AfterContentInit, HostBinding, - OnInit, AfterViewInit, ContentChildren, CUSTOM_ELEMENTS_SCHEMA, booleanAttribute + OnInit, AfterViewInit, ContentChildren, CUSTOM_ELEMENTS_SCHEMA, booleanAttribute, + ViewEncapsulation } from '@angular/core'; import { NgTemplateOutlet, NgClass, NgStyle } from '@angular/common'; @@ -115,6 +116,8 @@ export interface IGroupingDoneEventArgs extends IBaseEventArgs { ], selector: 'igx-grid', templateUrl: './grid.component.html', + styleUrls: ['./grid.component.scss'], + encapsulation: ViewEncapsulation.None, imports: [ NgClass, NgStyle, diff --git a/projects/igniteui-angular/src/lib/grids/themes/_base.scss b/projects/igniteui-angular/src/lib/grids/themes/_base.scss new file mode 100644 index 00000000000..6e38b33033d --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/_base.scss @@ -0,0 +1,40 @@ +@use 'igniteui-theming/sass/animations' as *; +@use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/themes' as *; +@use 'igniteui-theming/sass/typography' as *; +@use '../../../lib/core/styles/themes/standalone' as *; +@use 'light/tokens' as *; + +$theme: $material; + +@include layer(base) { + @include b(igx-grid) { + @include sizable(); + + --component-size: var(--ig-size, var(--ig-size-large)); + --grid-size: var(--component-size); + + @include e(td) { + border-inline-end: rem(1px) solid + var-get($theme, 'header-border-color'); + border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); + } + + @include e(td, $m: active) { + box-shadow: inset 0 0 0 rem(1px) + var-get($theme, 'cell-active-border-color'); + + // > %igx-grid__filtering-cell, + // > %grid-cell-header { + // border-inline-end-color: var-get( + // $theme, + // 'cell-active-border-color' + // ); + // border-bottom-color: var-get( + // $theme, + // 'cell-active-border-color' + // ); + // } + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss b/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss new file mode 100644 index 00000000000..af0e6b97398 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss @@ -0,0 +1,6 @@ +@use 'sass:meta'; +@use 'tokens'; +@use '../../../../lib/core/styles/themes/standalone' as *; + +$tokens: meta.module-variables(tokens); +@include themes(igx-grid, $tokens, dark); diff --git a/projects/igniteui-angular/src/lib/grids/themes/dark/_tokens.scss b/projects/igniteui-angular/src/lib/grids/themes/dark/_tokens.scss new file mode 100644 index 00000000000..d371999179e --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/dark/_tokens.scss @@ -0,0 +1,7 @@ +@use 'igniteui-theming/sass/themes' as *; +@use 'igniteui-theming/sass/themes/schemas/components/dark/grid' as *; + +$material: digest-schema($dark-material-grid); +$bootstrap: digest-schema($dark-bootstrap-grid); +$fluent: digest-schema($dark-fluent-grid); +$indigo: digest-schema($dark-indigo-grid); diff --git a/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss b/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss new file mode 100644 index 00000000000..91b9516b4de --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss @@ -0,0 +1,6 @@ +@use 'sass:meta'; +@use 'tokens'; +@use '../../../../lib/core/styles/themes/standalone' as *; + +$tokens: meta.module-variables(tokens); +@include themes(igx-grid, $tokens, light); diff --git a/projects/igniteui-angular/src/lib/grids/themes/light/_tokens.scss b/projects/igniteui-angular/src/lib/grids/themes/light/_tokens.scss new file mode 100644 index 00000000000..2fd4a5718e5 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/light/_tokens.scss @@ -0,0 +1,8 @@ +@use 'igniteui-theming/sass/themes' as *; +@use 'igniteui-theming/sass/themes/schemas/components/light/grid' as *; + +$base: digest-schema($light-grid); +$material: digest-schema($material-grid); +$bootstrap: digest-schema($bootstrap-grid); +$fluent: digest-schema($fluent-grid); +$indigo: digest-schema($indigo-grid); diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss new file mode 100644 index 00000000000..ca3dd3bc266 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss @@ -0,0 +1 @@ +@forward 'indigo'; diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/indigo.scss new file mode 100644 index 00000000000..ddcee75ae99 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/indigo.scss @@ -0,0 +1,5 @@ +@use 'igniteui-theming/sass/bem' as *; +@use '../../../../lib/core/styles/themes/standalone' as *; + +@include themed-block(igx-grid, indigo) { +} From 13d579ef0a6df43af6adfc6dc70ef17a2222e1a6 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 17 Jul 2025 18:00:30 +0300 Subject: [PATCH 2/8] refactor(grid): bundle more cell styles --- .../grid/_header-row-component.scss | 192 +++++++++--------- .../src/lib/grids/themes/_base.scss | 110 +++++++++- .../src/lib/grids/themes/dark/_index.scss | 1 + .../src/lib/grids/themes/dark/_indigo.scss | 16 ++ .../src/lib/grids/themes/light/_index.scss | 1 + .../src/lib/grids/themes/light/_indigo.scss | 16 ++ .../lib/grids/themes/shared/_bootstrap.scss | 11 + .../src/lib/grids/themes/shared/_fluent.scss | 11 + .../src/lib/grids/themes/shared/_index.scss | 3 + .../shared/{indigo.scss => _indigo.scss} | 0 .../lib/grids/themes/shared/_material.scss | 11 + src/styles/_variables.scss | 8 +- 12 files changed, 277 insertions(+), 103 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss create mode 100644 projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss rename projects/igniteui-angular/src/lib/grids/themes/shared/{indigo.scss => _indigo.scss} (100%) create mode 100644 projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss index a640f0ca808..1bf42efdc96 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss @@ -60,100 +60,100 @@ } } - @include b(igx-grid-th) { - @extend %grid-cell-display !optional; - @extend %grid-cell-header !optional; - - @include e(expander) { - @extend %igx-grid-th__expander !optional - } - - @include e(group-title) { - @extend %igx-grid-th__group-title !optional - } - - @include e(title) { - @extend %grid-cell-header-title !optional; - } - - @include e(icons) { - @extend %grid-cell-header-icons !optional; - } - - @include e(resize-handle) { - @extend %grid__resize-handle !optional; - } - - @include e(resize-line) { - @extend %grid__resize-line !optional; - } - - @include m(collapsible) { - @extend %igx-grid-th--collapsible !optional; - } - - @include m(sortable) { - @extend %igx-grid-th--sortable !optional; - } - - @include m(selectable) { - @extend %igx-grid-th--selectable !optional; - } - - @include m(filtrable) { - @extend %igx-grid-th--filtrable !optional; - } - - @include mx(filtrable, sortable) { - @extend %igx-grid-th--filtrable-sortable !optional; - } - - @include m(sorted) { - @extend %igx-grid-th--sorted !optional; - } - - @include m(selected) { - @extend %igx-grid-th--selected !optional; - } - - @include m(active) { - @extend %igx-grid-th--active !optional; - } - - @include m(number) { - @extend %grid-cell-number !optional; - } - - @include m(pinned) { - @extend %grid-cell--pinned !optional; - } - - @include m(pinned-last) { - @extend %grid-cell--pinned-last !optional; - } - - @include m(pinned-first) { - @extend %grid-cell--pinned-first !optional; - } - - @include m(fw) { - @extend %grid-cell--fixed-width !optional; - } - - @include m(filtering) { - @extend %grid-cell-header--filtering !optional; - } - - @include e(drop-indicator-left) { - @extend %igx-grid-th__drop-indicator-left !optional; - } - - @include e(drop-indicator-right) { - @extend %igx-grid-th__drop-indicator-right !optional; - } - - @include e(drop-indicator, $m: active) { - @extend %igx-grid-th__drop-indicator--active !optional; - } - } + // @include b(igx-grid-th) { + // @extend %grid-cell-display !optional; + // @extend %grid-cell-header !optional; + // + // @include e(expander) { + // @extend %igx-grid-th__expander !optional + // } + // + // @include e(group-title) { + // @extend %igx-grid-th__group-title !optional + // } + // + // @include e(title) { + // @extend %grid-cell-header-title !optional; + // } + // + // @include e(icons) { + // @extend %grid-cell-header-icons !optional; + // } + // + // @include e(resize-handle) { + // @extend %grid__resize-handle !optional; + // } + // + // @include e(resize-line) { + // @extend %grid__resize-line !optional; + // } + // + // @include m(collapsible) { + // @extend %igx-grid-th--collapsible !optional; + // } + // + // @include m(sortable) { + // @extend %igx-grid-th--sortable !optional; + // } + // + // @include m(selectable) { + // @extend %igx-grid-th--selectable !optional; + // } + // + // @include m(filtrable) { + // @extend %igx-grid-th--filtrable !optional; + // } + // + // @include mx(filtrable, sortable) { + // @extend %igx-grid-th--filtrable-sortable !optional; + // } + // + // @include m(sorted) { + // @extend %igx-grid-th--sorted !optional; + // } + // + // @include m(selected) { + // @extend %igx-grid-th--selected !optional; + // } + // + // @include m(active) { + // @extend %igx-grid-th--active !optional; + // } + // + // @include m(number) { + // @extend %grid-cell-number !optional; + // } + // + // @include m(pinned) { + // @extend %grid-cell--pinned !optional; + // } + // + // @include m(pinned-last) { + // @extend %grid-cell--pinned-last !optional; + // } + // + // @include m(pinned-first) { + // @extend %grid-cell--pinned-first !optional; + // } + // + // @include m(fw) { + // @extend %grid-cell--fixed-width !optional; + // } + // + // @include m(filtering) { + // @extend %grid-cell-header--filtering !optional; + // } + // + // @include e(drop-indicator-left) { + // @extend %igx-grid-th__drop-indicator-left !optional; + // } + // + // @include e(drop-indicator-right) { + // @extend %igx-grid-th__drop-indicator-right !optional; + // } + // + // @include e(drop-indicator, $m: active) { + // @extend %igx-grid-th__drop-indicator--active !optional; + // } + // } } diff --git a/projects/igniteui-angular/src/lib/grids/themes/_base.scss b/projects/igniteui-angular/src/lib/grids/themes/_base.scss index 6e38b33033d..b38ed3eb4ab 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/_base.scss @@ -1,3 +1,4 @@ +/* stylelint-disable max-nesting-depth */ @use 'igniteui-theming/sass/animations' as *; @use 'igniteui-theming/sass/bem' as *; @use 'igniteui-theming/sass/themes' as *; @@ -9,15 +10,53 @@ $theme: $material; @include layer(base) { @include b(igx-grid) { + %cell-base { + position: relative; + display: flex; + flex: 1 1 0%; + align-items: center; + outline-style: none; + color: inherit; + text-align: start; + background-clip: border-box !important; + + // The min-height should be different in the indigo theme -> 32px, 40px, 48px + min-height: sizable(rem(32px), rem(40px), rem(50px)); + + // Font size for the cell is different in the ingigo theme -> it simply uses the detail-1 styles for all cells + font-size: rem(13px); + line-height: rem(16px); + + padding-block: 0; + // The inline padding styles should be different in the indigo theme -> 8px, 12px, 16px + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + + // These should probably be added to the cell when it's a part of a multi-row layout header + border-inline-end: rem(1px) solid + var-get($theme, 'header-border-color'); + border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); + } + + %cell-header { + flex-flow: row nowrap; + justify-content: space-between; + align-items: flex-end; + min-width: 0; + min-height: var(--header-size); + border-inline-end: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + overflow: hidden; + transition: color 250ms ease-in-out; + } + @include sizable(); --component-size: var(--ig-size, var(--ig-size-large)); --grid-size: var(--component-size); @include e(td) { - border-inline-end: rem(1px) solid - var-get($theme, 'header-border-color'); - border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); + @extend %cell-base; } @include e(td, $m: active) { @@ -37,4 +76,69 @@ $theme: $material; // } } } + + @include b(igx-grid-th) { + @extend %cell-base; + @extend %cell-header; + + @include e(title) { + @include ellipsis(); + + // The font-weight depends on the theme, here's a list-style-type: + // material: 600, + // fluent: 800, + // bootstrap: 700, + // indigo: 600, + // Also, all other styles are from detail-2 (@include type-style('detail-2', false)) for the indigo theme + font-weight: 600; + min-width: 3ch; + user-select: none; + cursor: initial; + line-height: var(--header-size); + transition: color 250ms ease-in-out; + } + + @include e(icons) { + display: inline-flex; + align-items: center; + justify-content: flex-end; + user-select: none; + min-width: rem(30px); + height: var(--header-size); + align-self: flex-end; + + &:empty { + min-width: 0; + } + + .sort-icon { + position: relative; + display: flex; + + &::after { + content: attr(data-sortIndex); + position: absolute; + top: rem(-5px); + inset-inline-end: rem(-1px); + font-size: rem(10px); + text-align: end; + font-family: sans-serif; + line-height: rem(10px); + } + } + } + + @include m(sortable) { + @include e(icons) { + .sort-icon { + cursor: pointer; + opacity: 0.7; + + &:hover { + opacity: 1; + } + } + } + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss b/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss index af0e6b97398..fb156c5fa60 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/dark/_index.scss @@ -1,6 +1,7 @@ @use 'sass:meta'; @use 'tokens'; @use '../../../../lib/core/styles/themes/standalone' as *; +@use 'indigo'; $tokens: meta.module-variables(tokens); @include themes(igx-grid, $tokens, dark); diff --git a/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss new file mode 100644 index 00000000000..17d7c933e0a --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss @@ -0,0 +1,16 @@ +@use 'igniteui-theming/sass/bem' as *; +@use '../../../../lib/core/styles/themes/standalone' as *; + +@include themed-block(igx-grid-th, indigo, dark) { + @include m(sortable) { + @include e(icons) { + .sort-icon { + opacity: 0.85; + + &:hover { + opacity: 1; + } + } + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss b/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss index 91b9516b4de..1c985e7c1f8 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/light/_index.scss @@ -1,6 +1,7 @@ @use 'sass:meta'; @use 'tokens'; @use '../../../../lib/core/styles/themes/standalone' as *; +@use 'indigo'; $tokens: meta.module-variables(tokens); @include themes(igx-grid, $tokens, light); diff --git a/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss new file mode 100644 index 00000000000..d11b77b1a75 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss @@ -0,0 +1,16 @@ +@use 'igniteui-theming/sass/bem' as *; +@use '../../../../lib/core/styles/themes/standalone' as *; + +@include themed-block(igx-grid-th, indigo, light) { + @include m(sortable) { + @include e(icons) { + .sort-icon { + opacity: 0.75; + + &:hover { + opacity: 1; + } + } + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss new file mode 100644 index 00000000000..597f4573757 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss @@ -0,0 +1,11 @@ +@use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/typography/functions' as *; +@use '../../../../lib/core/styles/themes/standalone' as *; + +@include themed-block(igx-grid-th, bootstrap) { + @include e(icons) { + .sort-icon igx-icon { + --size: var(--igx-icon-size, #{rem(15px)}); + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss new file mode 100644 index 00000000000..14edc97e7e9 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss @@ -0,0 +1,11 @@ +@use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/typography/functions' as *; +@use '../../../../lib/core/styles/themes/standalone' as *; + +@include themed-block(igx-grid-th, fluent) { + @include e(icons) { + .sort-icon igx-icon { + --size: var(--igx-icon-size, #{rem(15px)}); + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss index ca3dd3bc266..0ca60c75786 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_index.scss @@ -1 +1,4 @@ +@forward 'material'; +@forward 'bootstrap'; +@forward 'fluent'; @forward 'indigo'; diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss similarity index 100% rename from projects/igniteui-angular/src/lib/grids/themes/shared/indigo.scss rename to projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss new file mode 100644 index 00000000000..9051f657847 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss @@ -0,0 +1,11 @@ +@use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/typography/functions' as *; +@use '../../../../lib/core/styles/themes/standalone' as *; + +@include themed-block(igx-grid-th, material) { + @include e(icons) { + .sort-icon igx-icon { + --size: var(--igx-icon-size, #{rem(15px)}); + } + } +} diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index 21d2f079812..fa429165538 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -1,10 +1,10 @@ @use 'sass:map'; @use '../../projects/igniteui-angular/src/lib/core/styles/themes' as *; -$palette: $light-bootstrap-palette; -$schema: $light-bootstrap-schema; -$typeface: $bootstrap-typeface; -$type-scale: $bootstrap-type-scale; +$palette: $light-material-palette; +$schema: $light-material-schema; +$typeface: $material-typeface; +$type-scale: $material-type-scale; $variant: map.get($schema, '_meta', 'variant'); $background-color: var(--ig-gray-900-contrast); From c442bdcb9feb6248a895577d7f5392c6212254a4 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Fri, 18 Jul 2025 09:50:18 +0300 Subject: [PATCH 3/8] refactor(grid): update header cell styles --- .../igniteui-angular/src/lib/grids/themes/_base.scss | 7 ------- .../src/lib/grids/themes/shared/_bootstrap.scss | 4 ++++ .../src/lib/grids/themes/shared/_fluent.scss | 4 ++++ .../src/lib/grids/themes/shared/_indigo.scss | 11 ++++++++++- .../src/lib/grids/themes/shared/_material.scss | 4 ++++ 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/themes/_base.scss b/projects/igniteui-angular/src/lib/grids/themes/_base.scss index b38ed3eb4ab..0cee9399b43 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/_base.scss @@ -84,13 +84,6 @@ $theme: $material; @include e(title) { @include ellipsis(); - // The font-weight depends on the theme, here's a list-style-type: - // material: 600, - // fluent: 800, - // bootstrap: 700, - // indigo: 600, - // Also, all other styles are from detail-2 (@include type-style('detail-2', false)) for the indigo theme - font-weight: 600; min-width: 3ch; user-select: none; cursor: initial; diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss index 597f4573757..325c6499425 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_bootstrap.scss @@ -3,6 +3,10 @@ @use '../../../../lib/core/styles/themes/standalone' as *; @include themed-block(igx-grid-th, bootstrap) { + @include e(title) { + font-weight: 700; + } + @include e(icons) { .sort-icon igx-icon { --size: var(--igx-icon-size, #{rem(15px)}); diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss index 14edc97e7e9..0920b293fa4 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_fluent.scss @@ -3,6 +3,10 @@ @use '../../../../lib/core/styles/themes/standalone' as *; @include themed-block(igx-grid-th, fluent) { + @include e(title) { + font-weight: 800; + } + @include e(icons) { .sort-icon igx-icon { --size: var(--igx-icon-size, #{rem(15px)}); diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss index ddcee75ae99..5c615dee95d 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss @@ -1,5 +1,14 @@ @use 'igniteui-theming/sass/bem' as *; @use '../../../../lib/core/styles/themes/standalone' as *; -@include themed-block(igx-grid, indigo) { +@include themed-block(igx-grid-th, indigo) { + @include e(title) { + font-weight: 600; + } + + @include e(icons) { + .sort-icon igx-icon { + --component-size: 2; + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss index 9051f657847..1bc7087efaf 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_material.scss @@ -3,6 +3,10 @@ @use '../../../../lib/core/styles/themes/standalone' as *; @include themed-block(igx-grid-th, material) { + @include e(title) { + font-weight: 600; + } + @include e(icons) { .sort-icon igx-icon { --size: var(--igx-icon-size, #{rem(15px)}); From 4930435d9c16bf4bcb4e6c231d35d252e3dcfa29 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 9 Oct 2025 09:54:53 +0300 Subject: [PATCH 4/8] refactor(themes): add updated grid theme scoped styles --- .../components/grid/_grid-component.scss | 6 +- .../styles/components/grid/_grid-theme.scss | 14 +- .../src/lib/grids/themes/_base.scss | 120 ++++++++++++------ .../src/lib/input-group/themes/_base.scss | 7 +- 4 files changed, 96 insertions(+), 51 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index 91cd1b1422a..4b58a73d266 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -320,9 +320,9 @@ @extend %igx-grid__td--merged-hovered !optional; } - @include e(td, $m: editing) { - @extend %igx-grid__td--editing !optional; - } + // @include e(td, $m: editing) { + // @extend %igx-grid__td--editing !optional; + // } @include e(td, $mods: (editing, valid)) { @extend %igx-grid__td--editing--valid !optional; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 021e58171ca..6dc310be16f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -1251,9 +1251,9 @@ flex-grow: 0; outline-style: none; - igx-icon { - --component-size: #{if($variant == 'indigo', 2, 3)}; - } + // igx-icon { + // --component-size: #{if($variant == 'indigo', 2, 3)}; + // } } %grid-cell--active { @@ -1402,9 +1402,9 @@ } %igx-grid__td--editing { - background: var-get($theme, 'cell-editing-background') !important; - box-shadow: inset 0 0 0 $editing-outline-width var-get($theme, 'edit-mode-color'); - padding-inline: rem(4px); + // background: var-get($theme, 'cell-editing-background') !important; + // box-shadow: inset 0 0 0 $editing-outline-width var-get($theme, 'edit-mode-color'); + // padding-inline: rem(4px); &.igx-grid__td--invalid { box-shadow: inset 0 0 0 rem(2px) color($color: 'error') !important; @@ -1414,7 +1414,7 @@ justify-content: flex-start !important; } - @extend %cell-input-overrides; + // @extend %cell-input-overrides; } %grid-cell--pinned { diff --git a/projects/igniteui-angular/src/lib/grids/themes/_base.scss b/projects/igniteui-angular/src/lib/grids/themes/_base.scss index 0cee9399b43..1ae6c17ff3e 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/_base.scss @@ -7,53 +7,55 @@ @use 'light/tokens' as *; $theme: $material; +$cell-font-size: rem(13px); +$cell-line-height: rem(16px); +$cell-editing-outline-width: rem(2px); @include layer(base) { - @include b(igx-grid) { - %cell-base { - position: relative; - display: flex; - flex: 1 1 0%; - align-items: center; - outline-style: none; - color: inherit; - text-align: start; - background-clip: border-box !important; - - // The min-height should be different in the indigo theme -> 32px, 40px, 48px - min-height: sizable(rem(32px), rem(40px), rem(50px)); - - // Font size for the cell is different in the ingigo theme -> it simply uses the detail-1 styles for all cells - font-size: rem(13px); - line-height: rem(16px); - - padding-block: 0; - // The inline padding styles should be different in the indigo theme -> 8px, 12px, 16px - padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); - - // These should probably be added to the cell when it's a part of a multi-row layout header - border-inline-end: rem(1px) solid - var-get($theme, 'header-border-color'); - border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); - } + %cell-base { + position: relative; + display: flex; + flex: 1 1 0%; + align-items: center; + outline-style: none; + color: inherit; + text-align: start; + background-clip: border-box !important; + min-height: var(--cell-height); + + // Font size for the cell is different in the ingigo theme -> it simply uses the detail-1 styles for all cells + font-size: $cell-font-size; + line-height: $cell-line-height; + + padding-block: 0; + // The inline padding styles should be different in the indigo theme -> 8px, 12px, 16px + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + + // These should probably be added to the cell when it's a part of a multi-row layout header + border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); + border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); + } - %cell-header { - flex-flow: row nowrap; - justify-content: space-between; - align-items: flex-end; - min-width: 0; - min-height: var(--header-size); - border-inline-end: var-get($theme, 'header-border-width') - var-get($theme, 'header-border-style') - var-get($theme, 'header-border-color'); - overflow: hidden; - transition: color 250ms ease-in-out; - } + %cell-header { + flex-flow: row nowrap; + justify-content: space-between; + align-items: flex-end; + min-width: 0; + min-height: var(--header-size); + border-inline-end: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + overflow: hidden; + transition: color 250ms ease-in-out; + } + @include b(igx-grid) { @include sizable(); --component-size: var(--ig-size, var(--ig-size-large)); --grid-size: var(--component-size); + // The cell size should be different in the indigo theme -> 32px, 40px, 48px + --cell-height: #{sizable(rem(32px), rem(40px), rem(50px))}; @include e(td) { @extend %cell-base; @@ -75,6 +77,46 @@ $theme: $material; // ); // } } + + @include e(td, $m: editing) { + border-width: 0; + background: var-get($theme, 'cell-editing-background') !important; + box-shadow: inset 0 0 0 #{$cell-editing-outline-width} var-get($theme, 'edit-mode-color'); + padding-inline: rem(4px); + + igx-input-group { + --size: var(--cell-height) !important; + + width: 100%; + overflow: hidden; + + // I don't like this, customize via CSS variables instead? + .igx-input-group__bundle { + background: transparent !important; + border: none !important; + box-shadow: none !important; + + &::before { + content: none !important; + } + + &::after { + display: none; + } + } + + input { + --input-font-size: #{$cell-font-size}; + --input-line-height: #{$cell-line-height}; + + font-size: var(--input-font-size) !important; + line-height: var(--input-line-height) !important; + box-shadow: none !important; + border: none !important; + } + } + } + } @include b(igx-grid-th) { diff --git a/projects/igniteui-angular/src/lib/input-group/themes/_base.scss b/projects/igniteui-angular/src/lib/input-group/themes/_base.scss index da57de78078..2446b6bdd77 100644 --- a/projects/igniteui-angular/src/lib/input-group/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/input-group/themes/_base.scss @@ -34,6 +34,7 @@ $base-scale-size: ( @include b(igx-input-group) { @include sizable(); --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); + --input-size: var(--component-size); --_bundle-template-columns: auto 1fr auto; --_bundle-template-rows: auto #{var-get($theme, 'size')}; --_prefix-suffix-spacing: #{pad-inline(rem(8px), rem(12px), rem(16px))}; @@ -58,8 +59,10 @@ $base-scale-size: ( igx-icon, igx-icon[igxPrefix], - igx-icon[igxSuffix] { - --component-size: var(--ig-size, #{var-get($theme, 'default-size')}); + igx-icon[igxSuffix], + igx-prefix igx-icon, + igx-suffix igx-icon { + --component-size: var(--input-size); } igx-suffix:not(igx-icon), From 9126855da792654c8a89c2f597758522a4362850 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Wed, 12 Nov 2025 12:21:09 +0200 Subject: [PATCH 5/8] refactor(grid): bundle more grid styles (copilot assisted) --- .../components/grid/_grid-component.scss | 638 ++++++----- .../grid/_header-row-component.scss | 114 +- .../src/lib/grids/grid/grid.component.ts | 2 +- .../src/lib/grids/themes/_base.scss | 1000 ++++++++++++++++- .../src/lib/grids/themes/dark/_indigo.scss | 32 + .../src/lib/grids/themes/light/_indigo.scss | 32 + .../src/lib/grids/themes/shared/_indigo.scss | 63 ++ 7 files changed, 1497 insertions(+), 384 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index 4b58a73d266..86a396241e8 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -34,89 +34,89 @@ @extend %grid-caption !optional; } - @include e(tbody) { - @extend %grid-tbody-container !optional; - } - - @include e(tbody-content) { - @extend %grid-tbody !optional; - - &:focus { - @extend %disable-focus-styles !optional; - } - } - - @include e(tbody-message) { - @extend %grid-tbody-message !optional; - } + // @include e(tbody) { + // @extend %grid-tbody-container !optional; + // } - @include e(loading) { - @extend %igx-grid__loading !optional; - } + // @include e(tbody-content) { + // @extend %grid-tbody !optional; + // + // &:focus { + // @extend %disable-focus-styles !optional; + // } + // } - @include e(tbody-scrollbar) { - @extend %grid-tbody-scrollbar !optional; - } + // @include e(tbody-message) { + // @extend %grid-tbody-message !optional; + // } - @include e(tbody-scrollbar-main) { - @extend %grid-tbody-scrollbar-main !optional; - } + // @include e(loading) { + // @extend %igx-grid__loading !optional; + // } - @include e(tbody-scrollbar-start) { - @extend %grid-tbody-scrollbar-start !optional; - } + // @include e(tbody-scrollbar) { + // @extend %grid-tbody-scrollbar !optional; + // } - @include e(tbody-scrollbar-end) { - @extend %grid-tbody-scrollbar-end !optional; - } + // @include e(tbody-scrollbar-main) { + // @extend %grid-tbody-scrollbar-main !optional; + // } - @include e(scroll) { - @extend %grid-scroll !optional; - } + // @include e(tbody-scrollbar-start) { + // @extend %grid-tbody-scrollbar-start !optional; + // } - @include e(scroll-start) { - @extend %grid-scroll-start !optional; - } + // @include e(tbody-scrollbar-end) { + // @extend %grid-tbody-scrollbar-end !optional; + // } - @include e(scroll-main) { - @extend %grid-scroll-main !optional; - } + // @include e(scroll) { + // @extend %grid-scroll !optional; + // } - @include e(tfoot) { - @extend %grid-tfoot !optional; + // @include e(scroll-start) { + // @extend %grid-scroll-start !optional; + // } - &:focus { - @extend %disable-focus-styles !optional; - } - } + // @include e(scroll-main) { + // @extend %grid-scroll-main !optional; + // } - @include e(tfoot-thumb) { - @extend %grid-tfoot-thumb !optional; - } + // @include e(tfoot) { + // @extend %grid-tfoot !optional; + // + // &:focus { + // @extend %disable-focus-styles !optional; + // } + // } - @include e(footer) { - @extend %grid-footer !optional; - } + // @include e(tfoot-thumb) { + // @extend %grid-tfoot-thumb !optional; + // } - @include e(tr) { - @extend %grid-row !optional; + // @include e(footer) { + // @extend %grid-footer !optional; + // } - igx-display-container { - @extend %grid-display-container-tr !optional; - } - } + // @include e(tr) { + // @extend %grid-row !optional; + // + // igx-display-container { + // @extend %grid-display-container-tr !optional; + // } + // } - @include e(tr-action) { - @extend %igx-grid__tr-action !optional - } + // @include e(tr-action) { + // @extend %igx-grid__tr-action !optional + // } - @include e(tr, $m: 'drag') { - @extend %igx-grid__tr--drag !optional; - } + // @include e(tr, $m: 'drag') { + // @extend %igx-grid__tr--drag !optional; + // } - @include e(tr, $m: 'ghost') { - @extend %igx-grid__tr--ghost !optional; - } + // @include e(tr, $m: 'ghost') { + // @extend %igx-grid__tr--ghost !optional; + // } @include e(drag-indicator) { @extend %igx-grid__drag-indicator !optional; @@ -130,13 +130,13 @@ @extend %igx-grid__drag-indicator--off !optional; } - @include e(tr, $m: 'mrl') { - @extend %grid-row--mrl !optional; - } + // @include e(tr, $m: 'mrl') { + // @extend %grid-row--mrl !optional; + // } - @include e(tr, $mods: ('mrl', 'edit')) { - @extend %grid-row--edit-mrl !optional; - } + // @include e(tr, $mods: ('mrl', 'edit')) { + // @extend %grid-row--edit-mrl !optional; + // } @include e(summaries) { @extend %grid-summaries !optional; @@ -159,61 +159,61 @@ @extend %grid-summaries-patch !optional; } - @include e(tr, $m: odd) { - @extend %grid-row--odd !optional; - } + // @include e(tr, $m: odd) { + // @extend %grid-row--odd !optional; + // } - @include e(tr, $m: even) { - @extend %grid-row--even !optional; - } + // @include e(tr, $m: even) { + // @extend %grid-row--even !optional; + // } - @include e(tr, $m: selected) { - @extend %grid-row--selected !optional; - } + // @include e(tr, $m: selected) { + // @extend %grid-row--selected !optional; + // } - @include e(tr, $m: edited) { - @extend %igx-grid__tr--edited !optional; - } + // @include e(tr, $m: edited) { + // @extend %igx-grid__tr--edited !optional; + // } - @include e(tr, $m: deleted) { - @extend %igx-grid__tr--deleted !optional; - } + // @include e(tr, $m: deleted) { + // @extend %igx-grid__tr--deleted !optional; + // } - @include e(tr, $m: highlighted) { - @extend %igx-grid__tr--highlighted !optional; - } + // @include e(tr, $m: highlighted) { + // @extend %igx-grid__tr--highlighted !optional; + // } - @include e(tr, $m: edit) { - @extend %igx-grid__tr--edit !optional; - } + // @include e(tr, $m: edit) { + // @extend %igx-grid__tr--edit !optional; + // } - @include e(tr, $m: add-animate) { - @extend %igx-grid__tr--add-animate !optional; - } + // @include e(tr, $m: add-animate) { + // @extend %igx-grid__tr--add-animate !optional; + // } - @include e(tr, $m: inner) { - @extend %igx-grid__tr--inner !optional; - } + // @include e(tr, $m: inner) { + // @extend %igx-grid__tr--inner !optional; + // } - @include e(tr, $m: header) { - @extend %igx-grid__tr--header !optional; - } + // @include e(tr, $m: header) { + // @extend %igx-grid__tr--header !optional; + // } - @include e(tr, $m: group) { - @extend %grid-row--group !optional; - } + // @include e(tr, $m: group) { + // @extend %grid-row--group !optional; + // } - @include e(tr, $m: mrl) { - @extend %grid-row--mrl !optional; - } + // @include e(tr, $m: mrl) { + // @extend %grid-row--mrl !optional; + // } - @include e(tr-container) { - @extend %igx-grid__tr-container !optional; - } + // @include e(tr-container) { + // @extend %igx-grid__tr-container !optional; + // } - @include e(tr-container, $m: active) { - @extend %igx-grid__tr-container--active !optional; - } + // @include e(tr-container, $m: active) { + // @extend %igx-grid__tr-container--active !optional; + // } // @include e(td) { // @extend %grid-cell-display !optional; @@ -256,159 +256,159 @@ // @extend %igx-grid__td--centered !optional; // } - @include e(tr, $mods: (selected, filtered)) { - @extend %grid-row--selected--filtered !optional; - } + // @include e(tr, $mods: (selected, filtered)) { + // @extend %grid-row--selected--filtered !optional; + // } - @include e(tr, $m: filtered) { - @extend %igx-grid-row--filtered !optional; - } + // @include e(tr, $m: filtered) { + // @extend %igx-grid-row--filtered !optional; + // } - @include e(tr, $m: expanded) { - @extend %igx-grid__tr--expanded !optional; - } + // @include e(tr, $m: expanded) { + // @extend %igx-grid__tr--expanded !optional; + // } - @include e(tr, $m: pinned) { - @extend %igx-grid__tr--pinned !optional; - } + // @include e(tr, $m: pinned) { + // @extend %igx-grid__tr--pinned !optional; + // } - @include e(tr, $m: merged) { - @extend %igx-grid__tr--merged !optional; - } + // @include e(tr, $m: merged) { + // @extend %igx-grid__tr--merged !optional; + // } - @include e(tr, $m: merged-top) { - @extend %igx-grid__tr--merged-top !optional; - } + // @include e(tr, $m: merged-top) { + // @extend %igx-grid__tr--merged-top !optional; + // } - @include e(tr, $m: pinned-top) { - @extend %igx-grid__tr--pinned-top !optional; - } + // @include e(tr, $m: pinned-top) { + // @extend %igx-grid__tr--pinned-top !optional; + // } - @include e(tr, $m: pinned-bottom) { - @extend %igx-grid__tr--pinned-bottom !optional; - } + // @include e(tr, $m: pinned-bottom) { + // @extend %igx-grid__tr--pinned-bottom !optional; + // } - @include e(tree-grouping-indicator) { - @extend %igx-grid__tree-grouping-indicator !optional; - } + // @include e(tree-grouping-indicator) { + // @extend %igx-grid__tree-grouping-indicator !optional; + // } - @include e(tree-loading-indicator) { - @extend %igx-grid__tree-loading-indicator !optional; - } + // @include e(tree-loading-indicator) { + // @extend %igx-grid__tree-loading-indicator !optional; + // } - @include e(td, $m: new) { - @extend %igx-grid__td--new !optional; - } + // @include e(td, $m: new) { + // @extend %igx-grid__td--new !optional; + // } - @include e(td, $m: edited) { - @extend %igx-grid__td--edited !optional; - } + // @include e(td, $m: edited) { + // @extend %igx-grid__td--edited !optional; + // } - @include e(td, $m: merged) { - @extend %igx-grid__td--merged !optional; - } + // @include e(td, $m: merged) { + // @extend %igx-grid__td--merged !optional; + // } - @include e(td, $mods: (merged-selected, merged-hovered)) { - @extend %igx-grid__td--merged-selected-hovered !optional; - } + // @include e(td, $mods: (merged-selected, merged-hovered)) { + // @extend %igx-grid__td--merged-selected-hovered !optional; + // } - @include e(td, $m: merged-selected) { - @extend %igx-grid__td--merged-selected !optional; - } + // @include e(td, $m: merged-selected) { + // @extend %igx-grid__td--merged-selected !optional; + // } - @include e(td, $m: merged-hovered) { - @extend %igx-grid__td--merged-hovered !optional; - } + // @include e(td, $m: merged-hovered) { + // @extend %igx-grid__td--merged-hovered !optional; + // } // @include e(td, $m: editing) { // @extend %igx-grid__td--editing !optional; // } - @include e(td, $mods: (editing, valid)) { - @extend %igx-grid__td--editing--valid !optional; - } + // @include e(td, $mods: (editing, valid)) { + // @extend %igx-grid__td--editing--valid !optional; + // } - @include e(td, $mods: (editing, invalid)) { - @extend %igx-grid__td--editing--invalid !optional; - } + // @include e(td, $mods: (editing, invalid)) { + // @extend %igx-grid__td--editing--invalid !optional; + // } - @include e(tr, $m: disabled) { - @extend %igx-grid__tr--disabled !optional; - } + // @include e(tr, $m: disabled) { + // @extend %igx-grid__tr--disabled !optional; + // } - @include e(td, $m: number) { - @extend %grid-cell-number !optional; - } + // @include e(td, $m: number) { + // @extend %grid-cell-number !optional; + // } - @include e(td, $m: pinned) { - @extend %grid-cell--pinned !optional; - } + // @include e(td, $m: pinned) { + // @extend %grid-cell--pinned !optional; + // } - @include e(td, $m: pinned-last) { - @extend %grid-cell--pinned !optional; - @extend %grid-cell--pinned-last !optional; - } + // @include e(td, $m: pinned-last) { + // @extend %grid-cell--pinned !optional; + // @extend %grid-cell--pinned-last !optional; + // } - @include e(td, $m: pinned-first) { - @extend %grid-cell--pinned !optional; - @extend %grid-cell--pinned-first !optional; - } + // @include e(td, $m: pinned-first) { + // @extend %grid-cell--pinned !optional; + // @extend %grid-cell--pinned-first !optional; + // } - @include e(td, $m: fw) { - @extend %grid-cell--fixed-width !optional; - } + // @include e(td, $m: fw) { + // @extend %grid-cell--fixed-width !optional; + // } - @include e(td, $mods: (pinned, selected)) { - @extend %grid-cell--pinned-selected !optional; - } + // @include e(td, $mods: (pinned, selected)) { + // @extend %grid-cell--pinned-selected !optional; + // } - @include e(td, $mods: (pinned, column-selected)) { - @extend %grid-cell--pinned--column-selected !optional; - } + // @include e(td, $mods: (pinned, column-selected)) { + // @extend %grid-cell--pinned--column-selected !optional; + // } - @include e(td, $m: row-pinned-first) { - @extend %grid-cell--row-pinned-first !optional; - } + // @include e(td, $m: row-pinned-first) { + // @extend %grid-cell--row-pinned-first !optional; + // } - @include e(td, $m: pinned-chip) { - @extend %grid-cell--pinned-chip !optional; - } + // @include e(td, $m: pinned-chip) { + // @extend %grid-cell--pinned-chip !optional; + // } - @include e(td-text) { - @extend %grid-cell-text !optional; - } + // @include e(td-text) { + // @extend %grid-cell-text !optional; + // } - @include e(cbx-padding) { - @extend %cbx-padding !optional; - } + // @include e(cbx-padding) { + // @extend %cbx-padding !optional; + // } - @include e(cbx-selection) { - @extend %grid__cbx-selection !optional; - } + // @include e(cbx-selection) { + // @extend %grid__cbx-selection !optional; + // } - @include e(cbx-selection, $m: push) { - @extend %grid__cbx-selection--push !optional; - } + // @include e(cbx-selection, $m: push) { + // @extend %grid__cbx-selection--push !optional; + // } - @include e(group-row) { - @extend %igx-grid__group-row !optional; - } + // @include e(group-row) { + // @extend %igx-grid__group-row !optional; + // } - @include e(group-row, $m: active) { - @extend %igx-grid__group-row--active !optional; - } + // @include e(group-row, $m: active) { + // @extend %igx-grid__group-row--active !optional; + // } - @include e(group-content) { - @extend %igx-grid__group-content !optional; - } + // @include e(group-content) { + // @extend %igx-grid__group-content !optional; + // } - @include e(row-indentation) { - @extend %igx-grid__row-indentation !optional; - } + // @include e(row-indentation) { + // @extend %igx-grid__row-indentation !optional; + // } - @include e(grouping-indicator) { - @extend %igx-grid__grouping-indicator !optional; - } + // @include e(grouping-indicator) { + // @extend %igx-grid__grouping-indicator !optional; + // } @include e(scroll-on-drag-left) { @extend %grid__scroll-on-drag-left !optional; @@ -438,21 +438,21 @@ @extend %igx-grid__drag-col-header !optional; } - @include e(header-indentation) { - @extend %igx-grid__header-indentation !optional; - } + // @include e(header-indentation) { + // @extend %igx-grid__header-indentation !optional; + // } - @include e(header-indentation, $m: 'no-border') { - @extend %igx-grid__header-indentation--no-border !optional; - } + // @include e(header-indentation, $m: 'no-border') { + // @extend %igx-grid__header-indentation--no-border !optional; + // } - @include e(group-expand-btn) { - @extend %igx-grid__group-expand-btn !optional; - } + // @include e(group-expand-btn) { + // @extend %igx-grid__group-expand-btn !optional; + // } - @include e(group-expand-btn, $m: 'push') { - @extend %igx-grid__group-expand-btn--push !optional; - } + // @include e(group-expand-btn, $m: 'push') { + // @extend %igx-grid__group-expand-btn--push !optional; + // } @include e(outlet) { @extend %igx-grid__outlet !optional; @@ -462,9 +462,9 @@ @extend %igx-grid__loading-outlet !optional; } - @include e(row-editing-outlet) { - @extend %igx-grid__row-editing-outlet !optional; - } + // @include e(row-editing-outlet) { + // @extend %igx-grid__row-editing-outlet !optional; + // } @include e(addrow-snackbar) { @extend %igx-grid__addrow-snackbar !optional; @@ -520,107 +520,105 @@ @extend %igx-grid__filtering-scroll-end !optional; } - @include e(hierarchical-indent) { - @extend %igx-grid__hierarchical-indent !optional; - } - - @include e(hierarchical-expander) { - @extend %igx-grid__hierarchical-expander !optional; - } + // @include e(hierarchical-indent) { + // @extend %igx-grid__hierarchical-indent !optional; + // } - @include e(hierarchical-expander, $m: empty) { - @extend %igx-grid__hierarchical-expander !optional; - @extend %igx-grid__hierarchical-expander--empty !optional; - } + // @include e(hierarchical-expander) { + // @extend %igx-grid__hierarchical-expander !optional; + // } - @include e(hierarchical-expander, $m: header) { - @extend %igx-grid__hierarchical-expander--header !optional; - } + // @include e(hierarchical-expander, $m: empty) { + // @extend %igx-grid__hierarchical-expander !optional; + // @extend %igx-grid__hierarchical-expander--empty !optional; + // } - @include e(hierarchical-expander, $m: push) { - @extend %igx-grid__hierarchical-expander--push !optional; - } + // @include e(hierarchical-expander, $m: header) { + // @extend %igx-grid__hierarchical-expander--header !optional; + // } - @include e(hierarchical-indent, $m: scroll) { - @extend %igx-grid__hierarchical-indent--scroll !optional; - } + // @include e(hierarchical-expander, $m: push) { + // @extend %igx-grid__hierarchical-expander--push !optional; + // } - @include e(mrl-block) { - @extend %grid-mrl-block !optional; - } + // @include e(hierarchical-indent, $m: scroll) { + // @extend %igx-grid__hierarchical-indent--scroll !optional; + // } - @for $i from 1 through 10 { - @include e(row-indentation, $m: level-#{$i}) { - @extend %igx-grid__row-indentation--level-#{$i} !optional; - } + // @include e(mrl-block) { + // @extend %grid-mrl-block !optional; + // } - @include e(group-row, $m: padding-level-#{$i}) { - @extend %igx-grid__group-row--padding-level-#{$i} !optional; - } - } + // @for $i from 1 through 10 { + // @include e(row-indentation, $m: level-#{$i}) { + // @extend %igx-grid__row-indentation--level-#{$i} !optional; + // } + // + // @include e(group-row, $m: padding-level-#{$i}) { + // @extend %igx-grid__group-row--padding-level-#{$i} !optional; + // } + // } // Pivot start - @include e(pivot, $m: 'super-compact') { - @extend %igx-grid__pivot--super-compact !optional - } - - @include e(tr-pivot) { - @extend %igx-grid__tr-pivot !optional - } - - @include e(pivot-filter-toggle) { - @extend %igx-grid__pivot-filter-toggle !optional - } + // @include e(pivot, $m: 'super-compact') { + // @extend %igx-grid__pivot--super-compact !optional + // } - @include e(pivot-empty-chip-area) { - @extend %igx-grid__pivot-empty-chip-area !optional - } + // @include e(tr-pivot) { + // @extend %igx-grid__tr-pivot !optional + // } + // @include e(pivot-filter-toggle) { + // @extend %igx-grid__pivot-filter-toggle !optional + // } + // @include e(pivot-empty-chip-area) { + // @extend %igx-grid__pivot-empty-chip-area !optional + // } - @include e(tr-pivot, $m: 'row-area') { - @extend %igx-grid__tr-pivot--row-area !optional - } + // @include e(tr-pivot, $m: 'row-area') { + // @extend %igx-grid__tr-pivot--row-area !optional + // } - @include e(tr-pivot, $m: 'filter-container') { - @extend %igx-grid__tr-pivot--filter-container !optional - } + // @include e(tr-pivot, $m: 'filter-container') { + // @extend %igx-grid__tr-pivot--filter-container !optional + // } - @include e(tr-pivot, $m: 'chip_drop_indicator') { - @extend %igx-grid__tr-pivot--chip_drop_indicator !optional - } + // @include e(tr-pivot, $m: 'chip_drop_indicator') { + // @extend %igx-grid__tr-pivot--chip_drop_indicator !optional + // } - @include e(tr-pivot, $m: 'drop-row-area') { - @extend %igx-grid__tr-pivot--drop-row-area !optional - } + // @include e(tr-pivot, $m: 'drop-row-area') { + // @extend %igx-grid__tr-pivot--drop-row-area !optional + // } - @include e(tr-pivot, $m: 'filter') { - @extend %igx-grid__tr-pivot--filter !optional - } + // @include e(tr-pivot, $m: 'filter') { + // @extend %igx-grid__tr-pivot--filter !optional + // } - @include e(tr-pivot-group) { - @extend %igx-grid__tr-pivot-group !optional - } + // @include e(tr-pivot-group) { + // @extend %igx-grid__tr-pivot-group !optional + // } - @include e(tr-header-row) { - @extend %igx-grid__tr-header-row !optional; - } + // @include e(tr-header-row) { + // @extend %igx-grid__tr-header-row !optional; + // } - @include e(tr-pivot, $m: 'columnDimensionLeaf') { - @extend %igx-grid__tr-pivot--columnDimensionLeaf !optional - } + // @include e(tr-pivot, $m: 'columnDimensionLeaf') { + // @extend %igx-grid__tr-pivot--columnDimensionLeaf !optional + // } - @include e(tr-pivot, $m: 'columnMultiRowSpan') { - @extend %igx-grid__tr-pivot--columnMultiRowSpan !optional - } + // @include e(tr-pivot, $m: 'columnMultiRowSpan') { + // @extend %igx-grid__tr-pivot--columnMultiRowSpan !optional + // } - @include e(tbody-pivot-mrl-dimension) { - @extend %igx-grid__tbody-pivot-mrl-dimension !optional - } + // @include e(tbody-pivot-mrl-dimension) { + // @extend %igx-grid__tbody-pivot-mrl-dimension !optional + // } - @include e(tr-pivot-toggle-icons) { - @extend %igx-grid__tr-pivot-toggle-icons !optional; - } + // @include e(tr-pivot-toggle-icons) { + // @extend %igx-grid__tr-pivot-toggle-icons !optional; + // } // pivot end @include excel-filtering-partial(); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss index 1bf42efdc96..e05512a0a1e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_header-row-component.scss @@ -2,63 +2,63 @@ /// @access private @mixin header-row { - @include b(igx-grid-thead) { - @extend %grid-thead-container !optional; - - @include e(wrapper) { - @extend %grid-thead !optional; - - igx-display-container { - @extend %grid-display-container-thead !optional; - } - - &:focus { - @extend %disable-focus-styles !optional; - } - } - - @include e(wrapper, $m: 'pivot') { - @extend %igx-grid-thead__wrapper--pivot !optional; - } - - @include e(title) { - @extend %grid-cell-display !optional; - @extend %grid-cell-header !optional; - @extend %grid-thead-title !optional; - } - - @include e(title, $m: pinned-last) { - @extend %grid-thead-title--pinned !optional; - } - - @include e(group) { - @extend %grid-thead-group !optional; - } - - @include e(subgroup) { - @extend %grid-thead-subgroup !optional; - } - - @include e(item) { - @extend %grid-thead-item !optional; - } - - @include e(thumb) { - @extend %grid-thead-thumb !optional; - } - - @include m(pivot) { - @extend %grid-thead--pivot !optional; - } - - @include m(virtualizationWrapper) { - @extend %grid-thead--virtualizationWrapper !optional; - } - - @include m(virtualizationContainer) { - @extend %grid-thead--virtualizationContainer !optional; - } - } + // @include b(igx-grid-thead) { + // @extend %grid-thead-container !optional; + // + // @include e(wrapper) { + // @extend %grid-thead !optional; + // + // igx-display-container { + // @extend %grid-display-container-thead !optional; + // } + // + // &:focus { + // @extend %disable-focus-styles !optional; + // } + // } + // + // @include e(wrapper, $m: 'pivot') { + // @extend %igx-grid-thead__wrapper--pivot !optional; + // } + // + // @include e(title) { + // @extend %grid-cell-display !optional; + // @extend %grid-cell-header !optional; + // @extend %grid-thead-title !optional; + // } + // + // @include e(title, $m: pinned-last) { + // @extend %grid-thead-title--pinned !optional; + // } + // + // @include e(group) { + // @extend %grid-thead-group !optional; + // } + // + // @include e(subgroup) { + // @extend %grid-thead-subgroup !optional; + // } + // + // @include e(item) { + // @extend %grid-thead-item !optional; + // } + // + // @include e(thumb) { + // @extend %grid-thead-thumb !optional; + // } + // + // @include m(pivot) { + // @extend %grid-thead--pivot !optional; + // } + // + // @include m(virtualizationWrapper) { + // @extend %grid-thead--virtualizationWrapper !optional; + // } + // + // @include m(virtualizationContainer) { + // @extend %grid-thead--virtualizationContainer !optional; + // } + // } // @include b(igx-grid-th) { // @extend %grid-cell-display !optional; diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts index 4f6b8fdaf5f..6040a1cce99 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts @@ -117,7 +117,7 @@ export interface IGroupingDoneEventArgs extends IBaseEventArgs { ], selector: 'igx-grid', templateUrl: './grid.component.html', - styleUrls: ['./grid.component.scss'], + styleUrls: ['./grid.component.css'], encapsulation: ViewEncapsulation.None, imports: [ NgClass, diff --git a/projects/igniteui-angular/src/lib/grids/themes/_base.scss b/projects/igniteui-angular/src/lib/grids/themes/_base.scss index 1ae6c17ff3e..446b7e39ee5 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/_base.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/_base.scss @@ -1,10 +1,10 @@ /* stylelint-disable max-nesting-depth */ -@use 'igniteui-theming/sass/animations' as *; @use 'igniteui-theming/sass/bem' as *; @use 'igniteui-theming/sass/themes' as *; @use 'igniteui-theming/sass/typography' as *; -@use '../../../lib/core/styles/themes/standalone' as *; -@use 'light/tokens' as *; +@use 'igniteui-theming/sass/color/functions' as *; +@use 'styles/themes/standalone' as *; +@use './light/tokens' as *; $theme: $material; $cell-font-size: rem(13px); @@ -12,7 +12,8 @@ $cell-line-height: rem(16px); $cell-editing-outline-width: rem(2px); @include layer(base) { - %cell-base { + // Base cell display - used for both data cells and header cells + %cell-display { position: relative; display: flex; flex: 1 1 0%; @@ -36,6 +37,33 @@ $cell-editing-outline-width: rem(2px); border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); } + // Text content wrapper inside cells + %cell-text { + @include ellipsis(); + pointer-events: none; + } + + // Fixed width columns (non-resizable) + %cell-fixed-width { + flex-grow: 0; + outline-style: none; + } + + // Base row structure + %row-base { + display: flex; + background: var-get($theme, 'content-background'); + border-bottom: rem(1px) solid var-get($theme, 'row-border-color'); + outline-style: none; + position: relative; + background-clip: content-box !important; + + &:hover { + background: var-get($theme, 'row-hover-background'); + color: var-get($theme, 'row-hover-text-color'); + } + } + %cell-header { flex-flow: row nowrap; justify-content: space-between; @@ -57,8 +85,325 @@ $cell-editing-outline-width: rem(2px); // The cell size should be different in the indigo theme -> 32px, 40px, 48px --cell-height: #{sizable(rem(32px), rem(40px), rem(50px))}; + // Table body container + @include e(tbody) { + position: relative; + display: flex; + grid-row: 4; + overflow: hidden; + } + + // Table body content area + @include e(tbody-content) { + position: relative; + background: var-get($theme, 'content-background'); + color: var-get($theme, 'content-text-color'); + overflow: hidden; + z-index: 1; + outline-style: none; + } + + // Table body message (empty state) + @include e(tbody-message) { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + color: var-get($theme, 'content-text-color'); + flex-direction: column; + padding: rem(24px); + } + + // Loading indicator + @include e(loading) { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + min-height: rem(100px); + } + + // Table body scrollbar + @include e(tbody-scrollbar) { + background: var-get($theme, 'content-background'); + border-inline-start: rem(1px) solid var-get($theme, 'row-border-color'); + position: relative; + } + + // Table body scrollbar main section + @include e(tbody-scrollbar-main) { + position: relative; + } + + // Table body scrollbar start section + @include e(tbody-scrollbar-start) { + background: var-get($theme, 'header-background'); + } + + // Table body scrollbar end section + @include e(tbody-scrollbar-end) { + background: var-get($theme, 'header-background'); + } + + // Horizontal scroll container + @include e(scroll) { + grid-row: 6; + display: flex; + flex-flow: row nowrap; + width: 100%; + background: var-get($theme, 'header-background'); + z-index: 10001; + } + + // Scroll start section + @include e(scroll-start) { + background: var-get($theme, 'header-background'); + } + + // Scroll main section + @include e(scroll-main) { + igx-display-container { + height: 0; + } + } + + // Table footer + @include e(tfoot) { + grid-row: 5; + border-top: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + z-index: 10001; + outline-style: none; + } + + // Table footer thumb (scrollbar) + @include e(tfoot-thumb) { + position: absolute; + top: 0; + inset-inline-end: 0; + background: var-get($theme, 'header-background'); + border-inline-start: rem(1px) solid var-get($theme, 'header-border-color'); + } + + // Grid footer + @include e(footer) { + grid-row: 7; + } + @include e(td) { - @extend %cell-base; + @extend %cell-display; + } + + @include e(td, $m: fw) { + @extend %cell-fixed-width; + } + + @include e(td-text) { + @extend %cell-text; + } + + // Base row element + @include e(tr) { + @extend %row-base; + } + + // Row striping - odd rows + @include e(tr, $m: odd) { + background: var-get($theme, 'row-odd-background'); + color: var-get($theme, 'row-odd-text-color'); + } + + // Row striping - even rows + @include e(tr, $m: even) { + background: var-get($theme, 'row-even-background'); + color: var-get($theme, 'row-even-text-color'); + } + + // Selected row state + @include e(tr, $m: selected) { + color: var-get($theme, 'row-selected-text-color'); + background: var-get($theme, 'row-selected-background'); + + &:hover { + background: var-get($theme, 'row-selected-hover-background'); + color: var-get($theme, 'row-selected-hover-text-color'); + } + } + + // Deleted row state - shows strikethrough text + @include e(tr, $m: deleted) { + .igx-grid__td-text { + font-style: italic; + color: color($color: 'error'); + text-decoration: line-through; + } + } + + // Highlighted row - shows left indicator bar + @include e(tr, $m: highlighted) { + position: relative; + + &::after { + content: ''; + position: absolute; + top: 0; + inset-inline-start: 0; + width: rem(4px); + height: 100%; + background: var-get($theme, 'row-highlight'); + z-index: 3; + } + + // When highlighted row is also edited, offset the edited indicator + &::before { + inset-inline-start: rem(4px); + } + } + + // Filtered row (tree grid) - subdued text color + @include e(tr, $m: filtered) { + .igx-grid__td-text { + color: var-get($theme, 'tree-filtered-text-color'); + } + } + + // Selected and filtered row combination (tree grid) + @include e(tr, $mods: (selected, filtered)) { + .igx-grid__td-text { + color: var-get($theme, 'tree-selected-filtered-row-text-color'); + } + } + + // Expanded row (hierarchical/tree grid) + @include e(tr, $m: expanded) { + border-bottom: none; + } + + // Pinned row + @include e(tr, $m: pinned) { + position: relative; + background: inherit; + z-index: 10000; + } + + // Pinned row at top + @include e(tr, $m: pinned-top) { + border-bottom: rem(2px) solid var-get($theme, 'pinned-border-color') !important; + } + + // Pinned row at bottom + @include e(tr, $m: pinned-bottom) { + border-top: rem(2px) solid var-get($theme, 'pinned-border-color') !important; + position: absolute; + bottom: 0; + } + + // Merged row (no bottom border) + @include e(tr, $m: merged) { + border-block-end: 0; + } + + // Merged row top + @include e(tr, $m: merged-top) { + position: absolute; + width: 100%; + } + + // Disabled row + @include e(tr, $m: disabled) { + .igx-grid__td-text { + color: var-get($theme, 'cell-disabled-color'); + } + } + + // New cell (newly added) + @include e(td, $m: new) { + color: var-get($theme, 'cell-new-color'); + } + + // Edited cell (value has been modified) + @include e(td, $m: edited) { + .igx-grid__td-text { + font-style: italic; + color: var-get($theme, 'cell-edited-value-color'); + padding: 0 rem(1px); + } + } + + // Merged cell + @include e(td, $m: merged) { + z-index: 1; + grid-row: 1 / -1; + } + + // Merged cell when selected + @include e(td, $m: merged-selected) { + color: var-get($theme, 'row-selected-text-color'); + background: var-get($theme, 'row-selected-background') !important; + } + + // Merged cell when hovered + @include e(td, $m: merged-hovered) { + background: var-get($theme, 'row-hover-background') !important; + color: var-get($theme, 'row-hover-text-color'); + } + + // Merged cell when both selected and hovered + @include e(td, $mods: (merged-selected, merged-hovered)) { + background: var-get($theme, 'row-selected-hover-background') !important; + color: var-get($theme, 'row-selected-hover-text-color'); + } + + // Number cell (right-aligned) + @include e(td, $m: number) { + text-align: end; + justify-content: flex-end; + flex-grow: 1; + } + + // Pinned cell + @include e(td, $m: pinned) { + position: relative; + background: inherit; + z-index: 9999; + } + + // Last pinned column (right border) + @include e(td, $m: pinned-last) { + border-inline-end: rem(2px) solid var-get($theme, 'pinned-border-color') !important; + } + + // First pinned column (left border) + @include e(td, $m: pinned-first) { + border-inline-start: rem(2px) solid var-get($theme, 'pinned-border-color') !important; + } + + // Pinned cell when selected + @include e(td, $mods: (pinned, selected)) { + color: var-get($theme, 'cell-selected-text-color'); + background: var-get($theme, 'cell-selected-background'); + } + + // Pinned cell when column is selected + @include e(td, $mods: (pinned, column-selected)) { + color: var-get($theme, 'row-selected-text-color'); + background: var-get($theme, 'row-selected-background'); + + &:hover { + background: var-get($theme, 'row-selected-hover-background'); + color: var-get($theme, 'row-selected-text-color'); + } + } + + // First cell in row-pinned layout + @include e(td, $m: row-pinned-first) { + overflow: hidden; + } + + // Pinned chip spacing + @include e(td, $m: pinned-chip) { + margin-inline-end: pad-inline(rem(4px), rem(8px), rem(12px)); } @include e(td, $m: active) { @@ -78,6 +423,11 @@ $cell-editing-outline-width: rem(2px); // } } + // Valid cell in edit mode + @include e(td, $mods: (editing, valid)) { + // Placeholder for valid state styling if needed + } + @include e(td, $m: editing) { border-width: 0; background: var-get($theme, 'cell-editing-background') !important; @@ -115,12 +465,570 @@ $cell-editing-outline-width: rem(2px); border: none !important; } } + + [aria-readonly='true'] { + color: var-get($theme, 'cell-disabled-color'); + + igx-icon { + color: var-get($theme, 'cell-disabled-color'); + } + } + } + + @include e(td, $mods: (editing, invalid)) { + box-shadow: inset 0 0 0 #{$cell-editing-outline-width} color($color: 'error') !important; + } + + // Row editing state - active edit mode on a row + @include e(tr, $m: edit) { + border-bottom: rem(1px) solid var-get($theme, 'edit-mode-color'); + position: relative; + + // Top border indicator + &::after { + content: ''; + position: absolute; + height: rem(1px); + width: 100%; + top: rem(-1px); + inset-inline-start: 0; + background: var-get($theme, 'edit-mode-color'); + } + } + + // MRL (Multi-row layout) specific edit row adjustments + @include e(tr, $mods: (mrl, edit)) { + &:first-of-type::after { + top: 0; + z-index: 5; + } + } + + // Multi-row layout row + @include e(tr, $m: mrl) { + border-bottom-color: transparent; + } + + // Dragging row state + @include e(tr, $m: drag) { + opacity: 0.5; + } + + // Ghost row during drag operation + @include e(tr, $m: ghost) { + background: var-get($theme, 'row-ghost-background'); + color: var-get($theme, 'row-drag-color'); + z-index: 10002; + } + + // Group row + @include e(tr, $m: group) { + position: relative; + background: var-get($theme, 'header-background') !important; + } + + // Inner row wrapper + @include e(tr, $m: inner) { + display: flex; + background: inherit; + } + + // Header row + @include e(tr, $m: header) { + display: flex; + align-items: center; + + igx-icon { + --component-size: 3; + } + } + + // Row add animation + @include e(tr, $m: add-animate) { + animation: scale-in-ver-center 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94); + } + + // Edited row indicator - shows row has been modified + @include e(tr, $m: edited) { + &::before { + content: ''; + position: absolute; + width: rem(2px); + height: 100%; + z-index: 10000; + background: var-get($theme, 'edited-row-indicator'); + } + } + + // Row editing overlay outlet container + @include e(row-editing-outlet) { + z-index: 10000; + position: absolute; + } + + // Row container + @include e(tr-container) { + overflow: auto; + width: 100%; + border-bottom: rem(1px) solid var-get($theme, 'row-border-color'); + } + + // Active row container + @include e(tr-container, $m: active) { + box-shadow: inset 0 0 0 rem(1px) var-get($theme, 'cell-active-border-color'); + } + + // Action row (for row actions like edit, delete buttons) + @include e(tr-action) { + &:last-of-type { + border-inline-end: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + min-height: sizable(rem(32px), rem(40px), rem(50px)); + } + } + + // Tree grid grouping indicator (expand/collapse icon) + @include e(tree-grouping-indicator) { + display: flex; + align-items: center; + justify-content: center; + user-select: none; + outline-style: none; + margin-inline-end: rem(8px); + cursor: pointer; + color: var-get($theme, 'expand-icon-color'); + + &:hover { + color: var-get($theme, 'expand-icon-hover-color'); + } + + [dir='rtl'] & { + transform: scaleX(-1); + } + + igx-icon { + --component-size: 3; + } + } + + // Tree grid loading indicator + @include e(tree-loading-indicator) { + width: rem(24px); + height: rem(24px); + margin-inline-end: rem(8px); + } + + // Row indentation for tree/grouping + @include e(row-indentation) { + position: relative; + display: flex; + justify-content: center; + align-items: center; + padding-inline: pad-inline(rem(12px), rem(16px), rem(18px)); + border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); + background: inherit; + z-index: 1; + background-clip: border-box; + + &::after { + content: ''; + position: absolute; + width: 100%; + height: rem(1px); + } + } + + // Hierarchical grid expander (expand/collapse child grids) + @include e(hierarchical-expander) { + user-select: none; + background: inherit; + padding-inline: pad-inline(rem(12px), rem(16px), rem(18px)); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + z-index: 3; + color: var-get($theme, 'expand-icon-color'); + background-clip: border-box; + + &:focus { + outline: none; + + igx-icon { + color: var-get($theme, 'expand-icon-hover-color'); + } + } + + &:hover { + igx-icon { + color: var-get($theme, 'expand-icon-hover-color'); + } + } + + igx-icon { + --component-size: 3; + color: var-get($theme, 'expand-icon-color'); + } + + [dir='rtl'] & { + transform: scaleX(-1); + } + } + + // Empty hierarchical expander (no children) + @include e(hierarchical-expander, $m: empty) { + cursor: default; + pointer-events: none; + } + + // Hierarchical expander in header + @include e(hierarchical-expander, $m: header) { + background: inherit; + border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); + z-index: 3; + background-clip: border-box; + + igx-icon { + display: flex; + align-items: center; + } + } + + // Hierarchical expander pushed to top + @include e(hierarchical-expander, $m: push) { + align-items: flex-start; + + igx-icon { + min-height: var(--header-size); + max-height: var(--header-size); + } + } + + // Hierarchical indent spacing + @include e(hierarchical-indent) { + display: flex; + margin-inline-start: pad-inline(rem(24px), rem(32px), rem(36px)); + } + + // Hierarchical indent when scrolling + @include e(hierarchical-indent, $m: scroll) { + margin-inline-start: 0; + } + + // Row indentation levels for tree/grouping (1-10) + @for $i from 1 through 10 { + @include e(row-indentation, $m: level-#{$i}) { + $level-compact: $i * rem(24px); + $level-cosy: $i * rem(32px); + $level-comfortable: $i * rem(36px); + + padding-inline-start: pad-inline($level-compact, $level-cosy, $level-comfortable); + } + } + + // Header indentation for tree/grouping + @include e(header-indentation) { + position: relative; + padding-inline-end: sizable(rem(12px), rem(16px), rem(18px)); + border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); + background: var-get($theme, 'header-background'); + z-index: 4; + + igx-icon { + --component-size: 3; + } + } + + // Header indentation without border + @include e(header-indentation, $m: no-border) { + border-inline-end: rem(1px) solid transparent; + } + + // Checkbox padding + @include e(cbx-padding) { + display: flex; + align-items: center; + justify-content: center; + padding-inline: pad-inline(rem(8px), rem(12px), rem(16px)); + } + + // Checkbox selection cell + @include e(cbx-selection) { + display: flex; + justify-content: center; + align-items: center; + background: inherit; + z-index: 4; + background-clip: border-box; + } + + // Checkbox selection pushed to top (for header alignment) + @include e(cbx-selection, $m: push) { + align-items: flex-start; + padding-block-start: pad-block( + calc((rem(32px) - rem(20px)) / 2), + calc((rem(40px) - rem(20px)) / 2), + calc((rem(50px) - rem(20px)) / 2) + ); + } + + // Group row + @include e(group-row) { + background: var-get($theme, 'group-row-background'); + display: flex; + outline-style: none; + border-bottom: rem(1px) solid var-get($theme, 'row-border-color'); + min-height: var(--header-size); + } + + // Active group row + @include e(group-row, $m: active) { + background: var-get($theme, 'group-row-selected-background'); + box-shadow: inset 0 0 0 rem(1px) var-get($theme, 'cell-active-border-color'); + + &:hover { + background: var-get($theme, 'group-row-selected-background'); + } + } + + // Group content area + @include e(group-content) { + display: flex; + align-items: center; + justify-content: flex-start; + flex: 1 1 auto; + padding-inline-start: pad-inline(rem(12px), rem(16px), rem(18px)); + min-height: sizable(rem(40px), rem(48px), rem(56px)); + + &:focus { + outline: transparent; + } + } + + // Grouping indicator (expand/collapse for groups) + @include e(grouping-indicator) { + position: relative; + display: flex; + user-select: none; + justify-content: center; + align-items: center; + z-index: 1; + cursor: pointer; + padding-inline-end: rem(12px); + margin-inline-start: sizable(rem(12px), rem(16px), rem(18px)); + min-height: var(--header-size); + + igx-icon { + --component-size: 3; + color: var-get($theme, 'expand-icon-color'); + } + + &:hover, + &:focus { + outline-style: none; + + igx-icon { + color: var-get($theme, 'expand-icon-hover-color'); + } + } + + [dir='rtl'] & { + transform: scaleX(-1); + } + } + + // Group expand button (on row indentation) + @include e(group-expand-btn) { + position: absolute; + cursor: pointer; + user-select: none; + inset-block-start: calc(50% - rem(12px) / 2); + inset-inline-start: var(--indicator-inline-inset); + + &:hover { + color: var-get($theme, 'expand-icon-hover-color'); + } } + // Group expand button pushed to top + @include e(group-expand-btn, $m: push) { + inset-block-start: sizable( + calc((rem(40px) - rem(12px)) / 2), + calc((rem(48px) - rem(12px)) / 2), + calc((rem(56px) - rem(12px)) / 2) + ); + } + + // Group row padding levels (1-10) - for nested groups + @for $i from 1 through 10 { + @include e(group-row, $m: padding-level-#{$i}) { + $indicator-padding-compact: $i * rem(12px); + $indicator-padding-cosy: $i * rem(16px); + $indicator-padding-comfortable: $i * rem(18px); + + .igx-grid__grouping-indicator { + margin-inline-start: sizable($indicator-padding-compact, $indicator-padding-cosy, $indicator-padding-comfortable); + } + } + } + + // Multi-row layout block (MRL) + @include e(mrl-block) { + display: grid; + background: inherit; + position: relative; + } + + // Pivot grid super-compact mode + @include e(pivot, $m: super-compact) { + --ig-size: 1 !important; + } + + // Pivot row + @include e(tr-pivot) { + display: flex; + align-items: center; + background: inherit; + overflow: hidden; + z-index: 3; + height: var(--header-size); + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + padding-block: 0; + background-clip: border-box !important; + border-inline-start: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + border-bottom: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + + igx-chips-area { + flex-wrap: nowrap; + width: auto; + + > * { + margin-inline-end: rem(4px); + } + + &:last-child { + margin-inline-end: 0; + } + } + } + + // Pivot filter toggle button + @include e(pivot-filter-toggle) { + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + position: relative; + + > igx-badge { + position: absolute; + top: rem(-4px); + inset-inline-start: 60%; + width: rem(18px); + min-width: rem(18px); + height: rem(18px); + font-size: rem(10px); + pointer-events: none; + user-select: none; + } + } + + // Pivot empty chip area placeholder + @include e(pivot-empty-chip-area) { + line-height: normal; + font-size: rem(14px); + margin-inline-end: 0 !important; + } + + // Pivot row area + @include e(tr-pivot, $m: row-area) { + height: auto !important; + align-items: flex-end; + padding-bottom: pad-block(rem(8px), rem(12px), rem(16px)); + border-inline-start: 0; + border-bottom: 0; + } + + // Pivot filter container + @include e(tr-pivot, $m: filter-container) { + display: flex; + flex-direction: column; + } + + // Pivot chip drop indicator + @include e(tr-pivot, $m: chip_drop_indicator) { + width: rem(2px); + background: var-get($theme, 'resize-line-color'); + visibility: hidden; + } + + // Pivot drop row area + @include e(tr-pivot, $m: drop-row-area) { + flex-grow: 1; + } + + // Pivot filter row + @include e(tr-pivot, $m: filter) { + height: var(--header-size); + border-inline-start: 0; + border-inline-end: 0; + border-bottom: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + } + + // Pivot group + @include e(tr-pivot-group) { + flex: 1; + } + + // Pivot header row + @include e(tr-header-row) { + igx-pivot-row-dimension-header-group { + igx-pivot-row-dimension-header { + align-items: center; + } + } + } + + // Pivot column dimension leaf + @include e(tr-pivot, $m: columnDimensionLeaf) { + box-shadow: none; + + igx-grid-header { + border: none; + } + } + + // Pivot column multi-row span + @include e(tr-pivot, $m: columnMultiRowSpan) { + igx-grid-header { + > * { + visibility: hidden; + } + } + } + + // Pivot tbody MRL dimension + @include e(tbody-pivot-mrl-dimension) { + .igx-grid-th { + border-bottom: none; + } + } + + // Pivot toggle icons + @include e(tr-pivot-toggle-icons) { + display: inline-flex !important; + } } @include b(igx-grid-th) { - @extend %cell-base; + @extend %cell-display; @extend %cell-header; @include e(title) { @@ -176,4 +1084,84 @@ $cell-editing-outline-width: rem(2px); } } } + + // Grid header (thead) container and structure + @include b(igx-grid-thead) { + // Main thead container + grid-row: 3; + display: flex; + overflow: hidden; + + // Header wrapper element + @include e(wrapper) { + border-bottom: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + z-index: 2; + } + + // Header title cell + @include e(title) { + @extend %cell-display; + @extend %cell-header; + flex-basis: auto !important; + align-items: center !important; + border-bottom: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + height: var(--header-size); + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + padding-block: 0; + } + + // Pinned header title (last pinned column) + @include e(title, $m: pinned-last) { + border-inline-end: rem(2px) solid var-get($theme, 'pinned-border-color') !important; + } + + // Header group (contains multiple columns) + @include e(group) { + display: flex; + flex-flow: row nowrap; + } + + // Header item (column header wrapper) + @include e(item) { + display: flex; + flex-flow: column nowrap; + position: relative; + } + + // Header subgroup (nested column headers) + @include e(subgroup) { + position: relative; + } + + // Scrollbar thumb for header + @include e(thumb) { + background: var-get($theme, 'header-background'); + border-inline-start: rem(1px) solid var-get($theme, 'header-border-color'); + } + + // Pivot grid modifier + @include m(pivot) { + display: flex; + } + + // Virtualization wrapper + @include m(virtualizationWrapper) { + height: 100%; + } + + // Virtualization container + @include m(virtualizationContainer) { + overflow: visible; + height: 100%; + } + + // Pivot wrapper specific styling + @include e(wrapper, $m: pivot) { + border-bottom: 0; + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss index 17d7c933e0a..f1c317a8b1c 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss @@ -14,3 +14,35 @@ } } } + +@include themed-block(igx-grid, indigo, dark) { + @include e(pivot-empty-chip-area) { + color: contrast-color($color: 'gray', $variant: 50, $opacity: .6); + } + + @include e(tr-header-row) { + igx-pivot-row-dimension-header-group { + igx-icon { + opacity: 0.85; + + &:hover { + opacity: 1; + cursor: pointer; + } + } + } + } +} + +@include themed-block(igx-grid-thead, indigo, dark) { + @include e(title) { + igx-icon { + opacity: 0.85; + + &:hover { + opacity: 1; + cursor: pointer; + } + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss index d11b77b1a75..db451fa04c2 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss @@ -14,3 +14,35 @@ } } } + +@include themed-block(igx-grid, indigo, light) { + @include e(pivot-empty-chip-area) { + color: color($color: 'gray', $variant: 600); + } + + @include e(tr-header-row) { + igx-pivot-row-dimension-header-group { + igx-icon { + opacity: 0.75; + + &:hover { + opacity: 1; + cursor: pointer; + } + } + } + } +} + +@include themed-block(igx-grid-thead, indigo, light) { + @include e(title) { + igx-icon { + opacity: 0.75; + + &:hover { + opacity: 1; + cursor: pointer; + } + } + } +} diff --git a/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss index 5c615dee95d..7f3817b59eb 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/shared/_indigo.scss @@ -1,4 +1,5 @@ @use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/typography/functions' as *; @use '../../../../lib/core/styles/themes/standalone' as *; @include themed-block(igx-grid-th, indigo) { @@ -12,3 +13,65 @@ } } } + +@include themed-block(igx-grid, indigo) { + @include e(tr, $m: edited) { + &::before { + width: rem(4px); + } + } + + @include e(tr, $m: header) { + igx-icon { + --component-size: 2; + } + } + + @include e(tr-action) { + &:last-of-type { + min-height: sizable(rem(32px), rem(40px), rem(48px)); + } + } + + @include e(tree-grouping-indicator) { + margin-inline-end: rem(4px); + + igx-icon { + --component-size: 2; + } + } + + @include e(hierarchical-expander) { + igx-icon { + --component-size: 2; + } + } + + @include e(header-indentation) { + igx-icon { + --component-size: 2; + } + } + + @include e(group-content) { + padding-inline-start: 0; + } + + @include e(grouping-indicator) { + padding-inline-end: rem(16px); + + igx-icon { + --component-size: 2; + } + } + + @include e(tr-pivot) { + padding-inline: pad-inline(rem(8px), rem(12px), rem(16px)); + } +} + +@include themed-block(igx-grid-thead, indigo) { + @include e(title) { + padding-inline: pad-inline(rem(8px), rem(12px), rem(16px)); + } +} From e587bb4f341560446251761098da0d05a4ed6ad9 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 17 Nov 2025 13:37:49 +0200 Subject: [PATCH 6/8] themes(grid): more changes to the bundled grid theme --- .../components/grid/_grid-component.scss | 201 +- .../headers/grid-header-row.component.html | 2 +- .../pivot-header-row.component.html | 2 +- ...pivot-row-dimension-content.component.html | 2 +- .../src/lib/grids/themes/_base.scss | 965 +++- .../src/lib/grids/themes/dark/_indigo.scss | 1 + .../src/lib/grids/themes/light/_indigo.scss | 1 + .../themes/test/igniteui-angular-dark.css | 3 + .../grids/themes/test/igniteui-angular.css | 5077 +++++++++++++++++ .../themes/test/igniteui-bootstrap-dark.css | 3 + .../themes/test/igniteui-bootstrap-light.css | 3 + .../grids/themes/test/igniteui-dark-green.css | 3 + .../test/igniteui-fluent-dark-excel.css | 3 + .../themes/test/igniteui-fluent-dark-word.css | 3 + .../themes/test/igniteui-fluent-dark.css | 3 + .../test/igniteui-fluent-light-excel.css | 3 + .../test/igniteui-fluent-light-word.css | 3 + .../themes/test/igniteui-fluent-light.css | 3 + .../themes/test/igniteui-indigo-dark.css | 3 + .../themes/test/igniteui-indigo-light.css | 3 + .../grids/tree-grid/tree-grid.component.scss | 4 + .../grids/tree-grid/tree-grid.component.ts | 5 +- src/styles/_variables.scss | 8 +- 23 files changed, 6158 insertions(+), 146 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-angular-dark.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-angular.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-bootstrap-dark.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-bootstrap-light.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-dark-green.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-fluent-dark-excel.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-fluent-dark-word.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-fluent-dark.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-fluent-light-excel.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-fluent-light-word.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-fluent-light.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-indigo-dark.css create mode 100644 projects/igniteui-angular/src/lib/grids/themes/test/igniteui-indigo-light.css create mode 100644 projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.scss diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index 86a396241e8..969fc931533 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -30,9 +30,10 @@ @extend %grid-display !optional; - @include e(caption) { - @extend %grid-caption !optional; - } + // TRANSFERRED to new _base.scss + // @include e(caption) { + // @extend %grid-caption !optional; + // } // @include e(tbody) { // @extend %grid-tbody-container !optional; @@ -118,17 +119,18 @@ // @extend %igx-grid__tr--ghost !optional; // } - @include e(drag-indicator) { - @extend %igx-grid__drag-indicator !optional; - } + // TRANSFERRED to new _base.scss + // @include e(drag-indicator) { + // @extend %igx-grid__drag-indicator !optional; + // } - @include e(drag-indicator, $m: 'header') { - @extend %igx-grid__drag-indicator--header !optional; - } + // @include e(drag-indicator, $m: 'header') { + // @extend %igx-grid__drag-indicator--header !optional; + // } - @include e(drag-indicator, $m: 'off') { - @extend %igx-grid__drag-indicator--off !optional; - } + // @include e(drag-indicator, $m: 'off') { + // @extend %igx-grid__drag-indicator--off !optional; + // } // @include e(tr, $m: 'mrl') { // @extend %grid-row--mrl !optional; @@ -138,26 +140,27 @@ // @extend %grid-row--edit-mrl !optional; // } - @include e(summaries) { - @extend %grid-summaries !optional; - - igx-display-container { - @extend %grid-display-container-tr !optional; - } - } - - @include e(summaries, $m: 'body') { - @extend %grid-summaries !optional; - @extend %grid-summaries--body !optional; + // TRANSFERRED to new _base.scss + // @include e(summaries) { + // @extend %grid-summaries !optional; + // + // igx-display-container { + // @extend %grid-display-container-tr !optional; + // } + // } - igx-display-container { - @extend %grid-display-container-tr !optional; - } - } + // @include e(summaries, $m: 'body') { + // @extend %grid-summaries !optional; + // @extend %grid-summaries--body !optional; + // + // igx-display-container { + // @extend %grid-display-container-tr !optional; + // } + // } - @include e(summaries-patch) { - @extend %grid-summaries-patch !optional; - } + // @include e(summaries-patch) { + // @extend %grid-summaries-patch !optional; + // } // @include e(tr, $m: odd) { // @extend %grid-row--odd !optional; @@ -410,33 +413,34 @@ // @extend %igx-grid__grouping-indicator !optional; // } - @include e(scroll-on-drag-left) { - @extend %grid__scroll-on-drag-left !optional; - } + // TRANSFERRED to new _base.scss + // @include e(scroll-on-drag-left) { + // @extend %grid__scroll-on-drag-left !optional; + // } - @include e(scroll-on-drag-right) { - @extend %grid__scroll-on-drag-right !optional; - } + // @include e(scroll-on-drag-right) { + // @extend %grid__scroll-on-drag-right !optional; + // } - @include e(scroll-on-drag-pinned) { - @extend %grid__scroll-on-drag-pinned !optional; - } + // @include e(scroll-on-drag-pinned) { + // @extend %grid__scroll-on-drag-pinned !optional; + // } - @include e(drag-ghost-image) { - @extend %grid__drag-ghost-image !optional; - } + // @include e(drag-ghost-image) { + // @extend %grid__drag-ghost-image !optional; + // } - @include e(drag-ghost-image-icon) { - @extend %grid__drag-ghost-image-icon !optional; - } + // @include e(drag-ghost-image-icon) { + // @extend %grid__drag-ghost-image-icon !optional; + // } - @include e(drag-ghost-image-icon-group) { - @extend %grid__drag-ghost-image-icon-group !optional; - } + // @include e(drag-ghost-image-icon-group) { + // @extend %grid__drag-ghost-image-icon-group !optional; + // } - @include e(drag-col-header) { - @extend %igx-grid__drag-col-header !optional; - } + // @include e(drag-col-header) { + // @extend %igx-grid__drag-col-header !optional; + // } // @include e(header-indentation) { // @extend %igx-grid__header-indentation !optional; @@ -454,71 +458,72 @@ // @extend %igx-grid__group-expand-btn--push !optional; // } - @include e(outlet) { - @extend %igx-grid__outlet !optional; - } + // TRANSFERRED to new _base.scss + // @include e(outlet) { + // @extend %igx-grid__outlet !optional; + // } - @include e(loading-outlet) { - @extend %igx-grid__loading-outlet !optional; - } + // @include e(loading-outlet) { + // @extend %igx-grid__loading-outlet !optional; + // } // @include e(row-editing-outlet) { // @extend %igx-grid__row-editing-outlet !optional; // } - @include e(addrow-snackbar) { - @extend %igx-grid__addrow-snackbar !optional; - } + // @include e(addrow-snackbar) { + // @extend %igx-grid__addrow-snackbar !optional; + // } - @include e(filtering-cell) { - @extend %igx-grid__filtering-cell !optional; - } + // @include e(filtering-cell) { + // @extend %igx-grid__filtering-cell !optional; + // } - @include e(filtering-cell, $m: 'selected') { - @extend %igx-grid__filtering-cell !optional; - @extend %igx-grid__filtering-cell--selected !optional; - } + // @include e(filtering-cell, $m: 'selected') { + // @extend %igx-grid__filtering-cell !optional; + // @extend %igx-grid__filtering-cell--selected !optional; + // } - @include e(filtering-cell-indicator) { - @extend %igx-grid__filtering-cell-indicator !optional; - } + // @include e(filtering-cell-indicator) { + // @extend %igx-grid__filtering-cell-indicator !optional; + // } - @include e(filtering-cell-indicator, $m: 'hidden') { - @extend %igx-grid__filtering-cell-indicator !optional; - @extend %igx-grid__filtering-cell-indicator--hidden !optional; - } + // @include e(filtering-cell-indicator, $m: 'hidden') { + // @extend %igx-grid__filtering-cell-indicator !optional; + // @extend %igx-grid__filtering-cell-indicator--hidden !optional; + // } - @include e(filtering-dropdown-items) { - @extend %igx-grid__filtering-dropdown-items !optional; - } + // @include e(filtering-dropdown-items) { + // @extend %igx-grid__filtering-dropdown-items !optional; + // } - @include e(filtering-dropdown-text) { - @extend %igx-grid__filtering-dropdown-text !optional; - } + // @include e(filtering-dropdown-text) { + // @extend %igx-grid__filtering-dropdown-text !optional; + // } - @include e(filtering-row) { - @extend %igx-grid__filtering-row !optional; - } + // @include e(filtering-row) { + // @extend %igx-grid__filtering-row !optional; + // } - @include e(filtering-row-editing-buttons) { - @extend %igx-grid__filtering-row-editing-buttons !optional; - } + // @include e(filtering-row-editing-buttons) { + // @extend %igx-grid__filtering-row-editing-buttons !optional; + // } - @include e(filtering-row-editing-buttons, $m: small) { - @extend %igx-grid__filtering-row-editing-buttons--small !optional; - } + // @include e(filtering-row-editing-buttons, $m: small) { + // @extend %igx-grid__filtering-row-editing-buttons--small !optional; + // } - @include e(filtering-row-main) { - @extend %igx-grid__filtering-row-main !optional; - } + // @include e(filtering-row-main) { + // @extend %igx-grid__filtering-row-main !optional; + // } - @include e(filtering-row-scroll-start) { - @extend %igx-grid__filtering-scroll-start !optional; - } + // @include e(filtering-row-scroll-start) { + // @extend %igx-grid__filtering-scroll-start !optional; + // } - @include e(filtering-row-scroll-end) { - @extend %igx-grid__filtering-scroll-end !optional; - } + // @include e(filtering-row-scroll-end) { + // @extend %igx-grid__filtering-scroll-end !optional; + // } // @include e(hierarchical-indent) { // @extend %igx-grid__hierarchical-indent !optional; diff --git a/projects/igniteui-angular/src/lib/grids/headers/grid-header-row.component.html b/projects/igniteui-angular/src/lib/grids/headers/grid-header-row.component.html index 261a1f203d9..979a5449bd5 100644 --- a/projects/igniteui-angular/src/lib/grids/headers/grid-header-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/headers/grid-header-row.component.html @@ -2,7 +2,7 @@ [class.igx-grid__tr--mrl]="hasMRL"> -
+
@if (grid.moving && grid.columnInDrag && pinnedStartColumnCollection.length <= 0) { diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html index 3772f3958c4..fe7403eba03 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html @@ -197,7 +197,7 @@ [class.igx-grid__tr--mrl]="hasMRL"> -
+
@if (!grid.pivotUI.showRowHeaders || grid.rowDimensions.length === 0) {
-
+
it simply uses the detail-1 styles for all cells @@ -31,10 +32,6 @@ $cell-editing-outline-width: rem(2px); padding-block: 0; // The inline padding styles should be different in the indigo theme -> 8px, 12px, 16px padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); - - // These should probably be added to the cell when it's a part of a multi-row layout header - border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); - border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); } // Text content wrapper inside cells @@ -49,27 +46,16 @@ $cell-editing-outline-width: rem(2px); outline-style: none; } - // Base row structure - %row-base { - display: flex; - background: var-get($theme, 'content-background'); - border-bottom: rem(1px) solid var-get($theme, 'row-border-color'); - outline-style: none; - position: relative; - background-clip: content-box !important; - - &:hover { - background: var-get($theme, 'row-hover-background'); - color: var-get($theme, 'row-hover-text-color'); - } - } - %cell-header { flex-flow: row nowrap; justify-content: space-between; align-items: flex-end; min-width: 0; min-height: var(--header-size); + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + padding-block: 0; + font-size: rem(12px); + font-weight: 600; border-inline-end: var-get($theme, 'header-border-width') var-get($theme, 'header-border-style') var-get($theme, 'header-border-color'); @@ -81,10 +67,37 @@ $cell-editing-outline-width: rem(2px); @include sizable(); --component-size: var(--ig-size, var(--ig-size-large)); + // TODO: This should be declared in the theme tokens --grid-size: var(--component-size); + // The cell size should be different in the indigo theme -> 32px, 40px, 48px --cell-height: #{sizable(rem(32px), rem(40px), rem(50px))}; + // Derived size variables for header, group area, and tree indentation + --header-size: #{sizable(rem(50px), rem(40px), rem(32px))}; + --grouparea-size: #{sizable(rem(57px), rem(49px), rem(41px))}; + --igx-tree-indent-size: #{sizable(rem(24px), rem(16px), rem(12px))}; + + // Core grid structure + position: relative; + display: grid; + grid-template-rows: auto auto auto 1fr auto auto; + grid-template-columns: 100%; + overflow: hidden; + box-shadow: var-get($theme, 'grid-elevation'); + outline-style: none; + z-index: 1; + + // Grid caption + @include e(caption) { + display: flex; + align-items: center; + font-size: rem(20px); + line-height: rem(32px); + padding: rem(16px) rem(24px); + grid-row: 1; + } + // Table body container @include e(tbody) { position: relative; @@ -101,6 +114,10 @@ $cell-editing-outline-width: rem(2px); overflow: hidden; z-index: 1; outline-style: none; + + &:focus { + outline: 0; + } } // Table body message (empty state) @@ -169,12 +186,37 @@ $cell-editing-outline-width: rem(2px); // Table footer @include e(tfoot) { + position: relative; + display: flex; + background: var-get($theme, 'header-background'); + color: var-get($theme, 'header-text-color'); + overflow: hidden; + outline-style: none; grid-row: 5; border-top: var-get($theme, 'header-border-width') var-get($theme, 'header-border-style') var-get($theme, 'header-border-color'); z-index: 10001; - outline-style: none; + + .igx-grid__tr { + position: relative; + background: inherit; + color: inherit; + z-index: 2; + + &:hover { + background: inherit; + color: inherit; + } + } + + > [aria-activedescendant] { + outline-style: none; + } + + &:focus { + outline: 0; + } } // Table footer thumb (scrollbar) @@ -205,7 +247,21 @@ $cell-editing-outline-width: rem(2px); // Base row element @include e(tr) { - @extend %row-base; + position: relative; + display: flex; + outline-style: none; + border-bottom: rem(1px) solid var-get($theme, 'row-border-color'); + // TODO: Why is this needed? + background-clip: content-box !important; + } + + @include e(tr, $not: (header, selected)) { + background: var-get($theme, 'content-background'); + + &:hover { + background: var-get($theme, 'row-hover-background'); + color: var-get($theme, 'row-hover-text-color'); + } } // Row striping - odd rows @@ -225,14 +281,28 @@ $cell-editing-outline-width: rem(2px); color: var-get($theme, 'row-selected-text-color'); background: var-get($theme, 'row-selected-background'); + // WARN: This doesn't follow the BEM structure, needs work + .igx-grid__td--selected, + .igx-grid__td--pinned.igx-grid__td--selected { + color: var-get($theme, 'cell-selected-within-text-color'); + background: var-get($theme, 'cell-selected-within-background'); + } + &:hover { background: var-get($theme, 'row-selected-hover-background'); color: var-get($theme, 'row-selected-hover-text-color'); + + // WARN: This doesn't follow the BEM structure, needs work + .igx-grid__td--column-selected { + color: var-get($theme, 'row-selected-hover-text-color'); + background: var-get($theme, 'row-selected-hover-background'); + } } } // Deleted row state - shows strikethrough text @include e(tr, $m: deleted) { + // WARN: This doesn't follow the BEM structure, needs work .igx-grid__td-text { font-style: italic; color: color($color: 'error'); @@ -263,6 +333,7 @@ $cell-editing-outline-width: rem(2px); // Filtered row (tree grid) - subdued text color @include e(tr, $m: filtered) { + // WARN: This doesn't follow the BEM structure, needs work .igx-grid__td-text { color: var-get($theme, 'tree-filtered-text-color'); } @@ -270,6 +341,7 @@ $cell-editing-outline-width: rem(2px); // Selected and filtered row combination (tree grid) @include e(tr, $mods: (selected, filtered)) { + // WARN: This doesn't follow the BEM structure, needs work .igx-grid__td-text { color: var-get($theme, 'tree-selected-filtered-row-text-color'); } @@ -409,18 +481,30 @@ $cell-editing-outline-width: rem(2px); @include e(td, $m: active) { box-shadow: inset 0 0 0 rem(1px) var-get($theme, 'cell-active-border-color'); + } + + // Selected cell + @include e(td, $m: selected) { + color: var-get($theme, 'cell-selected-text-color'); + background: var-get($theme, 'cell-selected-background'); - // > %igx-grid__filtering-cell, - // > %grid-cell-header { - // border-inline-end-color: var-get( - // $theme, - // 'cell-active-border-color' - // ); - // border-bottom-color: var-get( - // $theme, - // 'cell-active-border-color' - // ); - // } + .igx-grid__tree-grouping-indicator { + &:hover { + color: var-get($theme, 'cell-selected-text-color'); + } + } + } + + // Column selected (entire column is selected) + @include e(td, $m: column-selected) { + color: var-get($theme, 'row-selected-text-color'); + background: var-get($theme, 'row-selected-background'); + } + + // Cross-selected (cell + column selected) + @include e(td, $mods: (selected, column-selected)) { + color: var-get($theme, 'cell-selected-within-text-color'); + background: var-get($theme, 'cell-selected-within-background'); } // Valid cell in edit mode @@ -722,7 +806,7 @@ $cell-editing-outline-width: rem(2px); $level-compact: $i * rem(24px); $level-cosy: $i * rem(32px); $level-comfortable: $i * rem(36px); - + padding-inline-start: pad-inline($level-compact, $level-cosy, $level-comfortable); } } @@ -875,7 +959,7 @@ $cell-editing-outline-width: rem(2px); // Multi-row layout block (MRL) @include e(mrl-block) { - display: grid; + display: grid !important; background: inherit; position: relative; } @@ -1025,11 +1109,550 @@ $cell-editing-outline-width: rem(2px); @include e(tr-pivot-toggle-icons) { display: inline-flex !important; } + + // ============================================================================ + // Drag & Drop Elements + // ============================================================================ + + // Drag indicator for reordering columns/rows + @include e(drag-indicator) { + display: flex; + align-items: center; + justify-content: center; + padding-inline: pad-inline(rem(24px), rem(16px), rem(12px)); + min-height: sizable(rem(50px), rem(40px), rem(32px)); + padding-block: 0; + flex: 0 0 auto; + background: inherit; + z-index: 4; + cursor: move; + border-inline-end: rem(1px) solid transparent; + background-clip: border-box; + + igx-icon { + --component-size: 3; + } + } + + // Drag indicator in header + @include e(drag-indicator, $m: header) { + border-inline-end: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + } + + // Drag indicator off/disabled state + @include e(drag-indicator, $m: off) { + color: var-get($theme, 'row-drag-color'); + } + + // Ghost image shown while dragging + @include e(drag-ghost-image) { + position: absolute; + display: flex; + align-items: center; + background: var-get($theme, 'ghost-header-background') !important; + color: var-get($theme, 'ghost-header-text-color') !important; + min-width: rem(168px); + max-width: rem(320px); + height: var(--header-size); + min-height: var(--header-size); + padding-inline: pad-inline(rem(24px), rem(16px), rem(12px)); + top: rem(-10000px); + inset-inline-start: rem(-10000px); + border: none; + box-shadow: var(--drag-shadow); + overflow: hidden; + z-index: 20; + + .igx-grid-th__title { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + flex: 1 0 0; + text-align: end; + color: var-get($theme, 'ghost-header-text-color') !important; + } + + .igx-grid-th__icons { + display: none; + } + + .igx-grid-thead__title { + border: none; + color: var-get($theme, 'ghost-header-text-color') !important; + background: transparent !important; + } + } + + // Ghost image icon + @include e(drag-ghost-image-icon) { + color: var-get($theme, 'ghost-header-icon-color'); + margin-inline-end: rem(12px); + } + + // Ghost image icon group (multiple columns) + @include e(drag-ghost-image-icon-group) { + color: var-get($theme, 'ghost-header-icon-color'); + padding: rem(24px); + padding-inline-end: 0; + margin-inline-end: rem(8px); + } + + // Drag column header (being dragged) + @include e(drag-col-header) { + background: var-get($theme, 'header-background'); + + .igx-grid-thead__title > *, + .igx-grid-th > * { + opacity: 0.4; + } + } + + // Scroll on drag indicators + @include e(scroll-on-drag-left) { + position: absolute; + width: rem(15px); + top: 0; + height: 100%; + z-index: 25; + inset-inline-start: 0; + } + + @include e(scroll-on-drag-right) { + position: absolute; + width: rem(15px); + top: 0; + height: 100%; + z-index: 25; + inset-inline-end: 0; + } + + @include e(scroll-on-drag-pinned) { + position: absolute; + width: rem(15px); + height: 100%; + top: 0; + z-index: 25; + } + + // ============================================================================ + // Filtering Elements + // ============================================================================ + + // Filtering row + @include e(filtering-row) { + display: flex; + flex-flow: row nowrap; + align-items: center; + grid-row: 2; + background: var-get($theme, 'filtering-row-background'); + color: var-get($theme, 'filtering-row-text-color'); + z-index: 10001; + border-bottom: rem(1px) solid var-get($theme, 'header-border-color'); + + // Nested input group styles + igx-input-group { + flex: 1 1 auto; + width: 100%; + max-width: rem(200px); + min-width: rem(140px); + --ig-size: var(--grid-size) !important; + --size: calc(var(--header-size) - #{rem(8px)}); + border: rem(1px) solid var-get($theme, 'row-border-color'); + color: var-get($theme, 'filtering-row-text-color'); + + &:hover { + border-color: var-get($theme, 'cell-active-border-color'); + } + + .igx-input-group__bundle, + .igx-input-group__bundle-start, + .igx-input-group__bundle-main, + .igx-input-group__bundle-end, + igx-prefix, + igx-suffix { + background: transparent; + border-radius: 0; + border: 0; + + &:hover { + background: transparent; + border: 0; + box-shadow: none; + } + } + + .igx-input-group__bundle-main { + padding-inline-start: 0; + } + + .igx-input-group__bundle::after { + display: none; + } + + igx-prefix, + igx-suffix { + height: 100% !important; + padding: 0 pad-inline(rem(4px), rem(6px), rem(8px)); + + &:focus { + color: var-get($theme, 'edit-mode-color'); + } + } + + .igx-input-group__input { + font-size: sizable(rem(12px), rem(14px), rem(16px)); + padding-inline-start: 0; + padding-block: 0; + height: 100%; + border: 0; + + &:hover { + border: 0; + box-shadow: none; + } + } + + .igx-input-group__line { + display: none; + } + + igx-suffix igx-icon { + outline-style: none; + + &:focus { + color: var-get($theme, 'edit-mode-color'); + } + + + igx-icon { + margin-inline-start: rem(4px); + } + } + } + + .igx-input-group--focused { + border-color: var-get($theme, 'cell-active-border-color'); + + .igx-input-group__bundle, + .igx-input-group__bundle-start, + .igx-input-group__bundle-end, + .igx-input-group__input { + border: 0 !important; + box-shadow: none !important; + } + + .igx-input-group__bundle-main, + .igx-input-group__bundle-start, + .igx-input-group__bundle-end { + margin: 0 !important; + } + + .igx-input-group__bundle, + .igx-input-group__bundle-start, + .igx-input-group__bundle-end, + igx-prefix, + igx-suffix { + color: var-get($theme, 'filtering-row-text-color'); + background: transparent !important; + border-radius: 0; + } + } + + [igxIconButton] { + --ig-size: 1; + color: var-get($theme, 'filtering-row-text-color'); + } + } + + // Filtering row main section + @include e(filtering-row-main) { + display: flex; + flex: 1 1 auto; + align-items: center; + overflow: hidden; + max-width: calc(100% - rem(176px)); + min-width: rem(56px); + + igx-chips-area { + flex-wrap: nowrap; + gap: rem(4px); + } + } + + // Filtering row editing buttons + @include e(filtering-row-editing-buttons) { + display: flex; + align-items: center; + padding: rem(8px); + gap: rem(4px); + + button { + transition: none; + + &:not([disabled]) igx-icon { + color: var-get($theme, 'sorted-header-icon-color'); + } + } + } + + // Filtering row editing buttons (small) + @include e(filtering-row-editing-buttons, $m: small) { + padding: rem(4px); + + button { + transition: none; + + &:not([disabled]) igx-icon { + color: var-get($theme, 'sorted-header-icon-color'); + } + } + } + + // Filtering row scroll start + @include e(filtering-row-scroll-start) { + position: relative; + + &::after { + display: block; + position: absolute; + width: rem(10px); + content: ''; + inset-block: rem(-2px); + background: linear-gradient(to right, var-get($theme, 'filtering-row-background'), transparent); + inset-inline-end: rem(-10px); + } + } + + // Filtering row scroll end + @include e(filtering-row-scroll-end) { + position: relative; + + &::after { + display: block; + position: absolute; + width: rem(10px); + content: ''; + inset-block: rem(-2px); + background: linear-gradient(to left, var-get($theme, 'filtering-row-background'), transparent); + inset-inline-start: rem(-10px); + } + } + + // Filtering cell (advanced filtering) + @include e(filtering-cell) { + display: flex; + align-items: center; + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + padding-block: 0; + overflow: hidden; + border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); + border-top: rem(1px) solid var-get($theme, 'header-border-color'); + height: var(--header-size); + + igx-chips-area { + width: 100%; + flex-wrap: nowrap; + overflow: hidden; + + .igx-filtering-chips__connector { + font-size: rem(12px); + text-transform: uppercase; + font-weight: 600; + margin: 0 rem(8px); + overflow: hidden; + } + } + } + + // Filtering cell selected state + @include e(filtering-cell, $m: selected) { + background: var-get($theme, 'header-selected-background'); + + igx-chips-area { + background: inherit; + } + } + + // Filtering cell indicator (badge/icon) + @include e(filtering-cell-indicator) { + display: flex; + align-items: center; + position: relative; + + igx-icon, + .igx-badge { + cursor: pointer; + } + + .igx-badge { + position: absolute; + top: rem(-4px); + inset-inline-start: 60%; + } + } + + // Filtering cell indicator hidden state + @include e(filtering-cell-indicator, $m: hidden) { + .igx-badge, + igx-icon { + display: none; + } + } + + // Filtering dropdown items + @include e(filtering-dropdown-items) { + max-height: rem(320px); + overflow-y: auto; + } + + // Filtering dropdown text + @include e(filtering-dropdown-text) { + padding: rem(8px) rem(16px); + cursor: pointer; + + &:hover { + background: var-get($theme, 'row-hover-background'); + } + } + + // ============================================================================ + // Summaries Elements + // ============================================================================ + + // Summaries row + @include e(summaries) { + display: flex; + overflow: hidden; + outline-style: none; + background-color: var-get($theme, 'summaries-patch-background'); + + igx-display-container { + width: 100%; + overflow: visible; + flex: 1; + min-width: 0; + } + } + + // Summaries body (in grid body) + @include e(summaries, $m: body) { + --summaries-patch-background: var-get($theme, 'content-background'); + border-bottom: rem(1px) dashed var-get($theme, 'row-border-color'); + background-color: var-get($theme, 'summaries-patch-background'); + + &:last-of-type { + border-bottom: none; + } + + // Override summary component colors when in body context + .igx-grid-summary { + --background-color: inherit; + --result-color: hsla(from color(from var(--background-color) var(--y-contrast)) h 0 l / 1); + } + } + + // Summaries patch (fixed area) + @include e(summaries-patch) { + position: relative; + background: inherit; + border-inline-end: rem(1px) solid var-get($theme, 'header-border-color'); + z-index: 1; + } + + // ============================================================================ + // Outlet Elements + // ============================================================================ + + // Generic outlet for overlays + @include e(outlet) { + --ig-size: var(--grid-size); + z-index: 10002; + position: fixed; + } + + // Loading outlet + @include e(loading-outlet) { + z-index: 10003; + } + + // Row editing outlet + @include e(row-editing-outlet) { + z-index: 10000; + position: absolute; + } + + // Add row snackbar + @include e(addrow-snackbar) { + position: absolute; + bottom: rem(16px); + inset-inline-start: 50%; + transform: translateX(-50%); + z-index: 10003; + } + + // ============================================================================ + // Misc Elements + // ============================================================================ + + // Icon wrapper + @include e(icon) { + display: flex; + align-items: center; + justify-content: center; + } + + // Column name display + @include e(column-name) { + @include ellipsis(); + } + + // Count badge + @include e(count-badge) { + display: flex; + align-items: center; + justify-content: center; + min-width: rem(20px); + height: rem(20px); + padding: rem(2px) rem(6px); + border-radius: rem(10px); + font-size: rem(12px); + background: var-get($theme, 'group-count-background'); + color: var-get($theme, 'group-count-text-color'); + } + + // Text wrapper + @include e(text) { + @include ellipsis(); + } } @include b(igx-grid-th) { - @extend %cell-display; - @extend %cell-header; + position: relative; + display: flex; + flex: 1 1 0%; + color: inherit; + text-align: start; + // TODO: Verify if this is needed, commenting out for now + // background-clip: border-box !important; + + // Font size for the cell is different in the ingigo theme -> it simply uses the detail-1 styles for all cells + line-height: $cell-line-height; + flex-flow: row nowrap; + justify-content: space-between; + align-items: flex-end; + min-width: 0; + min-height: var(--header-size); + // The inline padding styles should be different in the indigo theme -> 8px, 12px, 16px + padding-inline: pad-inline(rem(12px), rem(16px), rem(24px)); + padding-block: 0; + font-size: rem(12px); + font-weight: 600; + // border-inline-end: var-get($theme, 'header-border-width') + // var-get($theme, 'header-border-style') + // var-get($theme, 'header-border-color'); + overflow: hidden; + transition: color 250ms ease-in-out; @include e(title) { @include ellipsis(); @@ -1083,6 +1706,126 @@ $cell-editing-outline-width: rem(2px); } } } + + // Sorted header (column is currently sorted) + @include m(sorted) { + .sort-icon { + opacity: 1; + color: var-get($theme, 'sorted-header-icon-color'); + + > igx-icon { + color: inherit; + } + + &:focus, + &:hover { + color: var-get($theme, 'sortable-header-icon-hover-color'); + + > igx-icon { + color: inherit; + } + } + } + + // When hovering over the header cell itself, change icon color + &:hover .sort-icon { + color: var-get($theme, 'sortable-header-icon-hover-color'); + + > igx-icon { + color: inherit; + } + } + } + + // Active header (selected/focused header cell) + @include m(active) { + box-shadow: inset 0 0 0 rem(1px) var-get($theme, 'cell-active-border-color'); + + .igx-grid-th--selected, + .igx-grid-th--selectable, + > .igx-grid__filtering-cell, + > .igx-grid-thead__title, + > .igx-grid-th { + border-inline-end-color: var-get($theme, 'cell-active-border-color'); + border-bottom-color: var-get($theme, 'cell-active-border-color'); + } + } + + // Selected header (column selection) + @include m(selectable) { + color: var-get($theme, 'header-selected-text-color'); + background: var-get($theme, 'header-selected-background'); + } + + @include m(selected) { + color: var-get($theme, 'header-selected-text-color'); + background: var-get($theme, 'header-selected-background'); + + .sort-icon::after { + background: var-get($theme, 'header-selected-background'); + } + + &.igx-grid-th--sorted { + .sort-icon { + color: var-get($theme, 'header-selected-text-color'); + + > igx-icon { + color: inherit; + } + } + } + } + + // Drop indicators for column reordering + @include e(drop-indicator-left) { + position: absolute; + width: rem(1px); + height: 100%; + top: 0; + z-index: 1; + inset-inline-start: rem(-1px); + } + + @include e(drop-indicator-right) { + position: absolute; + width: rem(1px); + height: 100%; + top: 0; + z-index: 1; + inset-inline-end: rem(-1px); + } + + // Active state with compound selectors - use @at-root to prevent nesting + @at-root { + .igx-grid-th__drop-indicator--active { + &.igx-grid-th__drop-indicator-left, + &.igx-grid-th__drop-indicator-right { + border-inline-end: rem(1px) solid var-get($theme, 'drop-indicator-color'); + } + + &::after, + &::before { + position: absolute; + content: ''; + width: 0; + height: 0; + border-style: solid; + inset-inline-start: rem(-3px); + } + + &::before { + bottom: 0; + border-width: 0 rem(4px) rem(4px); + border-color: transparent transparent var-get($theme, 'drop-indicator-color'); + } + + &::after { + top: 0; + border-width: rem(4px) rem(4px) 0; + border-color: var-get($theme, 'drop-indicator-color') transparent transparent; + } + } + } } // Grid header (thead) container and structure @@ -1091,13 +1834,65 @@ $cell-editing-outline-width: rem(2px); grid-row: 3; display: flex; overflow: hidden; + background: var-get($theme, 'header-background'); + color: var-get($theme, 'header-text-color'); + border-block-end: var-get($theme, 'header-border-width') + var-get($theme, 'header-border-style') + var-get($theme, 'header-border-color'); + + // TODO: This is completely upside down - doesn't follow BEM at all + // Rows inside thead should not have hover effects + .igx-grid__tr { + position: relative; + background: inherit; + color: inherit; + z-index: 2; + + &:hover { + background: inherit; + color: inherit; + } + } // Header wrapper element @include e(wrapper) { - border-bottom: var-get($theme, 'header-border-width') - var-get($theme, 'header-border-style') - var-get($theme, 'header-border-color'); + position: relative; + display: flex; + background: var-get($theme, 'header-background'); + color: var-get($theme, 'header-text-color'); + overflow: hidden; + outline-style: none; z-index: 2; + + .igx-grid__tr { + position: relative; + background: inherit; + color: inherit; + z-index: 2; + border-bottom: none; + + &:hover { + background: inherit; + color: inherit; + } + } + + .igx-grid__cbx-selection--push { + align-items: flex-start; + padding-block-start: pad-block( + calc((rem(32px) - rem(20px)) / 2), + calc((rem(40px) - rem(20px)) / 2), + calc((rem(50px) - rem(20px)) / 2) + ); + } + + > [aria-activedescendant] { + outline-style: none; + } + + &:focus { + outline: 0; + } } // Header title cell @@ -1164,4 +1959,94 @@ $cell-editing-outline-width: rem(2px); border-bottom: 0; } } + + // ============================================================================ + // TEMPORARY: Context-Specific Nested Rules + // These rules handle nested contexts that don't fit cleanly into the BEM model + // ============================================================================ + + // Thead context - elements styled differently when inside thead + .igx-grid-thead { + .igx-grid__header-indentation { + igx-icon { + --component-size: 3; + } + } + + .igx-grid__drag-indicator { + cursor: default; + } + + // MRL (Multi-Row Layout) specific thead styles + .igx-grid__tr--mrl { + .igx-grid__hierarchical-expander--header, + .igx-grid__hierarchical-expander, + .igx-grid__hierarchical-expander--empty, + .igx-grid__header-indentation, + .igx-grid__row-indentation, + .igx-grid__cbx-selection { + border-bottom: var(--header-border-width) var(--header-border-style) var(--header-border-color); + } + } + + &:focus-visible { + outline-color: transparent; + } + } + + // MRL block context - multi-row layout grid structure + .igx-grid__mrl-block { + .igx-grid-thead__item { + display: flex; + } + + .igx-grid-thead__title, + .igx-grid-th { + border-inline-end: 0; + } + + .igx-grid__td, + .igx-grid-thead__title, + .igx-grid-th { + border-bottom: 0; + } + } + + // MRL row context - rows in multi-row layout + .igx-grid__tr--mrl { + .igx-grid__cbx-selection, + .igx-grid__hierarchical-expander, + .igx-grid__hierarchical-expander--empty, + .igx-grid__row-indentation, + .igx-grid__drag-indicator { + border-bottom: rem(1px) solid var(--row-border-color); + } + } + + // Grid checkbox styles + .igx-grid { + .igx-checkbox { + min-width: rem(20px); + + .igx-checkbox__composite-wrapper { + width: var(--cbx-size, #{rem(20px)}); + height: var(--cbx-size, #{rem(20px)}); + padding: 0; + } + + .igx-checkbox__label { + margin-inline-start: rem(12px); + } + + .igx-checkbox__label--before { + margin-inline-end: rem(12px); + } + + .igx-checkbox__label:empty, + .igx-checkbox__label--before:empty { + padding: 0; + margin: 0; + } + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss index f1c317a8b1c..c6d59e0f21b 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/dark/_indigo.scss @@ -1,4 +1,5 @@ @use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/color/functions' as *; @use '../../../../lib/core/styles/themes/standalone' as *; @include themed-block(igx-grid-th, indigo, dark) { diff --git a/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss b/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss index db451fa04c2..ccbe35d5eef 100644 --- a/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss +++ b/projects/igniteui-angular/src/lib/grids/themes/light/_indigo.scss @@ -1,4 +1,5 @@ @use 'igniteui-theming/sass/bem' as *; +@use 'igniteui-theming/sass/color/functions' as *; @use '../../../../lib/core/styles/themes/standalone' as *; @include themed-block(igx-grid-th, indigo, light) { diff --git a/projects/igniteui-angular/src/lib/grids/themes/test/igniteui-angular-dark.css b/projects/igniteui-angular/src/lib/grids/themes/test/igniteui-angular-dark.css new file mode 100644 index 00000000000..f1b6f884e5b --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/themes/test/igniteui-angular-dark.css @@ -0,0 +1,3 @@ +.igx-display-container{display:inherit;flex-flow:inherit;position:relative;width:100%;overflow:hidden;flex-shrink:0}.igx-display-container--inactive{width:100%}.igx-drag{touch-action:none}.igx-drag--select-disabled{-webkit-user-select:none;-moz-user-select:none;user-select:none}.igx-drag__handle{-webkit-user-select:none;-moz-user-select:none;user-select:none}.igx-vhelper--vertical,.igx-vhelper--horizontal{display:block;overflow:auto;z-index:10001}.igx-vhelper--vertical{position:absolute;top:0;inset-inline-end:0;width:var(--vhelper-scrollbar-size)}.igx-vhelper--horizontal{width:100%}.igx-vhelper--vertical .igx-vhelper__placeholder-content{width:1px}.igx-vhelper--horizontal .igx-vhelper__placeholder-content{height:1px}[hidden]{display:none !important}[class^=igx-],[class^=igx-] *,[class^=igx-] *::before,[class^=igx-] *::after,[class^=ig-],[class^=ig-] *,[class^=ig-] *::before,[class^=ig-] *::after{box-sizing:border-box}@property --ig-spacing{syntax:" | ";initial-value:1;inherits:true}:root{--ig-spacing-inline-small: var(--ig-spacing-inline, var(--ig-spacing-small));--ig-spacing-inline-medium: var(--ig-spacing-inline, var(--ig-spacing-medium));--ig-spacing-inline-large: var(--ig-spacing-inline, var(--ig-spacing-large));--ig-spacing-block-small: var(--ig-spacing-block, var(--ig-spacing-small));--ig-spacing-block-medium: var(--ig-spacing-block, var(--ig-spacing-medium));--ig-spacing-block-large: var(--ig-spacing-block, var(--ig-spacing-large))}@property --_transition-delay{syntax:"